mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2024-10-01 01:26:01 -04:00
Merge pull request #2443 from brainplot/code-cleanup
Code cleanup and performance improvements - Part 2
This commit is contained in:
commit
c66f293f1e
@ -672,7 +672,7 @@ bool AutoType::checkSyntax(const QString& string)
|
||||
QString shortcutKeys = "[\\^\\%~\\+@]";
|
||||
// a normal string not in parentheses
|
||||
QString fixedStrings = "[^\\^\\%~\\+@\\{\\}]*";
|
||||
|
||||
// clang-format off
|
||||
QRegularExpression autoTypeSyntax(
|
||||
"^(?:" + shortcutKeys + "|" + fixedStrings + "|\\{(?:" + normalCommands + "|" + specialLiterals + "|"
|
||||
+ functionKeys
|
||||
@ -688,6 +688,7 @@ bool AutoType::checkSyntax(const QString& string)
|
||||
+ customAttributes
|
||||
+ "\\})*$",
|
||||
QRegularExpression::CaseInsensitiveOption);
|
||||
// clang-format on
|
||||
QRegularExpressionMatch match = autoTypeSyntax.match(string);
|
||||
return match.hasMatch();
|
||||
}
|
||||
@ -755,9 +756,10 @@ bool AutoType::verifyAutoTypeSyntax(const QString& sequence)
|
||||
}
|
||||
} else if (AutoType::checkHighRepetition(sequence)) {
|
||||
QMessageBox::StandardButton reply;
|
||||
reply =
|
||||
QMessageBox::question(nullptr, tr("Auto-Type"), tr("This Auto-Type command contains arguments which are "
|
||||
"repeated very often. Do you really want to proceed?"));
|
||||
reply = QMessageBox::question(nullptr,
|
||||
tr("Auto-Type"),
|
||||
tr("This Auto-Type command contains arguments which are "
|
||||
"repeated very often. Do you really want to proceed?"));
|
||||
|
||||
if (reply == QMessageBox::No) {
|
||||
return false;
|
||||
|
@ -67,10 +67,13 @@ AutoTypeSelectDialog::AutoTypeSelectDialog(QWidget* parent)
|
||||
QLabel* descriptionLabel = new QLabel(tr("Select entry to Auto-Type:"), this);
|
||||
layout->addWidget(descriptionLabel);
|
||||
|
||||
// clang-format off
|
||||
connect(m_view, SIGNAL(activated(QModelIndex)), SLOT(emitMatchActivated(QModelIndex)));
|
||||
connect(m_view, SIGNAL(clicked(QModelIndex)), SLOT(emitMatchActivated(QModelIndex)));
|
||||
connect(m_view->model(), SIGNAL(rowsRemoved(QModelIndex,int,int)), SLOT(matchRemoved()));
|
||||
connect(m_view, SIGNAL(rejected()), SLOT(reject()));
|
||||
// clang-format on
|
||||
|
||||
layout->addWidget(m_view);
|
||||
|
||||
QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel, Qt::Horizontal, this);
|
||||
|
@ -23,7 +23,7 @@
|
||||
const QChar WildcardMatcher::Wildcard = '*';
|
||||
const Qt::CaseSensitivity WildcardMatcher::Sensitivity = Qt::CaseInsensitive;
|
||||
|
||||
WildcardMatcher::WildcardMatcher(QString text)
|
||||
WildcardMatcher::WildcardMatcher(QString text)
|
||||
: m_text(std::move(text))
|
||||
{
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
class WildcardMatcher
|
||||
{
|
||||
public:
|
||||
explicit WildcardMatcher(QString text);
|
||||
explicit WildcardMatcher(QString text);
|
||||
bool match(const QString& pattern);
|
||||
|
||||
static const QChar Wildcard;
|
||||
|
@ -211,8 +211,7 @@ int AutoTypePlatformX11::platformEventFilter(void* event)
|
||||
xcb_key_press_event_t* keyPressEvent = static_cast<xcb_key_press_event_t*>(event);
|
||||
if (keyPressEvent->detail == m_currentGlobalKeycode
|
||||
&& (keyPressEvent->state & m_modifierMask) == m_currentGlobalNativeModifiers
|
||||
&& (!QApplication::activeWindow() || QApplication::activeWindow()->isMinimized())
|
||||
&& m_loaded) {
|
||||
&& (!QApplication::activeWindow() || QApplication::activeWindow()->isMinimized()) && m_loaded) {
|
||||
if (type == XCB_KEY_PRESS) {
|
||||
emit globalShortcutTriggered();
|
||||
}
|
||||
|
@ -1,25 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Francois Ferrand
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* Copyright (C) 2013 Francois Ferrand
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "BrowserAccessControlDialog.h"
|
||||
#include "core/Entry.h"
|
||||
#include "ui_BrowserAccessControlDialog.h"
|
||||
|
||||
#include "core/Entry.h"
|
||||
|
||||
BrowserAccessControlDialog::BrowserAccessControlDialog(QWidget* parent)
|
||||
: QDialog(parent)
|
||||
, m_ui(new Ui::BrowserAccessControlDialog())
|
||||
@ -38,8 +39,8 @@ BrowserAccessControlDialog::~BrowserAccessControlDialog()
|
||||
void BrowserAccessControlDialog::setUrl(const QString& url)
|
||||
{
|
||||
m_ui->label->setText(QString(tr("%1 has requested access to passwords for the following item(s).\n"
|
||||
"Please select whether you want to allow access."))
|
||||
.arg(QUrl(url).host()));
|
||||
"Please select whether you want to allow access."))
|
||||
.arg(QUrl(url).host()));
|
||||
}
|
||||
|
||||
void BrowserAccessControlDialog::setItems(const QList<Entry*>& items)
|
||||
|
@ -1,20 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Francois Ferrand
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* Copyright (C) 2013 Francois Ferrand
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BROWSERACCESSCONTROLDIALOG_H
|
||||
#define BROWSERACCESSCONTROLDIALOG_H
|
||||
|
@ -1,20 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "BrowserAction.h"
|
||||
#include "BrowserSettings.h"
|
||||
@ -167,9 +167,10 @@ QJsonObject BrowserAction::handleAssociate(const QJsonObject& json, const QStrin
|
||||
|
||||
QMutexLocker locker(&m_mutex);
|
||||
if (key.compare(m_clientPublicKey, Qt::CaseSensitive) == 0) {
|
||||
// Check for identification key. If it's not found, ensure backwards compatibility and use the current public key
|
||||
// Check for identification key. If it's not found, ensure backwards compatibility and use the current public
|
||||
// key
|
||||
const QString idKey = decrypted.value("idKey").toString();
|
||||
const QString id = m_browserService.storeKey((idKey.isEmpty() ? key: idKey));
|
||||
const QString id = m_browserService.storeKey((idKey.isEmpty() ? key : idKey));
|
||||
if (id.isEmpty()) {
|
||||
return getErrorReply(action, ERROR_KEEPASS_ACTION_CANCELLED_OR_DENIED);
|
||||
}
|
||||
|
@ -1,20 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BROWSERACTION_H
|
||||
#define BROWSERACTION_H
|
||||
|
@ -1,20 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "BrowserClients.h"
|
||||
#include <QJsonParseError>
|
||||
|
@ -1,20 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BROWSERCLIENTS_H
|
||||
#define BROWSERCLIENTS_H
|
||||
|
@ -1,20 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Francois Ferrand
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* Copyright (C) 2013 Francois Ferrand
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "BrowserEntryConfig.h"
|
||||
#include "core/Entry.h"
|
||||
|
@ -1,20 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Francois Ferrand
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* Copyright (C) 2013 Francois Ferrand
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BROWSERENTRYCONFIG_H
|
||||
#define BROWSERENTRYCONFIG_H
|
||||
|
@ -1,20 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Francois Ferrand
|
||||
* Copyright (C) 2018 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* Copyright (C) 2013 Francois Ferrand
|
||||
* Copyright (C) 2018 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "BrowserEntrySaveDialog.h"
|
||||
#include "ui_BrowserEntrySaveDialog.h"
|
||||
@ -34,7 +34,7 @@ BrowserEntrySaveDialog::BrowserEntrySaveDialog(QWidget* parent)
|
||||
|
||||
m_ui->itemsList->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
m_ui->label->setText(QString(tr("You have multiple databases open.\n"
|
||||
"Please select the correct database for saving credentials.")));
|
||||
"Please select the correct database for saving credentials.")));
|
||||
}
|
||||
|
||||
BrowserEntrySaveDialog::~BrowserEntrySaveDialog()
|
||||
@ -58,7 +58,7 @@ int BrowserEntrySaveDialog::setItems(QList<DatabaseWidget*>& databaseWidgets, Da
|
||||
} else {
|
||||
item->setText(QString("%1 (%2)").arg(databaseName, databaseFileName));
|
||||
}
|
||||
|
||||
|
||||
if (currentWidget == dbWidget) {
|
||||
activeIndex = counter;
|
||||
}
|
||||
@ -76,7 +76,7 @@ int BrowserEntrySaveDialog::setItems(QList<DatabaseWidget*>& databaseWidgets, Da
|
||||
return databaseWidgets.length();
|
||||
}
|
||||
|
||||
QList<QListWidgetItem*> BrowserEntrySaveDialog::getSelected() const
|
||||
{
|
||||
QList<QListWidgetItem*> BrowserEntrySaveDialog::getSelected() const
|
||||
{
|
||||
return m_ui->itemsList->selectedItems();
|
||||
}
|
||||
}
|
||||
|
@ -1,29 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Francois Ferrand
|
||||
* Copyright (C) 2018 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* Copyright (C) 2013 Francois Ferrand
|
||||
* Copyright (C) 2018 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BROWSERENTRYSAVEDIALOG_H
|
||||
#define BROWSERENTRYSAVEDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QScopedPointer>
|
||||
#include <QListWidgetItem>
|
||||
#include "gui/DatabaseTabWidget.h"
|
||||
|
||||
#include <QDialog>
|
||||
#include <QListWidgetItem>
|
||||
#include <QScopedPointer>
|
||||
|
||||
class Entry;
|
||||
|
||||
namespace Ui
|
||||
@ -40,7 +41,7 @@ public:
|
||||
~BrowserEntrySaveDialog() override;
|
||||
|
||||
int setItems(QList<DatabaseWidget*>& databaseWidgets, DatabaseWidget* currentWidget) const;
|
||||
QList<QListWidgetItem *> getSelected() const;
|
||||
QList<QListWidgetItem*> getSelected() const;
|
||||
|
||||
private:
|
||||
QScopedPointer<Ui::BrowserEntrySaveDialog> m_ui;
|
||||
|
@ -1,27 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Francois Ferrand
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* Copyright (C) 2013 Francois Ferrand
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "BrowserOptionDialog.h"
|
||||
#include "ui_BrowserOptionDialog.h"
|
||||
|
||||
#include "BrowserSettings.h"
|
||||
#include "config-keepassx.h"
|
||||
#include "core/FilePath.h"
|
||||
#include "ui_BrowserOptionDialog.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
|
||||
@ -32,18 +33,24 @@ BrowserOptionDialog::BrowserOptionDialog(QWidget* parent)
|
||||
m_ui->setupUi(this);
|
||||
|
||||
m_ui->extensionLabel->setOpenExternalLinks(true);
|
||||
m_ui->extensionLabel->setText(tr("KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2.").arg(
|
||||
"<a href=\"https://addons.mozilla.org/en-US/firefox/addon/keepassxc-browser/\">Firefox</a>",
|
||||
"<a href=\"https://chrome.google.com/webstore/detail/keepassxc-browser/oboonakemofpalcgghocfoadofidjkkk\">Google Chrome / Chromium / Vivaldi</a>"));
|
||||
m_ui->extensionLabel->setText(
|
||||
tr("KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2.")
|
||||
.arg("<a href=\"https://addons.mozilla.org/en-US/firefox/addon/keepassxc-browser/\">Firefox</a>",
|
||||
"<a "
|
||||
"href=\"https://chrome.google.com/webstore/detail/keepassxc-browser/"
|
||||
"oboonakemofpalcgghocfoadofidjkkk\">Google Chrome / Chromium / Vivaldi</a>"));
|
||||
|
||||
m_ui->scriptWarningWidget->setVisible(false);
|
||||
m_ui->scriptWarningWidget->setAutoHideTimeout(-1);
|
||||
m_ui->scriptWarningWidget->showMessage(tr("<b>Warning</b>, the keepassxc-proxy application was not found!"
|
||||
"<br />Please check the KeePassXC installation directory or confirm the custom path in advanced options."
|
||||
"<br />Browser integration WILL NOT WORK without the proxy application."
|
||||
"<br />Expected Path: "), MessageWidget::Warning);
|
||||
m_ui->scriptWarningWidget->showMessage(
|
||||
tr("<b>Warning</b>, the keepassxc-proxy application was not found!"
|
||||
"<br />Please check the KeePassXC installation directory or confirm the custom path in advanced options."
|
||||
"<br />Browser integration WILL NOT WORK without the proxy application."
|
||||
"<br />Expected Path: "),
|
||||
MessageWidget::Warning);
|
||||
|
||||
m_ui->warningWidget->showMessage(tr("<b>Warning:</b> The following options can be dangerous!"), MessageWidget::Warning);
|
||||
m_ui->warningWidget->showMessage(tr("<b>Warning:</b> The following options can be dangerous!"),
|
||||
MessageWidget::Warning);
|
||||
m_ui->warningWidget->setCloseButtonVisible(false);
|
||||
m_ui->warningWidget->setAutoHideTimeout(-1);
|
||||
|
||||
|
@ -1,27 +1,27 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Francois Ferrand
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* Copyright (C) 2013 Francois Ferrand
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BROWSEROPTIONDIALOG_H
|
||||
#define BROWSEROPTIONDIALOG_H
|
||||
|
||||
#include <QScopedPointer>
|
||||
#include <QPointer>
|
||||
#include <QScopedPointer>
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui
|
||||
|
@ -1,32 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Francois Ferrand
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* Copyright (C) 2013 Francois Ferrand
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QInputDialog>
|
||||
#include <QProgressDialog>
|
||||
#include <QJsonArray>
|
||||
#include <QMessageBox>
|
||||
#include <QProgressDialog>
|
||||
#include <QUuid>
|
||||
|
||||
#include "BrowserService.h"
|
||||
#include "BrowserAccessControlDialog.h"
|
||||
#include "BrowserEntryConfig.h"
|
||||
#include "BrowserEntrySaveDialog.h"
|
||||
#include "BrowserService.h"
|
||||
#include "BrowserSettings.h"
|
||||
#include "core/Database.h"
|
||||
#include "core/EntrySearcher.h"
|
||||
@ -54,7 +54,8 @@ BrowserService::BrowserService(DatabaseTabWidget* parent)
|
||||
// Don't connect the signals when used from DatabaseSettingsWidgetBrowser (parent is nullptr)
|
||||
if (m_dbTabWidget) {
|
||||
connect(m_dbTabWidget, SIGNAL(databaseLocked(DatabaseWidget*)), this, SLOT(databaseLocked(DatabaseWidget*)));
|
||||
connect(m_dbTabWidget, SIGNAL(databaseUnlocked(DatabaseWidget*)), this, SLOT(databaseUnlocked(DatabaseWidget*)));
|
||||
connect(
|
||||
m_dbTabWidget, SIGNAL(databaseUnlocked(DatabaseWidget*)), this, SLOT(databaseUnlocked(DatabaseWidget*)));
|
||||
connect(m_dbTabWidget,
|
||||
SIGNAL(activateDatabaseChanged(DatabaseWidget*)),
|
||||
this,
|
||||
@ -355,7 +356,8 @@ void BrowserService::updateEntry(const QString& id,
|
||||
return;
|
||||
}
|
||||
|
||||
if (username.compare(login, Qt::CaseSensitive) != 0 || entry->password().compare(password, Qt::CaseSensitive) != 0) {
|
||||
if (username.compare(login, Qt::CaseSensitive) != 0
|
||||
|| entry->password().compare(password, Qt::CaseSensitive) != 0) {
|
||||
int dialogResult = QMessageBox::No;
|
||||
if (!browserSettings()->alwaysAllowUpdate()) {
|
||||
QMessageBox msgBox;
|
||||
@ -393,16 +395,17 @@ QList<Entry*> BrowserService::searchEntries(QSharedPointer<Database> db, const Q
|
||||
QString entryScheme = entryQUrl.scheme();
|
||||
QUrl qUrl(url);
|
||||
|
||||
// Ignore entry if port or scheme defined in the URL doesn't match
|
||||
if ((entryQUrl.port() > 0 && entryQUrl.port() != qUrl.port()) ||
|
||||
(browserSettings()->matchUrlScheme() && !entryScheme.isEmpty() && entryScheme.compare(qUrl.scheme()) != 0)) {
|
||||
// Ignore entry if port or scheme defined in the URL doesn't match
|
||||
if ((entryQUrl.port() > 0 && entryQUrl.port() != qUrl.port())
|
||||
|| (browserSettings()->matchUrlScheme() && !entryScheme.isEmpty()
|
||||
&& entryScheme.compare(qUrl.scheme()) != 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Filter to match hostname in URL field
|
||||
if ((!entryUrl.isEmpty() && hostname.contains(entryUrl))
|
||||
if ((!entryUrl.isEmpty() && hostname.contains(entryUrl))
|
||||
|| (matchUrlScheme(entryUrl) && hostname.endsWith(entryQUrl.host()))) {
|
||||
entries.append(entry);
|
||||
entries.append(entry);
|
||||
}
|
||||
}
|
||||
|
||||
@ -420,7 +423,8 @@ QList<Entry*> BrowserService::searchEntries(const QString& url, const StringPair
|
||||
if (const auto& db = dbWidget->database()) {
|
||||
// Check if database is connected with KeePassXC-Browser
|
||||
for (const StringPair& keyPair : keyList) {
|
||||
QString key = db->metadata()->customData()->value(QLatin1String(ASSOCIATE_KEY_PREFIX) + keyPair.first);
|
||||
QString key =
|
||||
db->metadata()->customData()->value(QLatin1String(ASSOCIATE_KEY_PREFIX) + keyPair.first);
|
||||
if (!key.isEmpty() && keyPair.second == key) {
|
||||
databases << db;
|
||||
}
|
||||
@ -484,16 +488,22 @@ void BrowserService::convertAttributesToCustomData(QSharedPointer<Database> curr
|
||||
progress.reset();
|
||||
|
||||
if (counter > 0) {
|
||||
QMessageBox::information(nullptr, tr("KeePassXC: Converted KeePassHTTP attributes"),
|
||||
QMessageBox::information(nullptr,
|
||||
tr("KeePassXC: Converted KeePassHTTP attributes"),
|
||||
tr("Successfully converted attributes from %1 entry(s).\n"
|
||||
"Moved %2 keys to custom data.", "").arg(counter).arg(keyCounter),
|
||||
"Moved %2 keys to custom data.",
|
||||
"")
|
||||
.arg(counter)
|
||||
.arg(keyCounter),
|
||||
QMessageBox::Ok);
|
||||
} else if (counter == 0 && keyCounter > 0) {
|
||||
QMessageBox::information(nullptr, tr("KeePassXC: Converted KeePassHTTP attributes"),
|
||||
QMessageBox::information(nullptr,
|
||||
tr("KeePassXC: Converted KeePassHTTP attributes"),
|
||||
tr("Successfully moved %n keys to custom data.", "", keyCounter),
|
||||
QMessageBox::Ok);
|
||||
} else {
|
||||
QMessageBox::information(nullptr, tr("KeePassXC: No entry with KeePassHTTP attributes found!"),
|
||||
QMessageBox::information(nullptr,
|
||||
tr("KeePassXC: No entry with KeePassHTTP attributes found!"),
|
||||
tr("The active database does not contain an entry with KeePassHTTP attributes."),
|
||||
QMessageBox::Ok);
|
||||
}
|
||||
@ -539,9 +549,14 @@ QList<Entry*> BrowserService::sortEntries(QList<Entry*>& pwEntries, const QStrin
|
||||
// Sort same priority entries by Title or UserName
|
||||
auto entries = priorities.values(i);
|
||||
std::sort(entries.begin(), entries.end(), [&field](Entry* left, Entry* right) {
|
||||
return (QString::localeAwareCompare(left->attributes()->value(field), right->attributes()->value(field)) < 0) ||
|
||||
((QString::localeAwareCompare(left->attributes()->value(field), right->attributes()->value(field)) == 0) &&
|
||||
(QString::localeAwareCompare(left->attributes()->value("UserName"), right->attributes()->value("UserName")) < 0));
|
||||
return (QString::localeAwareCompare(left->attributes()->value(field), right->attributes()->value(field))
|
||||
< 0)
|
||||
|| ((QString::localeAwareCompare(left->attributes()->value(field),
|
||||
right->attributes()->value(field))
|
||||
== 0)
|
||||
&& (QString::localeAwareCompare(left->attributes()->value("UserName"),
|
||||
right->attributes()->value("UserName"))
|
||||
< 0));
|
||||
});
|
||||
results << entries;
|
||||
if (browserSettings()->bestMatchOnly() && !pwEntries.isEmpty()) {
|
||||
@ -843,7 +858,8 @@ int BrowserService::moveKeysToCustomData(Entry* entry, QSharedPointer<Database>
|
||||
|
||||
// Add key to database custom data
|
||||
if (db && !db->metadata()->customData()->contains(QLatin1String(ASSOCIATE_KEY_PREFIX) + publicKey)) {
|
||||
db->metadata()->customData()->set(QLatin1String(ASSOCIATE_KEY_PREFIX) + publicKey, entry->attributes()->value(key));
|
||||
db->metadata()->customData()->set(QLatin1String(ASSOCIATE_KEY_PREFIX) + publicKey,
|
||||
entry->attributes()->value(key));
|
||||
++keyCounter;
|
||||
}
|
||||
}
|
||||
@ -879,7 +895,6 @@ bool BrowserService::checkLegacySettings()
|
||||
"Do you want to upgrade the settings to the latest standard?\n"
|
||||
"This is necessary to maintain compatibility with the browser plugin."),
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
|
||||
return dialogResult == QMessageBox::Yes;
|
||||
}
|
||||
|
||||
|
@ -1,21 +1,21 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Francois Ferrand
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* Copyright (C) 2013 Francois Ferrand
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BROWSERSERVICE_H
|
||||
#define BROWSERSERVICE_H
|
||||
|
@ -1,21 +1,21 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Francois Ferrand
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* Copyright (C) 2013 Francois Ferrand
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "BrowserSettings.h"
|
||||
#include "core/Config.h"
|
||||
@ -192,7 +192,7 @@ bool BrowserSettings::chromeSupport()
|
||||
void BrowserSettings::setChromeSupport(bool enabled)
|
||||
{
|
||||
m_hostInstaller.installBrowser(
|
||||
HostInstaller::SupportedBrowsers::CHROME, enabled, supportBrowserProxy(), customProxyLocation());
|
||||
HostInstaller::SupportedBrowsers::CHROME, enabled, supportBrowserProxy(), customProxyLocation());
|
||||
}
|
||||
|
||||
bool BrowserSettings::chromiumSupport()
|
||||
@ -203,7 +203,7 @@ bool BrowserSettings::chromiumSupport()
|
||||
void BrowserSettings::setChromiumSupport(bool enabled)
|
||||
{
|
||||
m_hostInstaller.installBrowser(
|
||||
HostInstaller::SupportedBrowsers::CHROMIUM, enabled, supportBrowserProxy(), customProxyLocation());
|
||||
HostInstaller::SupportedBrowsers::CHROMIUM, enabled, supportBrowserProxy(), customProxyLocation());
|
||||
}
|
||||
|
||||
bool BrowserSettings::firefoxSupport()
|
||||
@ -214,7 +214,7 @@ bool BrowserSettings::firefoxSupport()
|
||||
void BrowserSettings::setFirefoxSupport(bool enabled)
|
||||
{
|
||||
m_hostInstaller.installBrowser(
|
||||
HostInstaller::SupportedBrowsers::FIREFOX, enabled, supportBrowserProxy(), customProxyLocation());
|
||||
HostInstaller::SupportedBrowsers::FIREFOX, enabled, supportBrowserProxy(), customProxyLocation());
|
||||
}
|
||||
|
||||
bool BrowserSettings::vivaldiSupport()
|
||||
@ -225,7 +225,7 @@ bool BrowserSettings::vivaldiSupport()
|
||||
void BrowserSettings::setVivaldiSupport(bool enabled)
|
||||
{
|
||||
m_hostInstaller.installBrowser(
|
||||
HostInstaller::SupportedBrowsers::VIVALDI, enabled, supportBrowserProxy(), customProxyLocation());
|
||||
HostInstaller::SupportedBrowsers::VIVALDI, enabled, supportBrowserProxy(), customProxyLocation());
|
||||
}
|
||||
|
||||
bool BrowserSettings::torBrowserSupport()
|
||||
|
@ -1,21 +1,21 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Francois Ferrand
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* Copyright (C) 2013 Francois Ferrand
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BROWSERSETTINGS_H
|
||||
#define BROWSERSETTINGS_H
|
||||
@ -72,7 +72,7 @@ public:
|
||||
void setVivaldiSupport(bool enabled);
|
||||
bool torBrowserSupport();
|
||||
void setTorBrowserSupport(bool enabled);
|
||||
|
||||
|
||||
bool passwordUseNumbers();
|
||||
void setPasswordUseNumbers(bool useNumbers);
|
||||
bool passwordUseLowercase();
|
||||
|
@ -1,20 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "HostInstaller.h"
|
||||
#include "config-keepassx.h"
|
||||
@ -46,8 +46,10 @@ HostInstaller::HostInstaller()
|
||||
, TARGET_DIR_VIVALDI("/.config/vivaldi/NativeMessagingHosts")
|
||||
, TARGET_DIR_TOR_BROWSER("/.tor-browser/app/Browser/TorBrowser/Data/Browser/.mozilla/native-messaging-hosts")
|
||||
#elif defined(Q_OS_WIN)
|
||||
// clang-format off
|
||||
, TARGET_DIR_CHROME("HKEY_CURRENT_USER\\Software\\Google\\Chrome\\NativeMessagingHosts\\org.keepassxc.keepassxc_browser")
|
||||
, TARGET_DIR_CHROMIUM("HKEY_CURRENT_USER\\Software\\Chromium\\NativeMessagingHosts\\org.keepassxc.keepassxc_browser")
|
||||
// clang-format on
|
||||
, TARGET_DIR_FIREFOX("HKEY_CURRENT_USER\\Software\\Mozilla\\NativeMessagingHosts\\org.keepassxc.keepassxc_browser")
|
||||
, TARGET_DIR_VIVALDI(TARGET_DIR_CHROME)
|
||||
, TARGET_DIR_TOR_BROWSER(TARGET_DIR_FIREFOX)
|
||||
@ -163,14 +165,14 @@ QString HostInstaller::getTargetPath(SupportedBrowsers browser) const
|
||||
case SupportedBrowsers::VIVALDI:
|
||||
return TARGET_DIR_VIVALDI;
|
||||
case SupportedBrowsers::TOR_BROWSER:
|
||||
return TARGET_DIR_TOR_BROWSER;
|
||||
return TARGET_DIR_TOR_BROWSER;
|
||||
default:
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the browser name
|
||||
* Returns the browser name
|
||||
* Needed for Windows to separate Chromium- or Firefox-based scripts
|
||||
*
|
||||
* @param browser Selected browser
|
||||
@ -188,7 +190,7 @@ QString HostInstaller::getBrowserName(SupportedBrowsers browser) const
|
||||
case SupportedBrowsers::VIVALDI:
|
||||
return "vivaldi";
|
||||
case SupportedBrowsers::TOR_BROWSER:
|
||||
return "tor-browser";
|
||||
return "tor-browser";
|
||||
default:
|
||||
return QString();
|
||||
}
|
||||
|
@ -1,20 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef HOSTINSTALLER_H
|
||||
#define HOSTINSTALLER_H
|
||||
|
@ -1,20 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "NativeMessagingBase.h"
|
||||
#include <QStandardPaths>
|
||||
@ -138,7 +138,8 @@ QString NativeMessagingBase::getLocalServerPath() const
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
// Use XDG_RUNTIME_DIR instead of /tmp if it's available
|
||||
QString path = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation);
|
||||
return path.isEmpty() ? QStandardPaths::writableLocation(QStandardPaths::TempLocation) + serverPath : path + serverPath;
|
||||
return path.isEmpty() ? QStandardPaths::writableLocation(QStandardPaths::TempLocation) + serverPath
|
||||
: path + serverPath;
|
||||
#else // Q_OS_MACOS, Q_OS_WIN and others
|
||||
return QStandardPaths::writableLocation(QStandardPaths::TempLocation) + serverPath;
|
||||
#endif
|
||||
|
@ -1,20 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef NATIVEMESSAGINGBASE_H
|
||||
#define NATIVEMESSAGINGBASE_H
|
||||
@ -33,11 +33,11 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef Q_OS_WIN
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
static const int NATIVE_MSG_MAX_LENGTH = 1024*1024;
|
||||
static const int NATIVE_MSG_MAX_LENGTH = 1024 * 1024;
|
||||
|
||||
class NativeMessagingBase : public QObject
|
||||
{
|
||||
|
@ -1,20 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "NativeMessagingHost.h"
|
||||
#include "BrowserSettings.h"
|
||||
@ -65,8 +65,8 @@ void NativeMessagingHost::run()
|
||||
|
||||
// Update KeePassXC/keepassxc-proxy binary paths to Native Messaging scripts
|
||||
if (browserSettings()->updateBinaryPath()) {
|
||||
browserSettings()->updateBinaryPaths(browserSettings()->useCustomProxy() ? browserSettings()->customProxyLocation()
|
||||
: "");
|
||||
browserSettings()->updateBinaryPaths(
|
||||
browserSettings()->useCustomProxy() ? browserSettings()->customProxyLocation() : "");
|
||||
}
|
||||
|
||||
m_running.store(true);
|
||||
|
@ -1,20 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef NATIVEMESSAGINGHOST_H
|
||||
#define NATIVEMESSAGINGHOST_H
|
||||
|
@ -1,19 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Variant.h"
|
||||
|
||||
|
@ -1,19 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef VARIANT_H
|
||||
#define VARIANT_H
|
||||
|
@ -51,7 +51,8 @@ int Add::execute(const QStringList& arguments)
|
||||
parser.addOption(Command::QuietOption);
|
||||
parser.addOption(Command::KeyFileOption);
|
||||
|
||||
QCommandLineOption username(QStringList() << "u" << "username",
|
||||
QCommandLineOption username(QStringList() << "u"
|
||||
<< "username",
|
||||
QObject::tr("Username for the entry."),
|
||||
QObject::tr("username"));
|
||||
parser.addOption(username);
|
||||
@ -59,15 +60,18 @@ int Add::execute(const QStringList& arguments)
|
||||
QCommandLineOption url(QStringList() << "url", QObject::tr("URL for the entry."), QObject::tr("URL"));
|
||||
parser.addOption(url);
|
||||
|
||||
QCommandLineOption prompt(QStringList() << "p" << "password-prompt",
|
||||
QCommandLineOption prompt(QStringList() << "p"
|
||||
<< "password-prompt",
|
||||
QObject::tr("Prompt for the entry's password."));
|
||||
parser.addOption(prompt);
|
||||
|
||||
QCommandLineOption generate(QStringList() << "g" << "generate",
|
||||
QCommandLineOption generate(QStringList() << "g"
|
||||
<< "generate",
|
||||
QObject::tr("Generate a password for the entry."));
|
||||
parser.addOption(generate);
|
||||
|
||||
QCommandLineOption length(QStringList() << "l" << "password-length",
|
||||
QCommandLineOption length(QStringList() << "l"
|
||||
<< "password-length",
|
||||
QObject::tr("Length for the generated password."),
|
||||
QObject::tr("length"));
|
||||
parser.addOption(length);
|
||||
|
@ -50,12 +50,13 @@ int Clip::execute(const QStringList& arguments)
|
||||
parser.addOption(Command::QuietOption);
|
||||
parser.addOption(Command::KeyFileOption);
|
||||
|
||||
QCommandLineOption totp(QStringList() << "t" << "totp",
|
||||
QCommandLineOption totp(QStringList() << "t"
|
||||
<< "totp",
|
||||
QObject::tr("Copy the current TOTP to the clipboard."));
|
||||
parser.addOption(totp);
|
||||
parser.addPositionalArgument("entry", QObject::tr("Path of the entry to clip.", "clip = copy to clipboard"));
|
||||
parser.addPositionalArgument("timeout",
|
||||
QObject::tr("Timeout in seconds before clearing the clipboard."), "[timeout]");
|
||||
parser.addPositionalArgument(
|
||||
"timeout", QObject::tr("Timeout in seconds before clearing the clipboard."), "[timeout]");
|
||||
parser.addHelpOption();
|
||||
parser.process(arguments);
|
||||
|
||||
|
@ -43,11 +43,13 @@ int Diceware::execute(const QStringList& arguments)
|
||||
|
||||
QCommandLineParser parser;
|
||||
parser.setApplicationDescription(description);
|
||||
QCommandLineOption words(QStringList() << "W" << "words",
|
||||
QCommandLineOption words(QStringList() << "W"
|
||||
<< "words",
|
||||
QObject::tr("Word count for the diceware passphrase."),
|
||||
QObject::tr("count", "CLI parameter"));
|
||||
parser.addOption(words);
|
||||
QCommandLineOption wordlistFile(QStringList() << "w" << "word-list",
|
||||
QCommandLineOption wordlistFile(QStringList() << "w"
|
||||
<< "word-list",
|
||||
QObject::tr("Wordlist for the diceware generator.\n[Default: EFF English]"),
|
||||
QObject::tr("path"));
|
||||
parser.addOption(wordlistFile);
|
||||
|
@ -51,7 +51,8 @@ int Edit::execute(const QStringList& arguments)
|
||||
parser.addOption(Command::QuietOption);
|
||||
parser.addOption(Command::KeyFileOption);
|
||||
|
||||
QCommandLineOption username(QStringList() << "u" << "username",
|
||||
QCommandLineOption username(QStringList() << "u"
|
||||
<< "username",
|
||||
QObject::tr("Username for the entry."),
|
||||
QObject::tr("username"));
|
||||
parser.addOption(username);
|
||||
@ -59,20 +60,24 @@ int Edit::execute(const QStringList& arguments)
|
||||
QCommandLineOption url(QStringList() << "url", QObject::tr("URL for the entry."), QObject::tr("URL"));
|
||||
parser.addOption(url);
|
||||
|
||||
QCommandLineOption title(QStringList() << "t" << "title",
|
||||
QCommandLineOption title(QStringList() << "t"
|
||||
<< "title",
|
||||
QObject::tr("Title for the entry."),
|
||||
QObject::tr("title"));
|
||||
parser.addOption(title);
|
||||
|
||||
QCommandLineOption prompt(QStringList() << "p" << "password-prompt",
|
||||
QCommandLineOption prompt(QStringList() << "p"
|
||||
<< "password-prompt",
|
||||
QObject::tr("Prompt for the entry's password."));
|
||||
parser.addOption(prompt);
|
||||
|
||||
QCommandLineOption generate(QStringList() << "g" << "generate",
|
||||
QCommandLineOption generate(QStringList() << "g"
|
||||
<< "generate",
|
||||
QObject::tr("Generate a password for the entry."));
|
||||
parser.addOption(generate);
|
||||
|
||||
QCommandLineOption length(QStringList() << "l" << "password-length",
|
||||
QCommandLineOption length(QStringList() << "l"
|
||||
<< "password-length",
|
||||
QObject::tr("Length for the generated password."),
|
||||
QObject::tr("length"));
|
||||
parser.addOption(length);
|
||||
@ -111,8 +116,7 @@ int Edit::execute(const QStringList& arguments)
|
||||
}
|
||||
|
||||
if (parser.value("username").isEmpty() && parser.value("url").isEmpty() && parser.value("title").isEmpty()
|
||||
&& !parser.isSet(prompt)
|
||||
&& !parser.isSet(generate)) {
|
||||
&& !parser.isSet(prompt) && !parser.isSet(generate)) {
|
||||
err << QObject::tr("Not changing any field for entry %1.").arg(entryPath) << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
@ -51,9 +51,11 @@ static void estimate(const char* pwd, bool advanced)
|
||||
int len = static_cast<int>(strlen(pwd));
|
||||
if (!advanced) {
|
||||
e = ZxcvbnMatch(pwd, nullptr, nullptr);
|
||||
// clang-format off
|
||||
out << QObject::tr("Length %1").arg(len, 0) << '\t'
|
||||
<< QObject::tr("Entropy %1").arg(e, 0, 'f', 3) << '\t'
|
||||
<< QObject::tr("Log10 %1").arg(e * 0.301029996, 0, 'f', 3) << endl;
|
||||
// clang-format on
|
||||
} else {
|
||||
int ChkLen = 0;
|
||||
ZxcMatch_t *info, *p;
|
||||
@ -63,10 +65,12 @@ static void estimate(const char* pwd, bool advanced)
|
||||
m += p->Entrpy;
|
||||
}
|
||||
m = e - m;
|
||||
// clang-format off
|
||||
out << QObject::tr("Length %1").arg(len) << '\t'
|
||||
<< QObject::tr("Entropy %1").arg(e, 0, 'f', 3) << '\t'
|
||||
<< QObject::tr("Log10 %1").arg(e * 0.301029996, 0, 'f', 3) << "\n "
|
||||
<< QObject::tr("Multi-word extra bits %1").arg(m, 0, 'f', 1) << endl;
|
||||
// clang-format on
|
||||
p = info;
|
||||
ChkLen = 0;
|
||||
while (p) {
|
||||
@ -132,9 +136,10 @@ static void estimate(const char* pwd, bool advanced)
|
||||
break;
|
||||
}
|
||||
ChkLen += p->Length;
|
||||
|
||||
// clang-format off
|
||||
out << QObject::tr("Length %1").arg(p->Length) << '\t'
|
||||
<< QObject::tr("Entropy %1 (%2)").arg(p->Entrpy, 6, 'f', 3).arg(p->Entrpy * 0.301029996, 0, 'f', 2) << '\t';
|
||||
// clang-format on
|
||||
for (n = 0; n < p->Length; ++n, ++pwd) {
|
||||
out << *pwd;
|
||||
}
|
||||
@ -143,7 +148,8 @@ static void estimate(const char* pwd, bool advanced)
|
||||
}
|
||||
ZxcvbnFreeInfo(info);
|
||||
if (ChkLen != len) {
|
||||
out << QObject::tr("*** Password length (%1) != sum of length of parts (%2) ***").arg(len).arg(ChkLen) << endl;
|
||||
out << QObject::tr("*** Password length (%1) != sum of length of parts (%2) ***").arg(len).arg(ChkLen)
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -156,7 +162,8 @@ int Estimate::execute(const QStringList& arguments)
|
||||
QCommandLineParser parser;
|
||||
parser.setApplicationDescription(description);
|
||||
parser.addPositionalArgument("password", QObject::tr("Password for which to estimate the entropy."), "[password]");
|
||||
QCommandLineOption advancedOption(QStringList() << "a" << "advanced",
|
||||
QCommandLineOption advancedOption(QStringList() << "a"
|
||||
<< "advanced",
|
||||
QObject::tr("Perform advanced analysis on the password."));
|
||||
parser.addOption(advancedOption);
|
||||
parser.addHelpOption();
|
||||
|
@ -84,7 +84,8 @@ int Extract::execute(const QStringList& arguments)
|
||||
if (fileKey->type() != FileKey::Hashed) {
|
||||
err << QObject::tr("WARNING: You are using a legacy key file format which may become\n"
|
||||
"unsupported in the future.\n\n"
|
||||
"Please consider generating a new key file.") << endl;
|
||||
"Please consider generating a new key file.")
|
||||
<< endl;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
|
@ -43,26 +43,33 @@ int Generate::execute(const QStringList& arguments)
|
||||
|
||||
QCommandLineParser parser;
|
||||
parser.setApplicationDescription(description);
|
||||
QCommandLineOption len(QStringList() << "L" << "length",
|
||||
QCommandLineOption len(QStringList() << "L"
|
||||
<< "length",
|
||||
QObject::tr("Length of the generated password"),
|
||||
QObject::tr("length"));
|
||||
parser.addOption(len);
|
||||
QCommandLineOption lower(QStringList() << "l" << "lower",
|
||||
QCommandLineOption lower(QStringList() << "l"
|
||||
<< "lower",
|
||||
QObject::tr("Use lowercase characters"));
|
||||
parser.addOption(lower);
|
||||
QCommandLineOption upper(QStringList() << "u" << "upper",
|
||||
QCommandLineOption upper(QStringList() << "u"
|
||||
<< "upper",
|
||||
QObject::tr("Use uppercase characters"));
|
||||
parser.addOption(upper);
|
||||
QCommandLineOption numeric(QStringList() << "n" << "numeric",
|
||||
QCommandLineOption numeric(QStringList() << "n"
|
||||
<< "numeric",
|
||||
QObject::tr("Use numbers."));
|
||||
parser.addOption(numeric);
|
||||
QCommandLineOption special(QStringList() << "s" << "special",
|
||||
QCommandLineOption special(QStringList() << "s"
|
||||
<< "special",
|
||||
QObject::tr("Use special characters"));
|
||||
parser.addOption(special);
|
||||
QCommandLineOption extended(QStringList() << "e" << "extended",
|
||||
QCommandLineOption extended(QStringList() << "e"
|
||||
<< "extended",
|
||||
QObject::tr("Use extended ASCII"));
|
||||
parser.addOption(extended);
|
||||
QCommandLineOption exclude(QStringList() << "x" << "exclude",
|
||||
QCommandLineOption exclude(QStringList() << "x"
|
||||
<< "exclude",
|
||||
QObject::tr("Exclude character set"),
|
||||
QObject::tr("chars"));
|
||||
parser.addOption(exclude);
|
||||
|
@ -49,7 +49,8 @@ int List::execute(const QStringList& arguments)
|
||||
parser.addOption(Command::QuietOption);
|
||||
parser.addOption(Command::KeyFileOption);
|
||||
|
||||
QCommandLineOption recursiveOption(QStringList() << "R" << "recursive",
|
||||
QCommandLineOption recursiveOption(QStringList() << "R"
|
||||
<< "recursive",
|
||||
QObject::tr("Recursively list the elements of the group."));
|
||||
parser.addOption(recursiveOption);
|
||||
parser.addHelpOption();
|
||||
|
@ -47,12 +47,14 @@ int Merge::execute(const QStringList& arguments)
|
||||
parser.addPositionalArgument("database2", QObject::tr("Path of the database to merge from."));
|
||||
parser.addOption(Command::QuietOption);
|
||||
|
||||
QCommandLineOption samePasswordOption(QStringList() << "s" << "same-credentials",
|
||||
QCommandLineOption samePasswordOption(QStringList() << "s"
|
||||
<< "same-credentials",
|
||||
QObject::tr("Use the same credentials for both database files."));
|
||||
parser.addOption(samePasswordOption);
|
||||
parser.addOption(Command::KeyFileOption);
|
||||
|
||||
QCommandLineOption keyFileFromOption(QStringList() << "f" << "key-file-from",
|
||||
QCommandLineOption keyFileFromOption(QStringList() << "f"
|
||||
<< "key-file-from",
|
||||
QObject::tr("Key file of the database to merge from."),
|
||||
QObject::tr("path"));
|
||||
parser.addOption(keyFileFromOption);
|
||||
|
@ -48,11 +48,13 @@ int Show::execute(const QStringList& arguments)
|
||||
parser.addPositionalArgument("database", QObject::tr("Path of the database."));
|
||||
parser.addOption(Command::QuietOption);
|
||||
parser.addOption(Command::KeyFileOption);
|
||||
QCommandLineOption totp(QStringList() << "t" << "totp",
|
||||
QCommandLineOption totp(QStringList() << "t"
|
||||
<< "totp",
|
||||
QObject::tr("Show the entry's current TOTP."));
|
||||
parser.addOption(totp);
|
||||
QCommandLineOption attributes(
|
||||
QStringList() << "a" << "attributes",
|
||||
QStringList() << "a"
|
||||
<< "attributes",
|
||||
QObject::tr(
|
||||
"Names of the attributes to show. "
|
||||
"This option can be specified more than once, with each attribute shown one-per-line in the given order. "
|
||||
|
@ -28,20 +28,20 @@
|
||||
|
||||
namespace Utils
|
||||
{
|
||||
/**
|
||||
* STDOUT file handle for the CLI.
|
||||
*/
|
||||
FILE* STDOUT = stdout;
|
||||
/**
|
||||
* STDOUT file handle for the CLI.
|
||||
*/
|
||||
FILE* STDOUT = stdout;
|
||||
|
||||
/**
|
||||
* STDERR file handle for the CLI.
|
||||
*/
|
||||
FILE* STDERR = stderr;
|
||||
/**
|
||||
* STDERR file handle for the CLI.
|
||||
*/
|
||||
FILE* STDERR = stderr;
|
||||
|
||||
/**
|
||||
* STDIN file handle for the CLI.
|
||||
*/
|
||||
FILE* STDIN = stdin;
|
||||
/**
|
||||
* STDIN file handle for the CLI.
|
||||
*/
|
||||
FILE* STDIN = stdin;
|
||||
|
||||
/**
|
||||
* DEVNULL file handle for the CLI.
|
||||
@ -56,48 +56,47 @@ FILE* DEVNULL = fopen("/dev/null", "w");
|
||||
void setStdinEcho(bool enable = true)
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE);
|
||||
DWORD mode;
|
||||
GetConsoleMode(hIn, &mode);
|
||||
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);
|
||||
if (enable) {
|
||||
mode |= ENABLE_ECHO_INPUT;
|
||||
} else {
|
||||
mode &= ~ENABLE_ECHO_INPUT;
|
||||
}
|
||||
|
||||
SetConsoleMode(hIn, mode);
|
||||
#else
|
||||
struct termios t;
|
||||
tcgetattr(STDIN_FILENO, &t);
|
||||
struct termios t;
|
||||
tcgetattr(STDIN_FILENO, &t);
|
||||
|
||||
if (enable) {
|
||||
t.c_lflag |= ECHO;
|
||||
} else {
|
||||
t.c_lflag &= ~ECHO;
|
||||
if (enable) {
|
||||
t.c_lflag |= ECHO;
|
||||
} else {
|
||||
t.c_lflag &= ~ECHO;
|
||||
}
|
||||
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &t);
|
||||
#endif
|
||||
}
|
||||
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &t);
|
||||
#endif
|
||||
}
|
||||
namespace Test
|
||||
{
|
||||
QStringList nextPasswords = {};
|
||||
|
||||
namespace Test
|
||||
{
|
||||
QStringList nextPasswords = {};
|
||||
|
||||
/**
|
||||
* Set the next password returned by \link getPassword() instead of reading it from STDIN.
|
||||
* Multiple calls to this method will fill a queue of passwords.
|
||||
* This function is intended for testing purposes.
|
||||
*
|
||||
* @param password password to return next
|
||||
*/
|
||||
void setNextPassword(const QString& password)
|
||||
{
|
||||
nextPasswords.append(password);
|
||||
}
|
||||
} // namespace Test
|
||||
/**
|
||||
* Set the next password returned by \link getPassword() instead of reading it from STDIN.
|
||||
* Multiple calls to this method will fill a queue of passwords.
|
||||
* This function is intended for testing purposes.
|
||||
*
|
||||
* @param password password to return next
|
||||
*/
|
||||
void setNextPassword(const QString& password)
|
||||
{
|
||||
nextPasswords.append(password);
|
||||
}
|
||||
} // namespace Test
|
||||
|
||||
/**
|
||||
* Read a user password from STDIN or return a password previously
|
||||
@ -109,74 +108,74 @@ QString getPassword(FILE* outputDescriptor)
|
||||
{
|
||||
TextStream out(outputDescriptor, QIODevice::WriteOnly);
|
||||
|
||||
// return preset password if one is set
|
||||
if (!Test::nextPasswords.isEmpty()) {
|
||||
auto password = Test::nextPasswords.takeFirst();
|
||||
// simulate user entering newline
|
||||
// return preset password if one is set
|
||||
if (!Test::nextPasswords.isEmpty()) {
|
||||
auto password = Test::nextPasswords.takeFirst();
|
||||
// simulate user entering newline
|
||||
out << endl;
|
||||
return password;
|
||||
}
|
||||
|
||||
TextStream in(STDIN, QIODevice::ReadOnly);
|
||||
|
||||
setStdinEcho(false);
|
||||
QString line = in.readLine();
|
||||
setStdinEcho(true);
|
||||
out << endl;
|
||||
return password;
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
TextStream in(STDIN, QIODevice::ReadOnly);
|
||||
/**
|
||||
* A valid and running event loop is needed to use the global QClipboard,
|
||||
* so we need to use this from the CLI.
|
||||
*/
|
||||
int clipText(const QString& text)
|
||||
{
|
||||
TextStream err(Utils::STDERR);
|
||||
|
||||
setStdinEcho(false);
|
||||
QString line = in.readLine();
|
||||
setStdinEcho(true);
|
||||
out << endl;
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
/**
|
||||
* A valid and running event loop is needed to use the global QClipboard,
|
||||
* so we need to use this from the CLI.
|
||||
*/
|
||||
int clipText(const QString& text)
|
||||
{
|
||||
TextStream err(Utils::STDERR);
|
||||
|
||||
QString programName = "";
|
||||
QStringList arguments;
|
||||
QString programName = "";
|
||||
QStringList arguments;
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
programName = "xclip";
|
||||
arguments << "-i"
|
||||
<< "-selection"
|
||||
<< "clipboard";
|
||||
programName = "xclip";
|
||||
arguments << "-i"
|
||||
<< "-selection"
|
||||
<< "clipboard";
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_MACOS
|
||||
programName = "pbcopy";
|
||||
programName = "pbcopy";
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
programName = "clip";
|
||||
programName = "clip";
|
||||
#endif
|
||||
|
||||
if (programName.isEmpty()) {
|
||||
err << QObject::tr("No program defined for clipboard manipulation");
|
||||
err.flush();
|
||||
return EXIT_FAILURE;
|
||||
if (programName.isEmpty()) {
|
||||
err << QObject::tr("No program defined for clipboard manipulation");
|
||||
err.flush();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
auto* clipProcess = new QProcess(nullptr);
|
||||
clipProcess->start(programName, arguments);
|
||||
clipProcess->waitForStarted();
|
||||
|
||||
if (clipProcess->state() != QProcess::Running) {
|
||||
err << QObject::tr("Unable to start program %1").arg(programName);
|
||||
err.flush();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (clipProcess->write(text.toLatin1()) == -1) {
|
||||
qDebug("Unable to write to process : %s", qPrintable(clipProcess->errorString()));
|
||||
}
|
||||
clipProcess->waitForBytesWritten();
|
||||
clipProcess->closeWriteChannel();
|
||||
clipProcess->waitForFinished();
|
||||
|
||||
return clipProcess->exitCode();
|
||||
}
|
||||
|
||||
auto* clipProcess = new QProcess(nullptr);
|
||||
clipProcess->start(programName, arguments);
|
||||
clipProcess->waitForStarted();
|
||||
|
||||
if (clipProcess->state() != QProcess::Running) {
|
||||
err << QObject::tr("Unable to start program %1").arg(programName);
|
||||
err.flush();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (clipProcess->write(text.toLatin1()) == -1) {
|
||||
qDebug("Unable to write to process : %s", qPrintable(clipProcess->errorString()));
|
||||
}
|
||||
clipProcess->waitForBytesWritten();
|
||||
clipProcess->closeWriteChannel();
|
||||
clipProcess->waitForFinished();
|
||||
|
||||
return clipProcess->exitCode();
|
||||
}
|
||||
|
||||
} // namespace Utils
|
||||
} // namespace Utils
|
||||
|
@ -18,24 +18,24 @@
|
||||
#ifndef KEEPASSXC_UTILS_H
|
||||
#define KEEPASSXC_UTILS_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
#include "cli/TextStream.h"
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
namespace Utils
|
||||
{
|
||||
extern FILE* STDOUT;
|
||||
extern FILE* STDERR;
|
||||
extern FILE* STDIN;
|
||||
extern FILE* DEVNULL;
|
||||
extern FILE* STDOUT;
|
||||
extern FILE* STDERR;
|
||||
extern FILE* STDIN;
|
||||
extern FILE* DEVNULL;
|
||||
|
||||
void setStdinEcho(bool enable);
|
||||
QString getPassword(FILE* outputDescriptor = STDOUT);
|
||||
int clipText(const QString& text);
|
||||
void setStdinEcho(bool enable);
|
||||
QString getPassword(FILE* outputDescriptor = STDOUT);
|
||||
int clipText(const QString& text);
|
||||
|
||||
namespace Test
|
||||
{
|
||||
void setNextPassword(const QString& password);
|
||||
}
|
||||
};
|
||||
namespace Test
|
||||
{
|
||||
void setNextPassword(const QString& password);
|
||||
}
|
||||
}; // namespace Utils
|
||||
|
||||
#endif // KEEPASSXC_UTILS_H
|
||||
|
@ -13,7 +13,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*/
|
||||
|
||||
#ifndef KEEPASSXC_ASYNCTASK_HPP
|
||||
#define KEEPASSXC_ASYNCTASK_HPP
|
||||
|
@ -26,201 +26,201 @@
|
||||
|
||||
namespace Bootstrap
|
||||
{
|
||||
/**
|
||||
* When QNetworkAccessManager is instantiated it regularly starts polling
|
||||
* all network interfaces to see if anything changes and if so, what. This
|
||||
* creates a latency spike every 10 seconds on Mac OS 10.12+ and Windows 7 >=
|
||||
* when on a wifi connection.
|
||||
* So here we disable it for lack of better measure.
|
||||
* This will also cause this message: QObject::startTimer: Timers cannot
|
||||
* have negative intervals
|
||||
* For more info see:
|
||||
* - https://bugreports.qt.io/browse/QTBUG-40332
|
||||
* - https://bugreports.qt.io/browse/QTBUG-46015
|
||||
*/
|
||||
static inline void applyEarlyQNetworkAccessManagerWorkaround()
|
||||
{
|
||||
qputenv("QT_BEARER_POLL_TIMEOUT", QByteArray::number(-1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform early application bootstrapping such as setting up search paths,
|
||||
* configuration OS security properties, and loading translators.
|
||||
* A QApplication object has to be instantiated before calling this function.
|
||||
*/
|
||||
void bootstrapApplication()
|
||||
{
|
||||
#ifdef QT_NO_DEBUG
|
||||
disableCoreDumps();
|
||||
#endif
|
||||
setupSearchPaths();
|
||||
applyEarlyQNetworkAccessManagerWorkaround();
|
||||
Translator::installTranslators();
|
||||
|
||||
#ifdef Q_OS_MACOS
|
||||
// Don't show menu icons on OSX
|
||||
QApplication::setAttribute(Qt::AA_DontShowIconsInMenus);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore the main window's state after launch
|
||||
*
|
||||
* @param mainWindow the main window whose state to restore
|
||||
*/
|
||||
void restoreMainWindowState(MainWindow& mainWindow)
|
||||
{
|
||||
// start minimized if configured
|
||||
if (config()->get("GUI/MinimizeOnStartup").toBool()) {
|
||||
mainWindow.showMinimized();
|
||||
} else {
|
||||
mainWindow.bringToFront();
|
||||
/**
|
||||
* When QNetworkAccessManager is instantiated it regularly starts polling
|
||||
* all network interfaces to see if anything changes and if so, what. This
|
||||
* creates a latency spike every 10 seconds on Mac OS 10.12+ and Windows 7 >=
|
||||
* when on a wifi connection.
|
||||
* So here we disable it for lack of better measure.
|
||||
* This will also cause this message: QObject::startTimer: Timers cannot
|
||||
* have negative intervals
|
||||
* For more info see:
|
||||
* - https://bugreports.qt.io/browse/QTBUG-40332
|
||||
* - https://bugreports.qt.io/browse/QTBUG-46015
|
||||
*/
|
||||
static inline void applyEarlyQNetworkAccessManagerWorkaround()
|
||||
{
|
||||
qputenv("QT_BEARER_POLL_TIMEOUT", QByteArray::number(-1));
|
||||
}
|
||||
|
||||
if (config()->get("OpenPreviousDatabasesOnStartup").toBool()) {
|
||||
const QStringList fileNames = config()->get("LastOpenedDatabases").toStringList();
|
||||
for (const QString& filename : fileNames) {
|
||||
if (!filename.isEmpty() && QFile::exists(filename)) {
|
||||
mainWindow.openDatabase(filename);
|
||||
/**
|
||||
* Perform early application bootstrapping such as setting up search paths,
|
||||
* configuration OS security properties, and loading translators.
|
||||
* A QApplication object has to be instantiated before calling this function.
|
||||
*/
|
||||
void bootstrapApplication()
|
||||
{
|
||||
#ifdef QT_NO_DEBUG
|
||||
disableCoreDumps();
|
||||
#endif
|
||||
setupSearchPaths();
|
||||
applyEarlyQNetworkAccessManagerWorkaround();
|
||||
Translator::installTranslators();
|
||||
|
||||
#ifdef Q_OS_MACOS
|
||||
// Don't show menu icons on OSX
|
||||
QApplication::setAttribute(Qt::AA_DontShowIconsInMenus);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore the main window's state after launch
|
||||
*
|
||||
* @param mainWindow the main window whose state to restore
|
||||
*/
|
||||
void restoreMainWindowState(MainWindow& mainWindow)
|
||||
{
|
||||
// start minimized if configured
|
||||
if (config()->get("GUI/MinimizeOnStartup").toBool()) {
|
||||
mainWindow.showMinimized();
|
||||
} else {
|
||||
mainWindow.bringToFront();
|
||||
}
|
||||
|
||||
if (config()->get("OpenPreviousDatabasesOnStartup").toBool()) {
|
||||
const QStringList fileNames = config()->get("LastOpenedDatabases").toStringList();
|
||||
for (const QString& filename : fileNames) {
|
||||
if (!filename.isEmpty() && QFile::exists(filename)) {
|
||||
mainWindow.openDatabase(filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// LCOV_EXCL_START
|
||||
void disableCoreDumps()
|
||||
{
|
||||
// default to true
|
||||
// there is no point in printing a warning if this is not implemented on the platform
|
||||
bool success = true;
|
||||
// LCOV_EXCL_START
|
||||
void disableCoreDumps()
|
||||
{
|
||||
// default to true
|
||||
// there is no point in printing a warning if this is not implemented on the platform
|
||||
bool success = true;
|
||||
|
||||
#if defined(HAVE_RLIMIT_CORE)
|
||||
struct rlimit limit;
|
||||
limit.rlim_cur = 0;
|
||||
limit.rlim_max = 0;
|
||||
success = success && (setrlimit(RLIMIT_CORE, &limit) == 0);
|
||||
struct rlimit limit;
|
||||
limit.rlim_cur = 0;
|
||||
limit.rlim_max = 0;
|
||||
success = success && (setrlimit(RLIMIT_CORE, &limit) == 0);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_PR_SET_DUMPABLE)
|
||||
success = success && (prctl(PR_SET_DUMPABLE, 0) == 0);
|
||||
success = success && (prctl(PR_SET_DUMPABLE, 0) == 0);
|
||||
#endif
|
||||
|
||||
// Mac OS X
|
||||
#ifdef HAVE_PT_DENY_ATTACH
|
||||
success = success && (ptrace(PT_DENY_ATTACH, 0, 0, 0) == 0);
|
||||
success = success && (ptrace(PT_DENY_ATTACH, 0, 0, 0) == 0);
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
success = success && createWindowsDACL();
|
||||
success = success && createWindowsDACL();
|
||||
#endif
|
||||
|
||||
if (!success) {
|
||||
qWarning("Unable to disable core dumps.");
|
||||
if (!success) {
|
||||
qWarning("Unable to disable core dumps.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// This function grants the user associated with the process token minimal access rights and
|
||||
// denies everything else on Windows. This includes PROCESS_QUERY_INFORMATION and
|
||||
// PROCESS_VM_READ access rights that are required for MiniDumpWriteDump() or ReadProcessMemory().
|
||||
// We do this using a discretionary access control list (DACL). Effectively this prevents
|
||||
// crash dumps and disallows other processes from accessing our memory. This works as long
|
||||
// as you do not have admin privileges, since then you are able to grant yourself the
|
||||
// SeDebugPrivilege or SeTakeOwnershipPrivilege and circumvent the DACL.
|
||||
//
|
||||
bool createWindowsDACL()
|
||||
{
|
||||
bool bSuccess = false;
|
||||
//
|
||||
// This function grants the user associated with the process token minimal access rights and
|
||||
// denies everything else on Windows. This includes PROCESS_QUERY_INFORMATION and
|
||||
// PROCESS_VM_READ access rights that are required for MiniDumpWriteDump() or ReadProcessMemory().
|
||||
// We do this using a discretionary access control list (DACL). Effectively this prevents
|
||||
// crash dumps and disallows other processes from accessing our memory. This works as long
|
||||
// as you do not have admin privileges, since then you are able to grant yourself the
|
||||
// SeDebugPrivilege or SeTakeOwnershipPrivilege and circumvent the DACL.
|
||||
//
|
||||
bool createWindowsDACL()
|
||||
{
|
||||
bool bSuccess = false;
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
// Process token and user
|
||||
HANDLE hToken = nullptr;
|
||||
PTOKEN_USER pTokenUser = nullptr;
|
||||
DWORD cbBufferSize = 0;
|
||||
// Process token and user
|
||||
HANDLE hToken = nullptr;
|
||||
PTOKEN_USER pTokenUser = nullptr;
|
||||
DWORD cbBufferSize = 0;
|
||||
|
||||
// Access control list
|
||||
PACL pACL = nullptr;
|
||||
DWORD cbACL = 0;
|
||||
// Access control list
|
||||
PACL pACL = nullptr;
|
||||
DWORD cbACL = 0;
|
||||
|
||||
// Open the access token associated with the calling process
|
||||
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) {
|
||||
goto Cleanup;
|
||||
}
|
||||
// Open the access token associated with the calling process
|
||||
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) {
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Retrieve the token information in a TOKEN_USER structure
|
||||
GetTokenInformation(hToken, TokenUser, nullptr, 0, &cbBufferSize);
|
||||
// Retrieve the token information in a TOKEN_USER structure
|
||||
GetTokenInformation(hToken, TokenUser, nullptr, 0, &cbBufferSize);
|
||||
|
||||
pTokenUser = static_cast<PTOKEN_USER>(HeapAlloc(GetProcessHeap(), 0, cbBufferSize));
|
||||
if (pTokenUser == nullptr) {
|
||||
goto Cleanup;
|
||||
}
|
||||
pTokenUser = static_cast<PTOKEN_USER>(HeapAlloc(GetProcessHeap(), 0, cbBufferSize));
|
||||
if (pTokenUser == nullptr) {
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
if (!GetTokenInformation(hToken, TokenUser, pTokenUser, cbBufferSize, &cbBufferSize)) {
|
||||
goto Cleanup;
|
||||
}
|
||||
if (!GetTokenInformation(hToken, TokenUser, pTokenUser, cbBufferSize, &cbBufferSize)) {
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
if (!IsValidSid(pTokenUser->User.Sid)) {
|
||||
goto Cleanup;
|
||||
}
|
||||
if (!IsValidSid(pTokenUser->User.Sid)) {
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Calculate the amount of memory that must be allocated for the DACL
|
||||
cbACL = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pTokenUser->User.Sid);
|
||||
// Calculate the amount of memory that must be allocated for the DACL
|
||||
cbACL = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pTokenUser->User.Sid);
|
||||
|
||||
// Create and initialize an ACL
|
||||
pACL = static_cast<PACL>(HeapAlloc(GetProcessHeap(), 0, cbACL));
|
||||
if (pACL == nullptr) {
|
||||
goto Cleanup;
|
||||
}
|
||||
// Create and initialize an ACL
|
||||
pACL = static_cast<PACL>(HeapAlloc(GetProcessHeap(), 0, cbACL));
|
||||
if (pACL == nullptr) {
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
if (!InitializeAcl(pACL, cbACL, ACL_REVISION)) {
|
||||
goto Cleanup;
|
||||
}
|
||||
if (!InitializeAcl(pACL, cbACL, ACL_REVISION)) {
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Add allowed access control entries, everything else is denied
|
||||
if (!AddAccessAllowedAce(
|
||||
pACL,
|
||||
ACL_REVISION,
|
||||
SYNCHRONIZE | PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_TERMINATE, // same as protected process
|
||||
pTokenUser->User.Sid // pointer to the trustee's SID
|
||||
)) {
|
||||
goto Cleanup;
|
||||
}
|
||||
// Add allowed access control entries, everything else is denied
|
||||
if (!AddAccessAllowedAce(
|
||||
pACL,
|
||||
ACL_REVISION,
|
||||
SYNCHRONIZE | PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_TERMINATE, // same as protected process
|
||||
pTokenUser->User.Sid // pointer to the trustee's SID
|
||||
)) {
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Set discretionary access control list
|
||||
bSuccess = ERROR_SUCCESS
|
||||
== SetSecurityInfo(GetCurrentProcess(), // object handle
|
||||
SE_KERNEL_OBJECT, // type of object
|
||||
DACL_SECURITY_INFORMATION, // change only the objects DACL
|
||||
nullptr,
|
||||
nullptr, // do not change owner or group
|
||||
pACL, // DACL specified
|
||||
nullptr // do not change SACL
|
||||
);
|
||||
// Set discretionary access control list
|
||||
bSuccess = ERROR_SUCCESS
|
||||
== SetSecurityInfo(GetCurrentProcess(), // object handle
|
||||
SE_KERNEL_OBJECT, // type of object
|
||||
DACL_SECURITY_INFORMATION, // change only the objects DACL
|
||||
nullptr,
|
||||
nullptr, // do not change owner or group
|
||||
pACL, // DACL specified
|
||||
nullptr // do not change SACL
|
||||
);
|
||||
|
||||
Cleanup:
|
||||
Cleanup:
|
||||
|
||||
if (pACL != nullptr) {
|
||||
HeapFree(GetProcessHeap(), 0, pACL);
|
||||
}
|
||||
if (pTokenUser != nullptr) {
|
||||
HeapFree(GetProcessHeap(), 0, pTokenUser);
|
||||
}
|
||||
if (hToken != nullptr) {
|
||||
CloseHandle(hToken);
|
||||
}
|
||||
if (pACL != nullptr) {
|
||||
HeapFree(GetProcessHeap(), 0, pACL);
|
||||
}
|
||||
if (pTokenUser != nullptr) {
|
||||
HeapFree(GetProcessHeap(), 0, pTokenUser);
|
||||
}
|
||||
if (hToken != nullptr) {
|
||||
CloseHandle(hToken);
|
||||
}
|
||||
#endif
|
||||
|
||||
return bSuccess;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
return bSuccess;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
void setupSearchPaths()
|
||||
{
|
||||
void setupSearchPaths()
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
// Make sure Windows doesn't load DLLs from the current working directory
|
||||
SetDllDirectoryA("");
|
||||
SetSearchPathMode(BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE);
|
||||
// Make sure Windows doesn't load DLLs from the current working directory
|
||||
SetDllDirectoryA("");
|
||||
SetSearchPathMode(BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Bootstrap
|
||||
} // namespace Bootstrap
|
||||
|
@ -15,7 +15,6 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef KEEPASSXC_BOOTSTRAP_H
|
||||
#define KEEPASSXC_BOOTSTRAP_H
|
||||
|
||||
@ -23,12 +22,11 @@
|
||||
|
||||
namespace Bootstrap
|
||||
{
|
||||
void bootstrapApplication();
|
||||
void restoreMainWindowState(MainWindow& mainWindow);
|
||||
void disableCoreDumps();
|
||||
bool createWindowsDACL();
|
||||
void setupSearchPaths();
|
||||
};
|
||||
void bootstrapApplication();
|
||||
void restoreMainWindowState(MainWindow& mainWindow);
|
||||
void disableCoreDumps();
|
||||
bool createWindowsDACL();
|
||||
void setupSearchPaths();
|
||||
}; // namespace Bootstrap
|
||||
|
||||
|
||||
#endif //KEEPASSXC_BOOTSTRAP_H
|
||||
#endif // KEEPASSXC_BOOTSTRAP_H
|
||||
|
@ -84,7 +84,7 @@ void Config::upgrade()
|
||||
{
|
||||
for (const auto& setting : deprecationMap.keys()) {
|
||||
if (m_settings->contains(setting)) {
|
||||
if(!deprecationMap.value(setting).isEmpty()) {
|
||||
if (!deprecationMap.value(setting).isEmpty()) {
|
||||
// Add entry with new name and old entry's value
|
||||
m_settings->setValue(deprecationMap.value(setting), m_settings->value(setting));
|
||||
}
|
||||
|
@ -403,10 +403,11 @@ QString CsvParser::getStatus() const
|
||||
|
||||
int CsvParser::getCsvCols() const
|
||||
{
|
||||
if ((m_table.size() > 0) && (m_table.at(0).size() > 0))
|
||||
if (!m_table.isEmpty() && !m_table.at(0).isEmpty()) {
|
||||
return m_table.at(0).size();
|
||||
else
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int CsvParser::getCsvRows() const
|
||||
|
@ -720,14 +720,15 @@ QSharedPointer<Database> Database::unlockFromStdin(const QString& databaseFilena
|
||||
QString errorMessage;
|
||||
// LCOV_EXCL_START
|
||||
if (!fileKey->load(keyFilename, &errorMessage)) {
|
||||
err << QObject::tr("Failed to load key file %1: %2").arg(keyFilename, errorMessage)<< endl;
|
||||
err << QObject::tr("Failed to load key file %1: %2").arg(keyFilename, errorMessage) << endl;
|
||||
return {};
|
||||
}
|
||||
|
||||
if (fileKey->type() != FileKey::Hashed) {
|
||||
err << QObject::tr("WARNING: You are using a legacy key file format which may become\n"
|
||||
"unsupported in the future.\n\n"
|
||||
"Please consider generating a new key file.") << endl;
|
||||
"Please consider generating a new key file.")
|
||||
<< endl;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
|
@ -657,12 +657,14 @@ Entry* Entry::clone(CloneFlags flags) const
|
||||
if (flags & CloneUserAsRef) {
|
||||
// Build the username reference
|
||||
QString username = "{REF:U@I:" + uuidToHex() + "}";
|
||||
entry->m_attributes->set(EntryAttributes::UserNameKey, username.toUpper(), m_attributes->isProtected(EntryAttributes::UserNameKey));
|
||||
entry->m_attributes->set(
|
||||
EntryAttributes::UserNameKey, username.toUpper(), m_attributes->isProtected(EntryAttributes::UserNameKey));
|
||||
}
|
||||
|
||||
if (flags & ClonePassAsRef) {
|
||||
QString password = "{REF:P@I:" + uuidToHex() + "}";
|
||||
entry->m_attributes->set(EntryAttributes::PasswordKey, password.toUpper(), m_attributes->isProtected(EntryAttributes::PasswordKey));
|
||||
entry->m_attributes->set(
|
||||
EntryAttributes::PasswordKey, password.toUpper(), m_attributes->isProtected(EntryAttributes::PasswordKey));
|
||||
}
|
||||
|
||||
entry->m_autoTypeAssociations->copyDataFrom(m_autoTypeAssociations);
|
||||
@ -1065,7 +1067,8 @@ QString Entry::resolveUrl(const QString& url) const
|
||||
|
||||
// Validate the URL
|
||||
QUrl tempUrl = QUrl(newUrl);
|
||||
if (tempUrl.isValid() && (tempUrl.scheme() == "http" || tempUrl.scheme() == "https" || tempUrl.scheme() == "file")) {
|
||||
if (tempUrl.isValid()
|
||||
&& (tempUrl.scheme() == "http" || tempUrl.scheme() == "https" || tempUrl.scheme() == "file")) {
|
||||
return tempUrl.url();
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,8 @@
|
||||
|
||||
class Database;
|
||||
class Group;
|
||||
namespace Totp {
|
||||
namespace Totp
|
||||
{
|
||||
struct Settings;
|
||||
}
|
||||
|
||||
|
@ -23,8 +23,8 @@ const QString EntryAttributes::UserNameKey = "UserName";
|
||||
const QString EntryAttributes::PasswordKey = "Password";
|
||||
const QString EntryAttributes::URLKey = "URL";
|
||||
const QString EntryAttributes::NotesKey = "Notes";
|
||||
const QStringList EntryAttributes::DefaultAttributes(QStringList() << TitleKey << UserNameKey << PasswordKey << URLKey
|
||||
<< NotesKey);
|
||||
const QStringList EntryAttributes::DefaultAttributes(QStringList()
|
||||
<< TitleKey << UserNameKey << PasswordKey << URLKey << NotesKey);
|
||||
|
||||
const QString EntryAttributes::WantedFieldGroupName = "WantedField";
|
||||
const QString EntryAttributes::SearchInGroupName = "SearchIn";
|
||||
|
@ -630,10 +630,12 @@ Entry* Group::findEntryByPathRecursive(const QString& entryPath, const QString&
|
||||
// Return the first entry that matches the full path OR if there is no leading
|
||||
// slash, return the first entry title that matches
|
||||
for (Entry* entry : entries()) {
|
||||
// clang-format off
|
||||
if (entryPath == (basePath + entry->title())
|
||||
|| (!entryPath.startsWith("/") && entry->title() == entryPath)) {
|
||||
return entry;
|
||||
}
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
for (Group* group : children()) {
|
||||
@ -654,9 +656,11 @@ Group* Group::findGroupByPath(const QString& groupPath)
|
||||
if (groupPath.isEmpty()) {
|
||||
normalizedGroupPath = QString("/"); // root group
|
||||
} else {
|
||||
// clang-format off
|
||||
normalizedGroupPath = (groupPath.startsWith("/") ? "" : "/")
|
||||
+ groupPath
|
||||
+ (groupPath.endsWith("/") ? "" : "/");
|
||||
// clang-format on
|
||||
}
|
||||
return findGroupByPathRecursive(normalizedGroupPath, "/");
|
||||
}
|
||||
@ -894,6 +898,7 @@ void Group::connectDatabaseSignalsRecursive(Database* db)
|
||||
}
|
||||
|
||||
if (db) {
|
||||
// clang-format off
|
||||
connect(this, SIGNAL(groupDataChanged(Group*)), db, SIGNAL(groupDataChanged(Group*)));
|
||||
connect(this, SIGNAL(groupAboutToRemove(Group*)), db, SIGNAL(groupAboutToRemove(Group*)));
|
||||
connect(this, SIGNAL(groupRemoved()), db, SIGNAL(groupRemoved()));
|
||||
@ -902,6 +907,7 @@ void Group::connectDatabaseSignalsRecursive(Database* db)
|
||||
connect(this, SIGNAL(aboutToMove(Group*,Group*,int)), db, SIGNAL(groupAboutToMove(Group*,Group*,int)));
|
||||
connect(this, SIGNAL(groupMoved()), db, SIGNAL(groupMoved()));
|
||||
connect(this, SIGNAL(groupModified()), db, SLOT(markAsModified()));
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
m_db = db;
|
||||
@ -983,7 +989,7 @@ QStringList Group::locate(const QString& locateTerm, const QString& currentPath)
|
||||
|
||||
for (const Entry* entry : asConst(m_entries)) {
|
||||
QString entryPath = currentPath + entry->title();
|
||||
if (entryPath.toLower().contains(locateTerm.toLower())) {
|
||||
if (entryPath.contains(locateTerm, Qt::CaseInsensitive)) {
|
||||
response << entryPath;
|
||||
}
|
||||
}
|
||||
|
@ -55,12 +55,13 @@ void InactivityTimer::deactivate()
|
||||
bool InactivityTimer::eventFilter(QObject* watched, QEvent* event)
|
||||
{
|
||||
const QEvent::Type type = event->type();
|
||||
|
||||
// clang-format off
|
||||
if ((type >= QEvent::MouseButtonPress && type <= QEvent::KeyRelease)
|
||||
|| (type >= QEvent::HoverEnter && type <= QEvent::HoverMove)
|
||||
|| (type == QEvent::Wheel)) {
|
||||
m_timer->start();
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
return QObject::eventFilter(watched, event);
|
||||
}
|
||||
|
@ -93,7 +93,8 @@ Merger::ChangeList Merger::mergeGroup(const MergeContext& context)
|
||||
moveEntry(targetEntry, context.m_targetGroup);
|
||||
} else {
|
||||
// Entry is already present in the database. Update it.
|
||||
const bool locationChanged = targetEntry->timeInfo().locationChanged() < sourceEntry->timeInfo().locationChanged();
|
||||
const bool locationChanged =
|
||||
targetEntry->timeInfo().locationChanged() < sourceEntry->timeInfo().locationChanged();
|
||||
if (locationChanged && targetEntry->group() != context.m_targetGroup) {
|
||||
changes << tr("Relocating %1 [%2]").arg(sourceEntry->title(), sourceEntry->uuidToHex());
|
||||
moveEntry(targetEntry, context.m_targetGroup);
|
||||
@ -136,7 +137,8 @@ Merger::ChangeList Merger::mergeGroup(const MergeContext& context)
|
||||
return changes;
|
||||
}
|
||||
|
||||
Merger::ChangeList Merger::resolveGroupConflict(const MergeContext& context, const Group* sourceChildGroup, Group* targetChildGroup)
|
||||
Merger::ChangeList
|
||||
Merger::resolveGroupConflict(const MergeContext& context, const Group* sourceChildGroup, Group* targetChildGroup)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
ChangeList changes;
|
||||
@ -261,10 +263,13 @@ void Merger::eraseGroup(Group* group)
|
||||
database->setDeletedObjects(deletions);
|
||||
}
|
||||
|
||||
Merger::ChangeList Merger::resolveEntryConflict_Duplicate(const MergeContext& context, const Entry* sourceEntry, Entry* targetEntry)
|
||||
Merger::ChangeList
|
||||
Merger::resolveEntryConflict_Duplicate(const MergeContext& context, const Entry* sourceEntry, Entry* targetEntry)
|
||||
{
|
||||
ChangeList changes;
|
||||
const int comparison = compare(targetEntry->timeInfo().lastModificationTime(), sourceEntry->timeInfo().lastModificationTime(), CompareItemIgnoreMilliseconds);
|
||||
const int comparison = compare(targetEntry->timeInfo().lastModificationTime(),
|
||||
sourceEntry->timeInfo().lastModificationTime(),
|
||||
CompareItemIgnoreMilliseconds);
|
||||
// if one entry is newer, create a clone and add it to the group
|
||||
if (comparison < 0) {
|
||||
Entry* clonedEntry = sourceEntry->clone(Entry::CloneNewUuid | Entry::CloneIncludeHistory);
|
||||
@ -280,11 +285,14 @@ Merger::ChangeList Merger::resolveEntryConflict_Duplicate(const MergeContext& co
|
||||
return changes;
|
||||
}
|
||||
|
||||
Merger::ChangeList Merger::resolveEntryConflict_KeepLocal(const MergeContext& context, const Entry* sourceEntry, Entry* targetEntry)
|
||||
Merger::ChangeList
|
||||
Merger::resolveEntryConflict_KeepLocal(const MergeContext& context, const Entry* sourceEntry, Entry* targetEntry)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
ChangeList changes;
|
||||
const int comparison = compare(targetEntry->timeInfo().lastModificationTime(), sourceEntry->timeInfo().lastModificationTime(), CompareItemIgnoreMilliseconds);
|
||||
const int comparison = compare(targetEntry->timeInfo().lastModificationTime(),
|
||||
sourceEntry->timeInfo().lastModificationTime(),
|
||||
CompareItemIgnoreMilliseconds);
|
||||
if (comparison < 0) {
|
||||
// we need to make our older entry "newer" than the new entry - therefore
|
||||
// we just create a new history entry without any changes - this preserves
|
||||
@ -293,18 +301,21 @@ Merger::ChangeList Merger::resolveEntryConflict_KeepLocal(const MergeContext& co
|
||||
// this type of merge changes the database timestamp since reapplying the
|
||||
// old entry is an active change of the database!
|
||||
changes << tr("Reapplying older target entry on top of newer source %1 [%2]")
|
||||
.arg(targetEntry->title(), targetEntry->uuidToHex());
|
||||
.arg(targetEntry->title(), targetEntry->uuidToHex());
|
||||
Entry* agedTargetEntry = targetEntry->clone(Entry::CloneNoFlags);
|
||||
targetEntry->addHistoryItem(agedTargetEntry);
|
||||
}
|
||||
return changes;
|
||||
}
|
||||
|
||||
Merger::ChangeList Merger::resolveEntryConflict_KeepRemote(const MergeContext& context, const Entry* sourceEntry, Entry* targetEntry)
|
||||
Merger::ChangeList
|
||||
Merger::resolveEntryConflict_KeepRemote(const MergeContext& context, const Entry* sourceEntry, Entry* targetEntry)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
ChangeList changes;
|
||||
const int comparison = compare(targetEntry->timeInfo().lastModificationTime(), sourceEntry->timeInfo().lastModificationTime(), CompareItemIgnoreMilliseconds);
|
||||
const int comparison = compare(targetEntry->timeInfo().lastModificationTime(),
|
||||
sourceEntry->timeInfo().lastModificationTime(),
|
||||
CompareItemIgnoreMilliseconds);
|
||||
if (comparison > 0) {
|
||||
// we need to make our older entry "newer" than the new entry - therefore
|
||||
// we just create a new history entry without any changes - this preserves
|
||||
@ -313,7 +324,7 @@ Merger::ChangeList Merger::resolveEntryConflict_KeepRemote(const MergeContext& c
|
||||
// this type of merge changes the database timestamp since reapplying the
|
||||
// old entry is an active change of the database!
|
||||
changes << tr("Reapplying older source entry on top of newer target %1 [%2]")
|
||||
.arg(targetEntry->title(), targetEntry->uuidToHex());
|
||||
.arg(targetEntry->title(), targetEntry->uuidToHex());
|
||||
targetEntry->beginUpdate();
|
||||
targetEntry->copyDataFrom(sourceEntry);
|
||||
targetEntry->endUpdate();
|
||||
@ -322,13 +333,17 @@ Merger::ChangeList Merger::resolveEntryConflict_KeepRemote(const MergeContext& c
|
||||
return changes;
|
||||
}
|
||||
|
||||
|
||||
Merger::ChangeList Merger::resolveEntryConflict_MergeHistories(const MergeContext& context, const Entry* sourceEntry, Entry* targetEntry, Group::MergeMode mergeMethod)
|
||||
Merger::ChangeList Merger::resolveEntryConflict_MergeHistories(const MergeContext& context,
|
||||
const Entry* sourceEntry,
|
||||
Entry* targetEntry,
|
||||
Group::MergeMode mergeMethod)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
|
||||
ChangeList changes;
|
||||
const int comparison = compare(targetEntry->timeInfo().lastModificationTime(), sourceEntry->timeInfo().lastModificationTime(), CompareItemIgnoreMilliseconds);
|
||||
const int comparison = compare(targetEntry->timeInfo().lastModificationTime(),
|
||||
sourceEntry->timeInfo().lastModificationTime(),
|
||||
CompareItemIgnoreMilliseconds);
|
||||
if (comparison < 0) {
|
||||
Group* currentGroup = targetEntry->group();
|
||||
Entry* clonedEntry = sourceEntry->clone(Entry::CloneIncludeHistory);
|
||||
@ -347,14 +362,15 @@ Merger::ChangeList Merger::resolveEntryConflict_MergeHistories(const MergeContex
|
||||
qPrintable(targetEntry->group()->name()));
|
||||
const bool changed = mergeHistory(sourceEntry, targetEntry, mergeMethod);
|
||||
if (changed) {
|
||||
changes << tr("Synchronizing from older source %1 [%2]").arg(targetEntry->title(), targetEntry->uuidToHex());
|
||||
changes
|
||||
<< tr("Synchronizing from older source %1 [%2]").arg(targetEntry->title(), targetEntry->uuidToHex());
|
||||
}
|
||||
}
|
||||
return changes;
|
||||
}
|
||||
|
||||
|
||||
Merger::ChangeList Merger::resolveEntryConflict(const MergeContext& context, const Entry* sourceEntry, Entry* targetEntry)
|
||||
Merger::ChangeList
|
||||
Merger::resolveEntryConflict(const MergeContext& context, const Entry* sourceEntry, Entry* targetEntry)
|
||||
{
|
||||
ChangeList changes;
|
||||
// We need to cut off the milliseconds since the persistent format only supports times down to seconds
|
||||
@ -395,15 +411,19 @@ bool Merger::mergeHistory(const Entry* sourceEntry, Entry* targetEntry, Group::M
|
||||
Q_UNUSED(mergeMethod);
|
||||
const auto targetHistoryItems = targetEntry->historyItems();
|
||||
const auto sourceHistoryItems = sourceEntry->historyItems();
|
||||
const int comparison = compare(sourceEntry->timeInfo().lastModificationTime(), targetEntry->timeInfo().lastModificationTime(), CompareItemIgnoreMilliseconds);
|
||||
const int comparison = compare(sourceEntry->timeInfo().lastModificationTime(),
|
||||
targetEntry->timeInfo().lastModificationTime(),
|
||||
CompareItemIgnoreMilliseconds);
|
||||
const bool preferLocal = mergeMethod == Group::KeepLocal || comparison < 0;
|
||||
const bool preferRemote = mergeMethod == Group::KeepRemote || comparison > 0;
|
||||
|
||||
QMap<QDateTime, Entry*> merged;
|
||||
for (Entry* historyItem : targetHistoryItems) {
|
||||
const QDateTime modificationTime = Clock::serialized(historyItem->timeInfo().lastModificationTime());
|
||||
if (merged.contains(modificationTime) && !merged[modificationTime]->equals(historyItem, CompareItemIgnoreMilliseconds)) {
|
||||
::qWarning("Inconsistent history entry of %s[%s] at %s contains conflicting changes - conflict resolution may lose data!",
|
||||
if (merged.contains(modificationTime)
|
||||
&& !merged[modificationTime]->equals(historyItem, CompareItemIgnoreMilliseconds)) {
|
||||
::qWarning("Inconsistent history entry of %s[%s] at %s contains conflicting changes - conflict resolution "
|
||||
"may lose data!",
|
||||
qPrintable(sourceEntry->title()),
|
||||
qPrintable(sourceEntry->uuidToHex()),
|
||||
qPrintable(modificationTime.toString("yyyy-MM-dd HH-mm-ss-zzz")));
|
||||
@ -413,8 +433,10 @@ bool Merger::mergeHistory(const Entry* sourceEntry, Entry* targetEntry, Group::M
|
||||
for (Entry* historyItem : sourceHistoryItems) {
|
||||
// Items with same modification-time changes will be regarded as same (like KeePass2)
|
||||
const QDateTime modificationTime = Clock::serialized(historyItem->timeInfo().lastModificationTime());
|
||||
if (merged.contains(modificationTime) && !merged[modificationTime]->equals(historyItem, CompareItemIgnoreMilliseconds)) {
|
||||
::qWarning("History entry of %s[%s] at %s contains conflicting changes - conflict resolution may lose data!",
|
||||
if (merged.contains(modificationTime)
|
||||
&& !merged[modificationTime]->equals(historyItem, CompareItemIgnoreMilliseconds)) {
|
||||
::qWarning(
|
||||
"History entry of %s[%s] at %s contains conflicting changes - conflict resolution may lose data!",
|
||||
qPrintable(sourceEntry->title()),
|
||||
qPrintable(sourceEntry->uuidToHex()),
|
||||
qPrintable(modificationTime.toString("yyyy-MM-dd HH-mm-ss-zzz")));
|
||||
@ -430,7 +452,9 @@ bool Merger::mergeHistory(const Entry* sourceEntry, Entry* targetEntry, Group::M
|
||||
|
||||
const QDateTime targetModificationTime = Clock::serialized(targetEntry->timeInfo().lastModificationTime());
|
||||
const QDateTime sourceModificationTime = Clock::serialized(sourceEntry->timeInfo().lastModificationTime());
|
||||
if (targetModificationTime == sourceModificationTime && !targetEntry->equals(sourceEntry, CompareItemIgnoreMilliseconds | CompareItemIgnoreHistory | CompareItemIgnoreLocation)) {
|
||||
if (targetModificationTime == sourceModificationTime
|
||||
&& !targetEntry->equals(sourceEntry,
|
||||
CompareItemIgnoreMilliseconds | CompareItemIgnoreHistory | CompareItemIgnoreLocation)) {
|
||||
::qWarning("Entry of %s[%s] contains conflicting changes - conflict resolution may lose data!",
|
||||
qPrintable(sourceEntry->title()),
|
||||
qPrintable(sourceEntry->uuidToHex()));
|
||||
@ -480,7 +504,7 @@ bool Merger::mergeHistory(const Entry* sourceEntry, Entry* targetEntry, Group::M
|
||||
bool updateTimeInfo = targetEntry->canUpdateTimeinfo();
|
||||
targetEntry->setUpdateTimeinfo(false);
|
||||
targetEntry->removeHistoryItems(targetHistoryItems);
|
||||
for (Entry* historyItem : merged.values()) {
|
||||
for (Entry* historyItem : merged) {
|
||||
Q_ASSERT(!historyItem->parent());
|
||||
targetEntry->addHistoryItem(historyItem);
|
||||
}
|
||||
|
@ -55,14 +55,22 @@ private:
|
||||
bool mergeHistory(const Entry* sourceEntry, Entry* targetEntry, Group::MergeMode mergeMethod);
|
||||
void moveEntry(Entry* entry, Group* targetGroup);
|
||||
void moveGroup(Group* group, Group* targetGroup);
|
||||
void eraseEntry(Entry* entry); // remove an entry without a trace in the deletedObjects - needed for elemination cloned entries
|
||||
void eraseGroup(Group* group); // remove an entry without a trace in the deletedObjects - needed for elemination cloned entries
|
||||
// remove an entry without a trace in the deletedObjects - needed for elemination cloned entries
|
||||
void eraseEntry(Entry* entry);
|
||||
// remove an entry without a trace in the deletedObjects - needed for elemination cloned entries
|
||||
void eraseGroup(Group* group);
|
||||
ChangeList resolveEntryConflict(const MergeContext& context, const Entry* existingEntry, Entry* otherEntry);
|
||||
ChangeList resolveGroupConflict(const MergeContext& context, const Group* existingGroup, Group* otherGroup);
|
||||
Merger::ChangeList resolveEntryConflict_Duplicate(const MergeContext& context, const Entry* sourceEntry, Entry* targetEntry);
|
||||
Merger::ChangeList resolveEntryConflict_KeepLocal(const MergeContext& context, const Entry* sourceEntry, Entry* targetEntry);
|
||||
Merger::ChangeList resolveEntryConflict_KeepRemote(const MergeContext& context, const Entry* sourceEntry, Entry* targetEntry);
|
||||
Merger::ChangeList resolveEntryConflict_MergeHistories(const MergeContext& context, const Entry* sourceEntry, Entry* targetEntry, Group::MergeMode mergeMethod);
|
||||
Merger::ChangeList
|
||||
resolveEntryConflict_Duplicate(const MergeContext& context, const Entry* sourceEntry, Entry* targetEntry);
|
||||
Merger::ChangeList
|
||||
resolveEntryConflict_KeepLocal(const MergeContext& context, const Entry* sourceEntry, Entry* targetEntry);
|
||||
Merger::ChangeList
|
||||
resolveEntryConflict_KeepRemote(const MergeContext& context, const Entry* sourceEntry, Entry* targetEntry);
|
||||
Merger::ChangeList resolveEntryConflict_MergeHistories(const MergeContext& context,
|
||||
const Entry* sourceEntry,
|
||||
Entry* targetEntry,
|
||||
Group::MergeMode mergeMethod);
|
||||
|
||||
private:
|
||||
MergeContext m_context;
|
||||
|
@ -429,7 +429,7 @@ void Metadata::removeCustomIcon(const QUuid& uuid)
|
||||
emit metadataModified();
|
||||
}
|
||||
|
||||
QUuid Metadata::findCustomIcon(const QImage &candidate)
|
||||
QUuid Metadata::findCustomIcon(const QImage& candidate)
|
||||
{
|
||||
QByteArray hash = hashImage(candidate);
|
||||
return m_customIconsHashes.value(hash, QUuid());
|
||||
|
@ -9,6 +9,7 @@ class OSEventFilter : public QAbstractNativeEventFilter
|
||||
public:
|
||||
OSEventFilter();
|
||||
bool nativeEventFilter(const QByteArray& eventType, void* message, long* result) override;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(OSEventFilter)
|
||||
};
|
||||
|
@ -124,7 +124,6 @@ bool PasswordGenerator::isValid() const
|
||||
}
|
||||
|
||||
return !passwordGroups().isEmpty();
|
||||
|
||||
}
|
||||
|
||||
QVector<PasswordGroup> PasswordGenerator::passwordGroups() const
|
||||
|
@ -22,14 +22,12 @@
|
||||
#include "core/Translator.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QElapsedTimer>
|
||||
#include <QIODevice>
|
||||
#include <QImageReader>
|
||||
#include <QLocale>
|
||||
#include <QStringList>
|
||||
#include <QRegularExpression>
|
||||
|
||||
#include <QElapsedTimer>
|
||||
|
||||
#include <QStringList>
|
||||
#include <cctype>
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
@ -59,147 +57,145 @@
|
||||
|
||||
namespace Tools
|
||||
{
|
||||
QString humanReadableFileSize(qint64 bytes, quint32 precision)
|
||||
{
|
||||
constexpr auto kibibyte = 1024;
|
||||
double size = bytes;
|
||||
QString humanReadableFileSize(qint64 bytes, quint32 precision)
|
||||
{
|
||||
constexpr auto kibibyte = 1024;
|
||||
double size = bytes;
|
||||
|
||||
QStringList units = QStringList() << "B"
|
||||
<< "KiB"
|
||||
<< "MiB"
|
||||
<< "GiB";
|
||||
int i = 0;
|
||||
int maxI = units.size() - 1;
|
||||
QStringList units = QStringList() << "B"
|
||||
<< "KiB"
|
||||
<< "MiB"
|
||||
<< "GiB";
|
||||
int i = 0;
|
||||
int maxI = units.size() - 1;
|
||||
|
||||
while ((size >= kibibyte) && (i < maxI)) {
|
||||
size /= kibibyte;
|
||||
i++;
|
||||
while ((size >= kibibyte) && (i < maxI)) {
|
||||
size /= kibibyte;
|
||||
i++;
|
||||
}
|
||||
|
||||
return QString("%1 %2").arg(QLocale().toString(size, 'f', precision), units.at(i));
|
||||
}
|
||||
|
||||
return QString("%1 %2").arg(QLocale().toString(size, 'f', precision), units.at(i));
|
||||
}
|
||||
bool readFromDevice(QIODevice* device, QByteArray& data, int size)
|
||||
{
|
||||
QByteArray buffer;
|
||||
buffer.resize(size);
|
||||
|
||||
bool readFromDevice(QIODevice* device, QByteArray& data, int size)
|
||||
{
|
||||
QByteArray buffer;
|
||||
buffer.resize(size);
|
||||
|
||||
qint64 readResult = device->read(buffer.data(), size);
|
||||
if (readResult == -1) {
|
||||
return false;
|
||||
} else {
|
||||
buffer.resize(readResult);
|
||||
data = buffer;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool readAllFromDevice(QIODevice* device, QByteArray& data)
|
||||
{
|
||||
QByteArray result;
|
||||
qint64 readBytes = 0;
|
||||
qint64 readResult;
|
||||
do {
|
||||
result.resize(result.size() + 16384);
|
||||
readResult = device->read(result.data() + readBytes, result.size() - readBytes);
|
||||
if (readResult > 0) {
|
||||
readBytes += readResult;
|
||||
qint64 readResult = device->read(buffer.data(), size);
|
||||
if (readResult == -1) {
|
||||
return false;
|
||||
} else {
|
||||
buffer.resize(readResult);
|
||||
data = buffer;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
while (readResult > 0);
|
||||
|
||||
if (readResult == -1) {
|
||||
return false;
|
||||
} else {
|
||||
result.resize(static_cast<int>(readBytes));
|
||||
data = result;
|
||||
return true;
|
||||
bool readAllFromDevice(QIODevice* device, QByteArray& data)
|
||||
{
|
||||
QByteArray result;
|
||||
qint64 readBytes = 0;
|
||||
qint64 readResult;
|
||||
do {
|
||||
result.resize(result.size() + 16384);
|
||||
readResult = device->read(result.data() + readBytes, result.size() - readBytes);
|
||||
if (readResult > 0) {
|
||||
readBytes += readResult;
|
||||
}
|
||||
} while (readResult > 0);
|
||||
|
||||
if (readResult == -1) {
|
||||
return false;
|
||||
} else {
|
||||
result.resize(static_cast<int>(readBytes));
|
||||
data = result;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString imageReaderFilter()
|
||||
{
|
||||
const QList<QByteArray> formats = QImageReader::supportedImageFormats();
|
||||
QStringList formatsStringList;
|
||||
QString imageReaderFilter()
|
||||
{
|
||||
const QList<QByteArray> formats = QImageReader::supportedImageFormats();
|
||||
QStringList formatsStringList;
|
||||
|
||||
for (const QByteArray& format : formats) {
|
||||
for (char codePoint : format) {
|
||||
if (!QChar(codePoint).isLetterOrNumber()) {
|
||||
continue;
|
||||
for (const QByteArray& format : formats) {
|
||||
for (char codePoint : format) {
|
||||
if (!QChar(codePoint).isLetterOrNumber()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
formatsStringList.append("*." + QString::fromLatin1(format).toLower());
|
||||
}
|
||||
|
||||
return formatsStringList.join(" ");
|
||||
}
|
||||
|
||||
bool isHex(const QByteArray& ba)
|
||||
{
|
||||
for (const unsigned char c : ba) {
|
||||
if (!std::isxdigit(c)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
formatsStringList.append("*." + QString::fromLatin1(format).toLower());
|
||||
return true;
|
||||
}
|
||||
|
||||
return formatsStringList.join(" ");
|
||||
}
|
||||
bool isBase64(const QByteArray& ba)
|
||||
{
|
||||
constexpr auto pattern = R"(^(?:[a-z0-9+]{4})*(?:[a-z0-9+]{3}=|[a-z0-9+]{2}==)?$)";
|
||||
QRegExp regexp(pattern, Qt::CaseInsensitive, QRegExp::RegExp2);
|
||||
|
||||
bool isHex(const QByteArray& ba)
|
||||
{
|
||||
for (const unsigned char c : ba) {
|
||||
if (!std::isxdigit(c)) {
|
||||
return false;
|
||||
QString base64 = QString::fromLatin1(ba.constData(), ba.size());
|
||||
|
||||
return regexp.exactMatch(base64);
|
||||
}
|
||||
|
||||
void sleep(int ms)
|
||||
{
|
||||
Q_ASSERT(ms >= 0);
|
||||
|
||||
if (ms == 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isBase64(const QByteArray& ba)
|
||||
{
|
||||
constexpr auto pattern = R"(^(?:[a-z0-9+]{4})*(?:[a-z0-9+]{3}=|[a-z0-9+]{2}==)?$)";
|
||||
QRegExp regexp(pattern, Qt::CaseInsensitive, QRegExp::RegExp2);
|
||||
|
||||
QString base64 = QString::fromLatin1(ba.constData(), ba.size());
|
||||
|
||||
return regexp.exactMatch(base64);
|
||||
}
|
||||
|
||||
void sleep(int ms)
|
||||
{
|
||||
Q_ASSERT(ms >= 0);
|
||||
|
||||
if (ms == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
Sleep(uint(ms));
|
||||
Sleep(uint(ms));
|
||||
#else
|
||||
timespec ts;
|
||||
ts.tv_sec = ms/1000;
|
||||
ts.tv_nsec = (ms%1000)*1000*1000;
|
||||
nanosleep(&ts, nullptr);
|
||||
timespec ts;
|
||||
ts.tv_sec = ms / 1000;
|
||||
ts.tv_nsec = (ms % 1000) * 1000 * 1000;
|
||||
nanosleep(&ts, nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
void wait(int ms)
|
||||
{
|
||||
Q_ASSERT(ms >= 0);
|
||||
|
||||
if (ms == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
QElapsedTimer timer;
|
||||
timer.start();
|
||||
void wait(int ms)
|
||||
{
|
||||
Q_ASSERT(ms >= 0);
|
||||
|
||||
if (ms <= 50) {
|
||||
QCoreApplication::processEvents(QEventLoop::AllEvents, ms);
|
||||
sleep(qMax(ms - static_cast<int>(timer.elapsed()), 0));
|
||||
} else {
|
||||
int timeLeft;
|
||||
do {
|
||||
timeLeft = ms - timer.elapsed();
|
||||
if (timeLeft > 0) {
|
||||
QCoreApplication::processEvents(QEventLoop::AllEvents, timeLeft);
|
||||
sleep(10);
|
||||
}
|
||||
if (ms == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
QElapsedTimer timer;
|
||||
timer.start();
|
||||
|
||||
if (ms <= 50) {
|
||||
QCoreApplication::processEvents(QEventLoop::AllEvents, ms);
|
||||
sleep(qMax(ms - static_cast<int>(timer.elapsed()), 0));
|
||||
} else {
|
||||
int timeLeft;
|
||||
do {
|
||||
timeLeft = ms - timer.elapsed();
|
||||
if (timeLeft > 0) {
|
||||
QCoreApplication::processEvents(QEventLoop::AllEvents, timeLeft);
|
||||
sleep(10);
|
||||
}
|
||||
} while (!timer.hasExpired(ms));
|
||||
}
|
||||
while (!timer.hasExpired(ms));
|
||||
}
|
||||
}
|
||||
|
||||
// Escape common regex symbols except for *, ?, and |
|
||||
auto regexEscape = QRegularExpression(R"re(([-[\]{}()+.,\\\/^$#]))re");
|
||||
|
@ -31,28 +31,28 @@ class QRegularExpression;
|
||||
|
||||
namespace Tools
|
||||
{
|
||||
QString humanReadableFileSize(qint64 bytes, quint32 precision = 2);
|
||||
bool readFromDevice(QIODevice* device, QByteArray& data, int size = 16384);
|
||||
bool readAllFromDevice(QIODevice* device, QByteArray& data);
|
||||
QString imageReaderFilter();
|
||||
bool isHex(const QByteArray& ba);
|
||||
bool isBase64(const QByteArray& ba);
|
||||
void sleep(int ms);
|
||||
void wait(int ms);
|
||||
QRegularExpression convertToRegex(const QString& string, bool useWildcards = false, bool exactMatch = false,
|
||||
bool caseSensitive = false);
|
||||
QString humanReadableFileSize(qint64 bytes, quint32 precision = 2);
|
||||
bool readFromDevice(QIODevice* device, QByteArray& data, int size = 16384);
|
||||
bool readAllFromDevice(QIODevice* device, QByteArray& data);
|
||||
QString imageReaderFilter();
|
||||
bool isHex(const QByteArray& ba);
|
||||
bool isBase64(const QByteArray& ba);
|
||||
void sleep(int ms);
|
||||
void wait(int ms);
|
||||
QRegularExpression convertToRegex(const QString& string, bool useWildcards = false,
|
||||
bool exactMatch = false, bool caseSensitive = false);
|
||||
|
||||
template <typename RandomAccessIterator, typename T>
|
||||
RandomAccessIterator binaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T& value)
|
||||
{
|
||||
RandomAccessIterator it = std::lower_bound(begin, end, value);
|
||||
template <typename RandomAccessIterator, typename T>
|
||||
RandomAccessIterator binaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T& value)
|
||||
{
|
||||
RandomAccessIterator it = std::lower_bound(begin, end, value);
|
||||
|
||||
if ((it == end) || (value < *it)) {
|
||||
return end;
|
||||
} else {
|
||||
return it;
|
||||
if ((it == end) || (value < *it)) {
|
||||
return end;
|
||||
} else {
|
||||
return it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Tools
|
||||
|
||||
|
@ -144,8 +144,9 @@ bool Crypto::testSha512()
|
||||
QByteArray sha512Test =
|
||||
CryptoHash::hash("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", CryptoHash::Sha512);
|
||||
|
||||
if (sha512Test != QByteArray::fromHex("204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b"
|
||||
"07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445")) {
|
||||
if (sha512Test
|
||||
!= QByteArray::fromHex("204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b"
|
||||
"07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445")) {
|
||||
raiseError("SHA-512 mismatch.");
|
||||
return false;
|
||||
}
|
||||
|
@ -1,19 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "SymmetricCipher.h"
|
||||
|
||||
|
@ -1,19 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef KEEPASSX_SYMMETRICCIPHER_H
|
||||
#define KEEPASSX_SYMMETRICCIPHER_H
|
||||
|
@ -1,19 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef KEEPASSX_SYMMETRICCIPHERBACKEND_H
|
||||
#define KEEPASSX_SYMMETRICCIPHERBACKEND_H
|
||||
|
@ -1,19 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "SymmetricCipherGcrypt.h"
|
||||
|
||||
|
@ -1,19 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef KEEPASSX_SYMMETRICCIPHERGCRYPT_H
|
||||
#define KEEPASSX_SYMMETRICCIPHERGCRYPT_H
|
||||
|
@ -46,12 +46,12 @@ protected:
|
||||
|
||||
private:
|
||||
Q_REQUIRED_RESULT static bool transformKeyRaw(const QByteArray& key,
|
||||
const QByteArray& seed,
|
||||
quint32 version,
|
||||
quint32 rounds,
|
||||
quint64 memory,
|
||||
quint32 parallelism,
|
||||
QByteArray& result);
|
||||
const QByteArray& seed,
|
||||
quint32 version,
|
||||
quint32 rounds,
|
||||
quint64 memory,
|
||||
quint32 parallelism,
|
||||
QByteArray& result);
|
||||
};
|
||||
|
||||
#endif // KEEPASSX_ARGON2KDF_H
|
||||
|
@ -18,8 +18,8 @@
|
||||
#ifndef KEEPASSX_KDF_H
|
||||
#define KEEPASSX_KDF_H
|
||||
|
||||
#include <QVariant>
|
||||
#include <QUuid>
|
||||
#include <QVariant>
|
||||
|
||||
#define KDF_DEFAULT_SEED_SIZE 32
|
||||
#define KDF_DEFAULT_ROUNDS 1000000ull
|
||||
|
@ -42,8 +42,7 @@ bool Kdbx3Reader::readDatabaseImpl(QIODevice* device,
|
||||
|
||||
// check if all required headers were present
|
||||
if (m_masterSeed.isEmpty() || m_encryptionIV.isEmpty() || m_streamStartBytes.isEmpty()
|
||||
|| m_protectedStreamKey.isEmpty()
|
||||
|| db->cipher().isNull()) {
|
||||
|| m_protectedStreamKey.isEmpty() || db->cipher().isNull()) {
|
||||
raiseError(tr("missing database headers"));
|
||||
return false;
|
||||
}
|
||||
|
@ -66,9 +66,10 @@ bool Kdbx3Writer::writeDatabase(QIODevice* device, Database* db)
|
||||
writeMagicNumbers(&header, KeePass2::SIGNATURE_1, KeePass2::SIGNATURE_2, KeePass2::FILE_VERSION_3_1);
|
||||
|
||||
CHECK_RETURN_FALSE(writeHeaderField<quint16>(&header, KeePass2::HeaderFieldID::CipherID, db->cipher().toRfc4122()));
|
||||
CHECK_RETURN_FALSE(writeHeaderField<quint16>(&header, KeePass2::HeaderFieldID::CompressionFlags,
|
||||
Endian::sizedIntToBytes<qint32>(db->compressionAlgorithm(),
|
||||
KeePass2::BYTEORDER)));
|
||||
CHECK_RETURN_FALSE(
|
||||
writeHeaderField<quint16>(&header,
|
||||
KeePass2::HeaderFieldID::CompressionFlags,
|
||||
Endian::sizedIntToBytes<qint32>(db->compressionAlgorithm(), KeePass2::BYTEORDER)));
|
||||
auto kdf = db->kdf();
|
||||
CHECK_RETURN_FALSE(writeHeaderField<quint16>(&header, KeePass2::HeaderFieldID::MasterSeed, masterSeed));
|
||||
CHECK_RETURN_FALSE(writeHeaderField<quint16>(&header, KeePass2::HeaderFieldID::TransformSeed, kdf->seed()));
|
||||
|
@ -50,7 +50,6 @@ bool Kdbx4Writer::writeDatabase(QIODevice* device, Database* db)
|
||||
QByteArray masterSeed = randomGen()->randomArray(32);
|
||||
QByteArray encryptionIV = randomGen()->randomArray(ivSize);
|
||||
QByteArray protectedStreamKey = randomGen()->randomArray(64);
|
||||
QByteArray startBytes;
|
||||
QByteArray endOfHeader = "\r\n\r\n";
|
||||
|
||||
if (!db->setKey(db->key(), false, true)) {
|
||||
@ -73,10 +72,12 @@ bool Kdbx4Writer::writeDatabase(QIODevice* device, Database* db)
|
||||
|
||||
writeMagicNumbers(&header, KeePass2::SIGNATURE_1, KeePass2::SIGNATURE_2, KeePass2::FILE_VERSION_4);
|
||||
|
||||
CHECK_RETURN_FALSE(writeHeaderField<quint32>(&header, KeePass2::HeaderFieldID::CipherID, db->cipher().toRfc4122()));
|
||||
CHECK_RETURN_FALSE(writeHeaderField<quint32>(&header, KeePass2::HeaderFieldID::CompressionFlags,
|
||||
Endian::sizedIntToBytes(static_cast<int>(db->compressionAlgorithm()),
|
||||
KeePass2::BYTEORDER)));
|
||||
CHECK_RETURN_FALSE(
|
||||
writeHeaderField<quint32>(&header, KeePass2::HeaderFieldID::CipherID, db->cipher().toRfc4122()));
|
||||
CHECK_RETURN_FALSE(writeHeaderField<quint32>(
|
||||
&header,
|
||||
KeePass2::HeaderFieldID::CompressionFlags,
|
||||
Endian::sizedIntToBytes(static_cast<int>(db->compressionAlgorithm()), KeePass2::BYTEORDER)));
|
||||
CHECK_RETURN_FALSE(writeHeaderField<quint32>(&header, KeePass2::HeaderFieldID::MasterSeed, masterSeed));
|
||||
CHECK_RETURN_FALSE(writeHeaderField<quint32>(&header, KeePass2::HeaderFieldID::EncryptionIV, encryptionIV));
|
||||
|
||||
|
@ -44,7 +44,7 @@ KdbxXmlReader::KdbxXmlReader(quint32 version)
|
||||
* @param version KDBX version
|
||||
* @param binaryPool binary pool
|
||||
*/
|
||||
KdbxXmlReader::KdbxXmlReader(quint32 version, QHash<QString, QByteArray> binaryPool)
|
||||
KdbxXmlReader::KdbxXmlReader(quint32 version, QHash<QString, QByteArray> binaryPool)
|
||||
: m_kdbxVersion(version)
|
||||
, m_binaryPool(std::move(binaryPool))
|
||||
{
|
||||
@ -731,7 +731,7 @@ Entry* KdbxXmlReader::parseEntry(bool history)
|
||||
}
|
||||
if (m_xml.name() == "Binary") {
|
||||
QPair<QString, QString> ref = parseEntryBinary(entry);
|
||||
if (!ref.first.isNull() && !ref.second.isNull()) {
|
||||
if (!ref.first.isEmpty() && !ref.second.isEmpty()) {
|
||||
binaryRefs.append(ref);
|
||||
}
|
||||
continue;
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include "core/Database.h"
|
||||
#include "core/Metadata.h"
|
||||
#include "core/TimeInfo.h"
|
||||
#include "core/Database.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QPair>
|
||||
@ -42,7 +41,7 @@ class KdbxXmlReader
|
||||
|
||||
public:
|
||||
explicit KdbxXmlReader(quint32 version);
|
||||
explicit KdbxXmlReader(quint32 version, QHash<QString, QByteArray> binaryPool);
|
||||
explicit KdbxXmlReader(quint32 version, QHash<QString, QByteArray> binaryPool);
|
||||
virtual ~KdbxXmlReader() = default;
|
||||
|
||||
virtual QSharedPointer<Database> readDatabase(const QString& filename);
|
||||
|
@ -356,12 +356,14 @@ void KdbxXmlWriter::writeEntry(const Entry* entry)
|
||||
for (const QString& key : attributesKeyList) {
|
||||
m_xml.writeStartElement("String");
|
||||
|
||||
// clang-format off
|
||||
bool protect =
|
||||
(((key == "Title") && m_meta->protectTitle()) || ((key == "UserName") && m_meta->protectUsername())
|
||||
|| ((key == "Password") && m_meta->protectPassword())
|
||||
|| ((key == "URL") && m_meta->protectUrl())
|
||||
|| ((key == "Notes") && m_meta->protectNotes())
|
||||
|| entry->attributes()->isProtected(key));
|
||||
// clang-format on
|
||||
|
||||
writeString("Key", key);
|
||||
|
||||
|
@ -1,19 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef KEEPASSX_KEEPASS1_H
|
||||
#define KEEPASSX_KEEPASS1_H
|
||||
@ -35,6 +35,6 @@ namespace KeePass1
|
||||
Rijndael = 2,
|
||||
Twofish = 8
|
||||
};
|
||||
}
|
||||
} // namespace KeePass1
|
||||
|
||||
#endif // KEEPASSX_KEEPASS1_H
|
||||
|
@ -23,14 +23,14 @@
|
||||
|
||||
#define UUID_LENGTH 16
|
||||
|
||||
const QUuid KeePass2::CIPHER_AES128 = QUuid("61ab05a1-9464-41c3-8d74-3a563df8dd35");
|
||||
const QUuid KeePass2::CIPHER_AES256 = QUuid("31c1f2e6-bf71-4350-be58-05216afc5aff");
|
||||
const QUuid KeePass2::CIPHER_TWOFISH = QUuid("ad68f29f-576f-4bb9-a36a-d47af965346c");
|
||||
const QUuid KeePass2::CIPHER_AES128 = QUuid("61ab05a1-9464-41c3-8d74-3a563df8dd35");
|
||||
const QUuid KeePass2::CIPHER_AES256 = QUuid("31c1f2e6-bf71-4350-be58-05216afc5aff");
|
||||
const QUuid KeePass2::CIPHER_TWOFISH = QUuid("ad68f29f-576f-4bb9-a36a-d47af965346c");
|
||||
const QUuid KeePass2::CIPHER_CHACHA20 = QUuid("d6038a2b-8b6f-4cb5-a524-339a31dbb59a");
|
||||
|
||||
const QUuid KeePass2::KDF_AES_KDBX3 = QUuid("c9d9f39a-628a-4460-bf74-0d08c18a4fea");
|
||||
const QUuid KeePass2::KDF_AES_KDBX4 = QUuid("7c02bb82-79a7-4ac0-927d-114a00648238");
|
||||
const QUuid KeePass2::KDF_ARGON2 = QUuid("ef636ddf-8c29-444b-91f7-a9a403e30a0c");
|
||||
const QUuid KeePass2::KDF_AES_KDBX3 = QUuid("c9d9f39a-628a-4460-bf74-0d08c18a4fea");
|
||||
const QUuid KeePass2::KDF_AES_KDBX4 = QUuid("7c02bb82-79a7-4ac0-927d-114a00648238");
|
||||
const QUuid KeePass2::KDF_ARGON2 = QUuid("ef636ddf-8c29-444b-91f7-a9a403e30a0c");
|
||||
|
||||
const QByteArray KeePass2::INNER_STREAM_SALSA20_IV("\xe8\x30\x09\x4b\x97\x20\x5d\x2a");
|
||||
|
||||
@ -50,14 +50,12 @@ const QString KeePass2::KDFPARAM_ARGON2_ASSOCDATA("A");
|
||||
const QList<QPair<QUuid, QString>> KeePass2::CIPHERS{
|
||||
qMakePair(KeePass2::CIPHER_AES256, QObject::tr("AES: 256-bit")),
|
||||
qMakePair(KeePass2::CIPHER_TWOFISH, QObject::tr("Twofish: 256-bit")),
|
||||
qMakePair(KeePass2::CIPHER_CHACHA20, QObject::tr("ChaCha20: 256-bit"))
|
||||
};
|
||||
qMakePair(KeePass2::CIPHER_CHACHA20, QObject::tr("ChaCha20: 256-bit"))};
|
||||
|
||||
const QList<QPair<QUuid, QString>> KeePass2::KDFS{
|
||||
qMakePair(KeePass2::KDF_ARGON2, QObject::tr("Argon2 (KDBX 4 – recommended)")),
|
||||
qMakePair(KeePass2::KDF_AES_KDBX4, QObject::tr("AES-KDF (KDBX 4)")),
|
||||
qMakePair(KeePass2::KDF_AES_KDBX3, QObject::tr("AES-KDF (KDBX 3.1)"))
|
||||
};
|
||||
qMakePair(KeePass2::KDF_AES_KDBX3, QObject::tr("AES-KDF (KDBX 3.1)"))};
|
||||
|
||||
QByteArray KeePass2::hmacKey(const QByteArray& masterSeed, const QByteArray& transformedMasterKey)
|
||||
{
|
||||
|
@ -21,9 +21,9 @@
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
#include <QSharedPointer>
|
||||
#include <QUuid>
|
||||
#include <QVariantMap>
|
||||
#include <QtGlobal>
|
||||
#include <QUuid>
|
||||
|
||||
#include "crypto/SymmetricCipher.h"
|
||||
#include "crypto/kdf/Kdf.h"
|
||||
@ -46,14 +46,14 @@ namespace KeePass2
|
||||
|
||||
const QSysInfo::Endian BYTEORDER = QSysInfo::LittleEndian;
|
||||
|
||||
extern const QUuid CIPHER_AES128;
|
||||
extern const QUuid CIPHER_AES256;
|
||||
extern const QUuid CIPHER_TWOFISH;
|
||||
extern const QUuid CIPHER_CHACHA20;
|
||||
extern const QUuid CIPHER_AES128;
|
||||
extern const QUuid CIPHER_AES256;
|
||||
extern const QUuid CIPHER_TWOFISH;
|
||||
extern const QUuid CIPHER_CHACHA20;
|
||||
|
||||
extern const QUuid KDF_AES_KDBX3;
|
||||
extern const QUuid KDF_AES_KDBX4;
|
||||
extern const QUuid KDF_ARGON2;
|
||||
extern const QUuid KDF_AES_KDBX3;
|
||||
extern const QUuid KDF_AES_KDBX4;
|
||||
extern const QUuid KDF_ARGON2;
|
||||
|
||||
extern const QByteArray INNER_STREAM_SALSA20_IV;
|
||||
|
||||
@ -68,8 +68,8 @@ extern const QUuid KDF_ARGON2;
|
||||
extern const QString KDFPARAM_ARGON2_SECRET;
|
||||
extern const QString KDFPARAM_ARGON2_ASSOCDATA;
|
||||
|
||||
extern const QList<QPair<QUuid, QString>> CIPHERS;
|
||||
extern const QList<QPair<QUuid, QString>> KDFS;
|
||||
extern const QList<QPair<QUuid, QString>> CIPHERS;
|
||||
extern const QList<QPair<QUuid, QString>> KDFS;
|
||||
|
||||
enum class HeaderFieldID
|
||||
{
|
||||
@ -126,11 +126,11 @@ extern const QList<QPair<QUuid, QString>> KDFS;
|
||||
ByteArray = 0x42
|
||||
};
|
||||
|
||||
QByteArray hmacKey(const QByteArray& masterSeed, const QByteArray& transformedMasterKey);
|
||||
QSharedPointer<Kdf> kdfFromParameters(const QVariantMap& p);
|
||||
QVariantMap kdfToParameters(const QSharedPointer<Kdf>& kdf);
|
||||
QSharedPointer<Kdf> uuidToKdf(const QUuid& uuid);
|
||||
ProtectedStreamAlgo idToProtectedStreamAlgo(quint32 id);
|
||||
QByteArray hmacKey(const QByteArray& masterSeed, const QByteArray& transformedMasterKey);
|
||||
QSharedPointer<Kdf> kdfFromParameters(const QVariantMap& p);
|
||||
QVariantMap kdfToParameters(const QSharedPointer<Kdf>& kdf);
|
||||
QSharedPointer<Kdf> uuidToKdf(const QUuid& uuid);
|
||||
ProtectedStreamAlgo idToProtectedStreamAlgo(quint32 id);
|
||||
|
||||
} // namespace KeePass2
|
||||
|
||||
|
@ -64,10 +64,9 @@ AboutDialog::AboutDialog(QWidget* parent)
|
||||
debugInfo.append(tr("Distribution: %1").arg(KEEPASSXC_DIST_TYPE).append("\n"));
|
||||
#endif
|
||||
|
||||
debugInfo.append("\n").append(QString("%1\n- Qt %2\n- %3\n\n")
|
||||
.arg(tr("Libraries:"),
|
||||
QString::fromLocal8Bit(qVersion()),
|
||||
Crypto::backendVersion()));
|
||||
debugInfo.append("\n").append(
|
||||
QString("%1\n- Qt %2\n- %3\n\n")
|
||||
.arg(tr("Libraries:"), QString::fromLocal8Bit(qVersion()), Crypto::backendVersion()));
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
|
||||
debugInfo.append(tr("Operating system: %1\nCPU architecture: %2\nKernel: %3 %4")
|
||||
|
@ -25,7 +25,7 @@ namespace Ui
|
||||
{
|
||||
class ApplicationSettingsWidgetGeneral;
|
||||
class ApplicationSettingsWidgetSecurity;
|
||||
}
|
||||
} // namespace Ui
|
||||
|
||||
class ISettingsPage
|
||||
{
|
||||
|
@ -38,8 +38,9 @@ CategoryListWidget::CategoryListWidget(QWidget* parent)
|
||||
connect(m_ui->scrollUp, SIGNAL(clicked()), SLOT(scrollCategoriesUp()));
|
||||
connect(m_ui->scrollDown, SIGNAL(clicked()), SLOT(scrollCategoriesDown()));
|
||||
connect(m_ui->categoryList->verticalScrollBar(), SIGNAL(valueChanged(int)), SLOT(updateCategoryScrollButtons()));
|
||||
connect(
|
||||
m_ui->categoryList->verticalScrollBar(), SIGNAL(rangeChanged(int,int)), SLOT(updateCategoryScrollButtons()));
|
||||
// clang-format off
|
||||
connect(m_ui->categoryList->verticalScrollBar(), SIGNAL(rangeChanged(int,int)), SLOT(updateCategoryScrollButtons()));
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
CategoryListWidget::~CategoryListWidget()
|
||||
|
@ -105,9 +105,11 @@ void DatabaseOpenWidget::showEvent(QShowEvent* event)
|
||||
#ifdef WITH_XC_YUBIKEY
|
||||
// showEvent() may be called twice, so make sure we are only polling once
|
||||
if (!m_yubiKeyBeingPolled) {
|
||||
// clang-format off
|
||||
connect(YubiKey::instance(), SIGNAL(detected(int,bool)), SLOT(yubikeyDetected(int,bool)), Qt::QueuedConnection);
|
||||
connect(YubiKey::instance(), SIGNAL(detectComplete()), SLOT(yubikeyDetectComplete()), Qt::QueuedConnection);
|
||||
connect(YubiKey::instance(), SIGNAL(notFound()), SLOT(noYubikeyFound()), Qt::QueuedConnection);
|
||||
// clang-format on
|
||||
|
||||
pollYubikey();
|
||||
m_yubiKeyBeingPolled = true;
|
||||
@ -172,7 +174,7 @@ QSharedPointer<Database> DatabaseOpenWidget::database()
|
||||
|
||||
void DatabaseOpenWidget::enterKey(const QString& pw, const QString& keyFile)
|
||||
{
|
||||
if (!pw.isNull()) {
|
||||
if (!pw.isEmpty()) {
|
||||
m_ui->editPassword->setText(pw);
|
||||
}
|
||||
if (!keyFile.isEmpty()) {
|
||||
@ -190,7 +192,7 @@ void DatabaseOpenWidget::openDatabase()
|
||||
}
|
||||
|
||||
if (!m_ui->editPassword->isPasswordVisible()) {
|
||||
m_ui->editPassword->setShowPassword(false);
|
||||
m_ui->editPassword->setShowPassword(false);
|
||||
}
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
|
@ -94,10 +94,12 @@ QSharedPointer<Database> DatabaseTabWidget::execNewDatabaseWizard()
|
||||
Q_ASSERT(db->key());
|
||||
Q_ASSERT(db->kdf());
|
||||
if (!db->key() || !db->kdf()) {
|
||||
MessageBox::critical(this, tr("Database creation error"),
|
||||
tr("The created database has no key or KDF, refusing to save it.\n"
|
||||
"This is definitely a bug, please report it to the developers."),
|
||||
QMessageBox::Ok, QMessageBox::Ok);
|
||||
MessageBox::critical(this,
|
||||
tr("Database creation error"),
|
||||
tr("The created database has no key or KDF, refusing to save it.\n"
|
||||
"This is definitely a bug, please report it to the developers."),
|
||||
QMessageBox::Ok,
|
||||
QMessageBox::Ok);
|
||||
return {};
|
||||
}
|
||||
|
||||
@ -216,7 +218,7 @@ void DatabaseTabWidget::mergeDatabase()
|
||||
auto dbWidget = currentDatabaseWidget();
|
||||
if (dbWidget && !dbWidget->isLocked()) {
|
||||
QString filter = QString("%1 (*.kdbx);;%2 (*)").arg(tr("KeePass 2 Database"), tr("All files"));
|
||||
const QString fileName = fileDialog()->getOpenFileName(this, tr("Merge database"), "", filter);
|
||||
const QString fileName = fileDialog()->getOpenFileName(this, tr("Merge database"), QString(), filter);
|
||||
if (!fileName.isEmpty()) {
|
||||
mergeDatabase(fileName);
|
||||
}
|
||||
|
@ -50,8 +50,8 @@
|
||||
#include "gui/EntryPreviewWidget.h"
|
||||
#include "gui/KeePass1OpenWidget.h"
|
||||
#include "gui/MessageBox.h"
|
||||
#include "gui/TotpSetupDialog.h"
|
||||
#include "gui/TotpDialog.h"
|
||||
#include "gui/TotpSetupDialog.h"
|
||||
#include "gui/TotpExportSettingsDialog.h"
|
||||
#include "gui/entry/EditEntryWidget.h"
|
||||
#include "gui/entry/EntryView.h"
|
||||
@ -155,6 +155,7 @@ DatabaseWidget::DatabaseWidget(QSharedPointer<Database> db, QWidget* parent)
|
||||
addChildWidget(m_csvImportWizard);
|
||||
addChildWidget(m_keepass1OpenWidget);
|
||||
|
||||
// clang-format off
|
||||
connect(m_mainSplitter, SIGNAL(splitterMoved(int,int)), SIGNAL(mainSplitterSizesChanged()));
|
||||
connect(m_previewSplitter, SIGNAL(splitterMoved(int,int)), SIGNAL(previewSplitterSizesChanged()));
|
||||
connect(this, SIGNAL(currentModeChanged(DatabaseWidget::Mode)), m_previewView, SLOT(setDatabaseMode(DatabaseWidget::Mode)));
|
||||
@ -177,7 +178,8 @@ DatabaseWidget::DatabaseWidget(QSharedPointer<Database> db, QWidget* parent)
|
||||
connect(&m_fileWatchTimer, SIGNAL(timeout()), this, SLOT(reloadDatabaseFile()));
|
||||
connect(&m_fileWatchUnblockTimer, SIGNAL(timeout()), this, SLOT(unblockAutoReload()));
|
||||
connect(this, SIGNAL(currentChanged(int)), this, SLOT(emitCurrentModeChanged()));
|
||||
|
||||
// clang-format on
|
||||
|
||||
connectDatabaseSignals();
|
||||
|
||||
m_fileWatchTimer.setSingleShot(true);
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "EditWidget.h"
|
||||
#include "ui_EditWidget.h"
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QScrollArea>
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
#ifdef WITH_XC_NETWORKING
|
||||
#include <QtNetwork>
|
||||
#include <QNetworkAccessManager>
|
||||
#endif
|
||||
|
||||
IconStruct::IconStruct()
|
||||
@ -44,6 +45,7 @@ EditWidgetIcons::EditWidgetIcons(QWidget* parent)
|
||||
, m_ui(new Ui::EditWidgetIcons())
|
||||
, m_db(nullptr)
|
||||
#ifdef WITH_XC_NETWORKING
|
||||
, m_netMgr(new QNetworkAccessManager(this))
|
||||
, m_reply(nullptr)
|
||||
#endif
|
||||
, m_defaultIconModel(new DefaultIconModel(this))
|
||||
@ -54,6 +56,7 @@ EditWidgetIcons::EditWidgetIcons(QWidget* parent)
|
||||
m_ui->defaultIconsView->setModel(m_defaultIconModel);
|
||||
m_ui->customIconsView->setModel(m_customIconModel);
|
||||
|
||||
// clang-format off
|
||||
connect(m_ui->defaultIconsView, SIGNAL(clicked(QModelIndex)), this, SLOT(updateRadioButtonDefaultIcons()));
|
||||
connect(m_ui->customIconsView, SIGNAL(clicked(QModelIndex)), this, SLOT(updateRadioButtonCustomIcons()));
|
||||
connect(m_ui->defaultIconsRadio, SIGNAL(toggled(bool)), this, SLOT(updateWidgetsDefaultIcons(bool)));
|
||||
@ -64,14 +67,11 @@ EditWidgetIcons::EditWidgetIcons(QWidget* parent)
|
||||
|
||||
connect(m_ui->defaultIconsRadio, SIGNAL(toggled(bool)), this, SIGNAL(widgetUpdated()));
|
||||
connect(m_ui->defaultIconsRadio, SIGNAL(toggled(bool)), this, SIGNAL(widgetUpdated()));
|
||||
connect(m_ui->defaultIconsView->selectionModel(),
|
||||
SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
|
||||
this,
|
||||
SIGNAL(widgetUpdated()));
|
||||
connect(m_ui->customIconsView->selectionModel(),
|
||||
SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
|
||||
this,
|
||||
SIGNAL(widgetUpdated()));
|
||||
connect(m_ui->defaultIconsView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
|
||||
this, SIGNAL(widgetUpdated()));
|
||||
connect(m_ui->customIconsView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
|
||||
this, SIGNAL(widgetUpdated()));
|
||||
// clang-format on
|
||||
|
||||
m_ui->faviconButton->setVisible(false);
|
||||
m_ui->addButton->setEnabled(true);
|
||||
@ -156,7 +156,8 @@ void EditWidgetIcons::setUrl(const QString& url)
|
||||
}
|
||||
|
||||
#ifdef WITH_XC_NETWORKING
|
||||
namespace {
|
||||
namespace
|
||||
{
|
||||
// Try to get the 2nd level domain of the host part of a QUrl. For example,
|
||||
// "foo.bar.example.com" would become "example.com", and "foo.bar.example.co.uk"
|
||||
// would become "example.co.uk".
|
||||
@ -173,17 +174,17 @@ namespace {
|
||||
{
|
||||
QUrl url;
|
||||
if (var.canConvert<QUrl>())
|
||||
url = var.value<QUrl>();
|
||||
url = var.toUrl();
|
||||
return url;
|
||||
}
|
||||
|
||||
QUrl getRedirectTarget(QNetworkReply *reply)
|
||||
QUrl getRedirectTarget(QNetworkReply* reply)
|
||||
{
|
||||
QVariant var = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
|
||||
QUrl url = convertVariantToUrl(var);
|
||||
return url;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
#endif
|
||||
|
||||
void EditWidgetIcons::downloadFavicon()
|
||||
@ -264,9 +265,10 @@ void EditWidgetIcons::fetchFinished()
|
||||
return;
|
||||
} else {
|
||||
if (!fallbackEnabled) {
|
||||
emit messageEditEntry(tr("Unable to fetch favicon.") + "\n" +
|
||||
tr("Hint: You can enable DuckDuckGo as a fallback under Tools>Settings>Security"),
|
||||
MessageWidget::Error);
|
||||
emit messageEditEntry(
|
||||
tr("Unable to fetch favicon.") + "\n"
|
||||
+ tr("Hint: You can enable DuckDuckGo as a fallback under Tools>Settings>Security"),
|
||||
MessageWidget::Error);
|
||||
} else {
|
||||
emit messageEditEntry(tr("Unable to fetch favicon."), MessageWidget::Error);
|
||||
}
|
||||
@ -294,7 +296,7 @@ void EditWidgetIcons::startFetchFavicon(const QUrl& url)
|
||||
|
||||
QNetworkRequest request(url);
|
||||
|
||||
m_reply = m_netMgr.get(request);
|
||||
m_reply = m_netMgr->get(request);
|
||||
connect(m_reply, &QNetworkReply::finished, this, &EditWidgetIcons::fetchFinished);
|
||||
connect(m_reply, &QIODevice::readyRead, this, &EditWidgetIcons::fetchReadyRead);
|
||||
#else
|
||||
@ -339,8 +341,9 @@ void EditWidgetIcons::addCustomIconFromFile()
|
||||
if (!errornames.empty()) {
|
||||
// Show the first 8 icons that failed to load
|
||||
errornames = errornames.mid(0, 8);
|
||||
emit messageEditEntry(msg + "\n" + tr("The following icon(s) failed:", "", errornames.size()) +
|
||||
"\n" + errornames.join("\n"), MessageWidget::Error);
|
||||
emit messageEditEntry(msg + "\n" + tr("The following icon(s) failed:", "", errornames.size()) + "\n"
|
||||
+ errornames.join("\n"),
|
||||
MessageWidget::Error);
|
||||
} else if (numloaded > 0) {
|
||||
emit messageEditEntry(msg, MessageWidget::Positive);
|
||||
} else {
|
||||
|
@ -21,9 +21,8 @@
|
||||
|
||||
#include <QSet>
|
||||
#include <QUrl>
|
||||
#include <QWidget>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QUuid>
|
||||
#include <QWidget>
|
||||
|
||||
#include "config-keepassx.h"
|
||||
#include "core/Global.h"
|
||||
@ -33,6 +32,7 @@ class Database;
|
||||
class DefaultIconModel;
|
||||
class CustomIconModel;
|
||||
#ifdef WITH_XC_NETWORKING
|
||||
class QNetworkAccessManager;
|
||||
class QNetworkReply;
|
||||
#endif
|
||||
|
||||
@ -95,8 +95,8 @@ private:
|
||||
QUrl m_fetchUrl;
|
||||
QList<QUrl> m_urlsToTry;
|
||||
QByteArray m_bytesReceived;
|
||||
QNetworkAccessManager m_netMgr;
|
||||
QNetworkReply *m_reply;
|
||||
QNetworkAccessManager* m_netMgr;
|
||||
QNetworkReply* m_reply;
|
||||
int m_redirects;
|
||||
#endif
|
||||
DefaultIconModel* const m_defaultIconModel;
|
||||
|
@ -16,11 +16,11 @@
|
||||
*/
|
||||
|
||||
#include "EditWidgetProperties.h"
|
||||
|
||||
#include <QUuid>
|
||||
#include "ui_EditWidgetProperties.h"
|
||||
|
||||
#include "MessageBox.h"
|
||||
#include "ui_EditWidgetProperties.h"
|
||||
|
||||
#include <QUuid>
|
||||
|
||||
EditWidgetProperties::EditWidgetProperties(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
@ -32,9 +32,11 @@ EditWidgetProperties::EditWidgetProperties(QWidget* parent)
|
||||
m_ui->removeCustomDataButton->setEnabled(false);
|
||||
m_ui->customDataTable->setModel(m_customDataModel);
|
||||
|
||||
// clang-format off
|
||||
connect(m_ui->customDataTable->selectionModel(),
|
||||
SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
|
||||
SLOT(toggleRemoveButton(QItemSelection)));
|
||||
// clang-format on
|
||||
connect(m_ui->removeCustomDataButton, SIGNAL(clicked()), SLOT(removeSelectedPluginData()));
|
||||
}
|
||||
|
||||
@ -66,12 +68,13 @@ const CustomData* EditWidgetProperties::customData() const
|
||||
|
||||
void EditWidgetProperties::removeSelectedPluginData()
|
||||
{
|
||||
if (QMessageBox::Yes != MessageBox::question(this,
|
||||
tr("Delete plugin data?"),
|
||||
tr("Do you really want to delete the selected plugin data?\n"
|
||||
"This may cause the affected plugins to malfunction."),
|
||||
QMessageBox::Yes | QMessageBox::Cancel,
|
||||
QMessageBox::Cancel)) {
|
||||
if (QMessageBox::Yes
|
||||
!= MessageBox::question(this,
|
||||
tr("Delete plugin data?"),
|
||||
tr("Do you really want to delete the selected plugin data?\n"
|
||||
"This may cause the affected plugins to malfunction."),
|
||||
QMessageBox::Yes | QMessageBox::Cancel,
|
||||
QMessageBox::Cancel)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -97,8 +100,8 @@ void EditWidgetProperties::updateModel()
|
||||
m_customDataModel->setHorizontalHeaderLabels({tr("Key"), tr("Value")});
|
||||
|
||||
for (const QString& key : m_customData->keys()) {
|
||||
m_customDataModel->appendRow(QList<QStandardItem*>() << new QStandardItem(key)
|
||||
<< new QStandardItem(m_customData->value(key)));
|
||||
m_customDataModel->appendRow(QList<QStandardItem*>()
|
||||
<< new QStandardItem(key) << new QStandardItem(m_customData->value(key)));
|
||||
}
|
||||
|
||||
m_ui->removeCustomDataButton->setEnabled(false);
|
||||
|
@ -220,7 +220,7 @@ void EntryPreviewWidget::updateEntryAttributesTab()
|
||||
m_ui->entryAttributesEdit->clear();
|
||||
const EntryAttributes* attributes = m_currentEntry->attributes();
|
||||
const QStringList customAttributes = attributes->customKeys();
|
||||
const bool haveAttributes = customAttributes.size() > 0;
|
||||
const bool haveAttributes = !customAttributes.isEmpty();
|
||||
setTabEnabled(m_ui->entryTabWidget, m_ui->entryAttributesTab, haveAttributes);
|
||||
if (haveAttributes) {
|
||||
QString attributesText;
|
||||
|
@ -287,7 +287,6 @@ void KMessageWidget::setMessageType(KMessageWidget::MessageType type)
|
||||
|
||||
// Tint close icon
|
||||
auto closeButtonPixmap = d->closeButtonPixmap;
|
||||
QPixmap mask(closeButtonPixmap);
|
||||
QPainter painter;
|
||||
painter.begin(&closeButtonPixmap);
|
||||
painter.setRenderHints(QPainter::HighQualityAntialiasing);
|
||||
|
@ -16,6 +16,7 @@
|
||||
*/
|
||||
|
||||
#include "KeePass1OpenWidget.h"
|
||||
#include "ui_DatabaseOpenWidget.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
@ -24,7 +25,6 @@
|
||||
#include "core/Metadata.h"
|
||||
#include "format/KeePass1Reader.h"
|
||||
#include "gui/MessageBox.h"
|
||||
#include "ui_DatabaseOpenWidget.h"
|
||||
|
||||
KeePass1OpenWidget::KeePass1OpenWidget(QWidget* parent)
|
||||
: DatabaseOpenWidget(parent)
|
||||
|
@ -20,10 +20,10 @@
|
||||
#include "ui_MainWindow.h"
|
||||
|
||||
#include <QCloseEvent>
|
||||
#include <QDesktopServices>
|
||||
#include <QMimeData>
|
||||
#include <QShortcut>
|
||||
#include <QTimer>
|
||||
#include <QDesktopServices>
|
||||
|
||||
#include "config-keepassx.h"
|
||||
|
||||
@ -56,8 +56,8 @@
|
||||
#include <QtDBus/QtDBus>
|
||||
#endif
|
||||
|
||||
#include "gui/PasswordGeneratorWidget.h"
|
||||
#include "gui/ApplicationSettingsWidget.h"
|
||||
#include "gui/PasswordGeneratorWidget.h"
|
||||
|
||||
#include "touchid/TouchID.h"
|
||||
|
||||
@ -67,7 +67,8 @@ class BrowserPlugin : public ISettingsPage
|
||||
public:
|
||||
BrowserPlugin(DatabaseTabWidget* tabWidget)
|
||||
{
|
||||
m_nativeMessagingHost = QSharedPointer<NativeMessagingHost>(new NativeMessagingHost(tabWidget, browserSettings()->isEnabled()));
|
||||
m_nativeMessagingHost =
|
||||
QSharedPointer<NativeMessagingHost>(new NativeMessagingHost(tabWidget, browserSettings()->isEnabled()));
|
||||
}
|
||||
|
||||
~BrowserPlugin()
|
||||
@ -105,8 +106,8 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
QSharedPointer<NativeMessagingHost> m_nativeMessagingHost;
|
||||
private:
|
||||
QSharedPointer<NativeMessagingHost> m_nativeMessagingHost;
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -346,11 +347,13 @@ MainWindow::MainWindow()
|
||||
#ifdef Q_OS_MACOS
|
||||
setUnifiedTitleAndToolBarOnMac(true);
|
||||
#endif
|
||||
|
||||
// clang-format off
|
||||
connect(m_ui->tabWidget,
|
||||
SIGNAL(messageGlobal(QString,MessageWidget::MessageType)),
|
||||
this,
|
||||
SLOT(displayGlobalMessage(QString,MessageWidget::MessageType)));
|
||||
// clang-format on
|
||||
|
||||
connect(m_ui->tabWidget, SIGNAL(messageDismissGlobal()), this, SLOT(hideGlobalMessage()));
|
||||
|
||||
m_screenLockListener = new ScreenLockListener(this);
|
||||
@ -368,13 +371,15 @@ MainWindow::MainWindow()
|
||||
tr("WARNING: You are using an unstable build of KeePassXC!\n"
|
||||
"There is a high risk of corruption, maintain a backup of your databases.\n"
|
||||
"This version is not meant for production use."),
|
||||
MessageWidget::Warning, -1);
|
||||
MessageWidget::Warning,
|
||||
-1);
|
||||
#elif (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0) && QT_VERSION < QT_VERSION_CHECK(5, 6, 0))
|
||||
if (!config()->get("QtErrorMessageShown", false).toBool()) {
|
||||
m_ui->globalMessageWidget->showMessage(
|
||||
tr("WARNING: Your Qt version may cause KeePassXC to crash with an On-Screen Keyboard!\n"
|
||||
"We recommend you use the AppImage available on our downloads page."),
|
||||
MessageWidget::Warning, -1);
|
||||
MessageWidget::Warning,
|
||||
-1);
|
||||
config()->set("QtErrorMessageShown", true);
|
||||
}
|
||||
#endif
|
||||
@ -671,10 +676,10 @@ void MainWindow::switchToSettings(bool enabled)
|
||||
void MainWindow::switchToPasswordGen(bool enabled)
|
||||
{
|
||||
if (enabled) {
|
||||
m_ui->passwordGeneratorWidget->loadSettings();
|
||||
m_ui->passwordGeneratorWidget->regeneratePassword();
|
||||
m_ui->passwordGeneratorWidget->setStandaloneMode(true);
|
||||
m_ui->stackedWidget->setCurrentIndex(PasswordGeneratorScreen);
|
||||
m_ui->passwordGeneratorWidget->loadSettings();
|
||||
m_ui->passwordGeneratorWidget->regeneratePassword();
|
||||
m_ui->passwordGeneratorWidget->setStandaloneMode(true);
|
||||
m_ui->stackedWidget->setCurrentIndex(PasswordGeneratorScreen);
|
||||
} else {
|
||||
m_ui->passwordGeneratorWidget->saveSettings();
|
||||
switchToDatabases();
|
||||
|
@ -71,8 +71,9 @@ void PasswordEdit::setShowPassword(bool show)
|
||||
emit showPasswordChanged(show);
|
||||
}
|
||||
|
||||
bool PasswordEdit::isPasswordVisible() const {
|
||||
return isEnabled();
|
||||
bool PasswordEdit::isPasswordVisible() const
|
||||
{
|
||||
return isEnabled();
|
||||
}
|
||||
|
||||
bool PasswordEdit::passwordsEqual() const
|
||||
|
@ -338,10 +338,8 @@ void PasswordGeneratorWidget::selectSimpleMode()
|
||||
m_ui->checkBoxLower->setChecked(m_ui->checkBoxLowerAdv->isChecked());
|
||||
m_ui->checkBoxNumbers->setChecked(m_ui->checkBoxNumbersAdv->isChecked());
|
||||
m_ui->checkBoxSpecialChars->setChecked(m_ui->checkBoxBraces->isChecked() | m_ui->checkBoxPunctuation->isChecked()
|
||||
| m_ui->checkBoxQuotes->isChecked()
|
||||
| m_ui->checkBoxMath->isChecked()
|
||||
| m_ui->checkBoxDashes->isChecked()
|
||||
| m_ui->checkBoxLogograms->isChecked());
|
||||
| m_ui->checkBoxQuotes->isChecked() | m_ui->checkBoxMath->isChecked()
|
||||
| m_ui->checkBoxDashes->isChecked() | m_ui->checkBoxLogograms->isChecked());
|
||||
m_ui->checkBoxExtASCII->setChecked(m_ui->checkBoxExtASCIIAdv->isChecked());
|
||||
m_ui->simpleBar->show();
|
||||
}
|
||||
|
@ -17,9 +17,10 @@
|
||||
*/
|
||||
|
||||
#include "TotpSetupDialog.h"
|
||||
#include "totp/totp.h"
|
||||
#include "ui_TotpSetupDialog.h"
|
||||
|
||||
#include "totp/totp.h"
|
||||
|
||||
TotpSetupDialog::TotpSetupDialog(QWidget* parent, Entry* entry)
|
||||
: QDialog(parent)
|
||||
, m_ui(new Ui::TotpSetupDialog())
|
||||
|
@ -40,7 +40,7 @@ CsvImportWidget::CsvImportWidget(QWidget* parent)
|
||||
, m_columnHeader(QStringList() << QObject::tr("Group") << QObject::tr("Title") << QObject::tr("Username")
|
||||
<< QObject::tr("Password") << QObject::tr("URL") << QObject::tr("Notes")
|
||||
<< QObject::tr("Last Modified") << QObject::tr("Created")
|
||||
/* << QObject::tr("Future field1") */ )
|
||||
/* << QObject::tr("Future field1") */)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
@ -87,9 +87,11 @@ CsvImportWidget::CsvImportWidget(QWidget* parent)
|
||||
m_combos.append(combo);
|
||||
combo->setModel(m_comboModel);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
|
||||
connect(combo, QOverload<int>::of(&QComboBox::currentIndexChanged), [=]{ comboChanged(combo, i); });
|
||||
connect(combo, QOverload<int>::of(&QComboBox::currentIndexChanged), [=] { comboChanged(combo, i); });
|
||||
#else
|
||||
connect(combo, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), [=]{ comboChanged(combo, i); });
|
||||
connect(combo, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), [=] {
|
||||
comboChanged(combo, i);
|
||||
});
|
||||
#endif
|
||||
|
||||
// layout labels and combo fields in column-first order
|
||||
|
@ -42,7 +42,6 @@ void CsvImportWizard::load(const QString& filename, Database* database)
|
||||
m_parse->load(filename, database);
|
||||
}
|
||||
|
||||
|
||||
void CsvImportWizard::parseFinished(bool accepted)
|
||||
{
|
||||
emit importFinished(accepted);
|
||||
|
@ -18,16 +18,17 @@
|
||||
|
||||
#include "DatabaseSettingsDialog.h"
|
||||
#include "ui_DatabaseSettingsDialog.h"
|
||||
#include "DatabaseSettingsWidgetGeneral.h"
|
||||
|
||||
#include "DatabaseSettingsWidgetEncryption.h"
|
||||
#include "DatabaseSettingsWidgetGeneral.h"
|
||||
#include "DatabaseSettingsWidgetMasterKey.h"
|
||||
#ifdef WITH_XC_BROWSER
|
||||
#include "DatabaseSettingsWidgetBrowser.h"
|
||||
#endif
|
||||
|
||||
#include "core/Config.h"
|
||||
#include "core/FilePath.h"
|
||||
#include "core/Database.h"
|
||||
#include "core/FilePath.h"
|
||||
#include "touchid/TouchID.h"
|
||||
|
||||
DatabaseSettingsDialog::DatabaseSettingsDialog(QWidget* parent)
|
||||
@ -57,12 +58,13 @@ DatabaseSettingsDialog::DatabaseSettingsDialog(QWidget* parent)
|
||||
m_ui->stackedWidget->setCurrentIndex(0);
|
||||
m_securityTabWidget->setCurrentIndex(0);
|
||||
|
||||
connect(m_securityTabWidget, SIGNAL(currentChanged(int)), SLOT(pageChanged()));
|
||||
connect(m_securityTabWidget, SIGNAL(currentChanged(int)), SLOT(pageChanged()));
|
||||
connect(m_ui->categoryList, SIGNAL(categoryChanged(int)), m_ui->stackedWidget, SLOT(setCurrentIndex(int)));
|
||||
connect(m_ui->advancedSettingsToggle, SIGNAL(toggled(bool)), SLOT(toggleAdvancedMode(bool)));
|
||||
|
||||
#ifdef WITH_XC_BROWSER
|
||||
m_ui->categoryList->addCategory(tr("Browser Integration"), FilePath::instance()->icon("apps", "internet-web-browser"));
|
||||
m_ui->categoryList->addCategory(tr("Browser Integration"),
|
||||
FilePath::instance()->icon("apps", "internet-web-browser"));
|
||||
m_ui->stackedWidget->addWidget(m_browserWidget);
|
||||
#endif
|
||||
|
||||
|
@ -18,8 +18,8 @@
|
||||
#ifndef KEEPASSX_DATABASESETTINGSWIDGET_H
|
||||
#define KEEPASSX_DATABASESETTINGSWIDGET_H
|
||||
|
||||
#include "gui/DialogyWidget.h"
|
||||
#include "config-keepassx.h"
|
||||
#include "gui/DialogyWidget.h"
|
||||
|
||||
#include <QPointer>
|
||||
#include <QScopedPointer>
|
||||
|
@ -18,8 +18,8 @@
|
||||
#include "DatabaseSettingsWidget.h"
|
||||
#include "core/Database.h"
|
||||
|
||||
#include <QWidget>
|
||||
#include <QTimer>
|
||||
#include <QWidget>
|
||||
|
||||
DatabaseSettingsWidget::DatabaseSettingsWidget(QWidget* parent)
|
||||
: SettingsWidget(parent)
|
||||
|
@ -48,4 +48,4 @@ protected:
|
||||
QSharedPointer<Database> m_db;
|
||||
};
|
||||
|
||||
#endif //KEEPASSXC_DATABASESETTINGSWIDGET_H
|
||||
#endif // KEEPASSXC_DATABASESETTINGSWIDGET_H
|
||||
|
@ -17,18 +17,21 @@
|
||||
*/
|
||||
|
||||
#include "DatabaseSettingsWidgetBrowser.h"
|
||||
#include "ui_DatabaseSettingsWidgetBrowser.h"
|
||||
|
||||
#include <QProgressDialog>
|
||||
|
||||
#include "browser/BrowserSettings.h"
|
||||
#include "core/Clock.h"
|
||||
#include "core/Database.h"
|
||||
#include "core/Entry.h"
|
||||
#include "core/Group.h"
|
||||
#include "core/Metadata.h"
|
||||
#include "gui/MessageBox.h"
|
||||
#include "browser/BrowserSettings.h"
|
||||
#include "ui_DatabaseSettingsWidgetBrowser.h"
|
||||
|
||||
DatabaseSettingsWidgetBrowser::DatabaseSettingsWidgetBrowser(QWidget* parent)
|
||||
: DatabaseSettingsWidget(parent), m_ui(new Ui::DatabaseSettingsWidgetBrowser())
|
||||
: DatabaseSettingsWidget(parent)
|
||||
, m_ui(new Ui::DatabaseSettingsWidgetBrowser())
|
||||
, m_customData(new CustomData(this))
|
||||
, m_customDataModel(new QStandardItemModel(this))
|
||||
, m_browserService(nullptr)
|
||||
@ -38,8 +41,13 @@ DatabaseSettingsWidgetBrowser::DatabaseSettingsWidgetBrowser(QWidget* parent)
|
||||
m_ui->customDataTable->setModel(m_customDataModel);
|
||||
|
||||
settingsWarning();
|
||||
connect(m_ui->customDataTable->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
|
||||
|
||||
// clang-format off
|
||||
connect(m_ui->customDataTable->selectionModel(),
|
||||
SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
|
||||
SLOT(toggleRemoveButton(QItemSelection)));
|
||||
// clang-format on
|
||||
|
||||
connect(m_ui->removeCustomDataButton, SIGNAL(clicked()), SLOT(removeSelectedKey()));
|
||||
connect(m_ui->convertToCustomData, SIGNAL(clicked()), this, SLOT(convertAttributesToCustomData()));
|
||||
connect(m_ui->convertToCustomData, SIGNAL(clicked()), this, SLOT(updateSharedKeyList()));
|
||||
@ -83,11 +91,13 @@ bool DatabaseSettingsWidgetBrowser::save()
|
||||
|
||||
void DatabaseSettingsWidgetBrowser::removeSelectedKey()
|
||||
{
|
||||
if (QMessageBox::Yes != MessageBox::question(this,
|
||||
tr("Delete the selected key?"),
|
||||
tr("Do you really want to delete the selected key?\n"
|
||||
"This may prevent connection to the browser plugin."),
|
||||
QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel)) {
|
||||
if (QMessageBox::Yes
|
||||
!= MessageBox::question(this,
|
||||
tr("Delete the selected key?"),
|
||||
tr("Do you really want to delete the selected key?\n"
|
||||
"This may prevent connection to the browser plugin."),
|
||||
QMessageBox::Yes | QMessageBox::Cancel,
|
||||
QMessageBox::Cancel)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -116,9 +126,8 @@ void DatabaseSettingsWidgetBrowser::updateModel()
|
||||
if (key.startsWith(BrowserService::ASSOCIATE_KEY_PREFIX)) {
|
||||
QString strippedKey = key;
|
||||
strippedKey.remove(BrowserService::ASSOCIATE_KEY_PREFIX);
|
||||
m_customDataModel->appendRow(QList<QStandardItem*>()
|
||||
<< new QStandardItem(strippedKey)
|
||||
<< new QStandardItem(customData()->value(key)));
|
||||
m_customDataModel->appendRow(QList<QStandardItem*>() << new QStandardItem(strippedKey)
|
||||
<< new QStandardItem(customData()->value(key)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,7 +141,8 @@ void DatabaseSettingsWidgetBrowser::settingsWarning()
|
||||
m_ui->removeSharedEncryptionKeys->setEnabled(false);
|
||||
m_ui->removeStoredPermissions->setEnabled(false);
|
||||
m_ui->customDataTable->setEnabled(false);
|
||||
m_ui->warningWidget->showMessage(tr("Enable Browser Integration to access these settings."), MessageWidget::Warning);
|
||||
m_ui->warningWidget->showMessage(tr("Enable Browser Integration to access these settings."),
|
||||
MessageWidget::Warning);
|
||||
m_ui->warningWidget->setCloseButtonVisible(false);
|
||||
m_ui->warningWidget->setAutoHideTimeout(-1);
|
||||
} else {
|
||||
@ -146,11 +156,13 @@ void DatabaseSettingsWidgetBrowser::settingsWarning()
|
||||
|
||||
void DatabaseSettingsWidgetBrowser::removeSharedEncryptionKeys()
|
||||
{
|
||||
if (QMessageBox::Yes != MessageBox::question(this,
|
||||
tr("Disconnect all browsers"),
|
||||
tr("Do you really want to disconnect all browsers?\n"
|
||||
"This may prevent connection to the browser plugin."),
|
||||
QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel)) {
|
||||
if (QMessageBox::Yes
|
||||
!= MessageBox::question(this,
|
||||
tr("Disconnect all browsers"),
|
||||
tr("Do you really want to disconnect all browsers?\n"
|
||||
"This may prevent connection to the browser plugin."),
|
||||
QMessageBox::Yes | QMessageBox::Cancel,
|
||||
QMessageBox::Cancel)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -182,11 +194,13 @@ void DatabaseSettingsWidgetBrowser::removeSharedEncryptionKeys()
|
||||
|
||||
void DatabaseSettingsWidgetBrowser::removeStoredPermissions()
|
||||
{
|
||||
if (QMessageBox::Yes != MessageBox::question(this,
|
||||
tr("Forget all site-specific settings on entries"),
|
||||
tr("Do you really want forget all site-specific settings on every entry?\n"
|
||||
"Permissions to access entries will be revoked."),
|
||||
QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel)) {
|
||||
if (QMessageBox::Yes
|
||||
!= MessageBox::question(this,
|
||||
tr("Forget all site-specific settings on entries"),
|
||||
tr("Do you really want forget all site-specific settings on every entry?\n"
|
||||
"Permissions to access entries will be revoked."),
|
||||
QMessageBox::Yes | QMessageBox::Cancel,
|
||||
QMessageBox::Cancel)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -226,11 +240,14 @@ void DatabaseSettingsWidgetBrowser::removeStoredPermissions()
|
||||
|
||||
void DatabaseSettingsWidgetBrowser::convertAttributesToCustomData()
|
||||
{
|
||||
if (QMessageBox::Yes != MessageBox::question(this,
|
||||
tr("Move KeePassHTTP attributes to custom data"),
|
||||
tr("Do you really want to move all legacy browser integration data to the latest standard?\n"
|
||||
"This is necessary to maintain compatibility with the browser plugin."),
|
||||
QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel)) {
|
||||
if (QMessageBox::Yes
|
||||
!= MessageBox::question(
|
||||
this,
|
||||
tr("Move KeePassHTTP attributes to custom data"),
|
||||
tr("Do you really want to move all legacy browser integration data to the latest standard?\n"
|
||||
"This is necessary to maintain compatibility with the browser plugin."),
|
||||
QMessageBox::Yes | QMessageBox::Cancel,
|
||||
QMessageBox::Cancel)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -242,4 +259,3 @@ void DatabaseSettingsWidgetBrowser::updateSharedKeyList()
|
||||
{
|
||||
updateModel();
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user