Formatting the code.

This commit is contained in:
Louis-Bertrand Varin 2018-03-31 16:01:30 -04:00
parent 74efc57369
commit 8324d03f0a
294 changed files with 3796 additions and 3740 deletions

View File

@ -304,8 +304,8 @@ void AutoType::performGlobalAutoType(const QList<Database*>& dbList)
auto* msgBox = new QMessageBox(); auto* msgBox = new QMessageBox();
msgBox->setAttribute(Qt::WA_DeleteOnClose); msgBox->setAttribute(Qt::WA_DeleteOnClose);
msgBox->setWindowTitle(tr("Auto-Type - KeePassXC")); msgBox->setWindowTitle(tr("Auto-Type - KeePassXC"));
msgBox->setText(tr("Couldn't find an entry that matches the window title:").append("\n\n") msgBox->setText(
.append(windowTitle)); tr("Couldn't find an entry that matches the window title:").append("\n\n").append(windowTitle));
msgBox->setIcon(QMessageBox::Information); msgBox->setIcon(QMessageBox::Information);
msgBox->setStandardButtons(QMessageBox::Ok); msgBox->setStandardButtons(QMessageBox::Ok);
msgBox->show(); msgBox->show();
@ -323,8 +323,7 @@ void AutoType::performGlobalAutoType(const QList<Database*>& dbList)
auto* selectDialog = new AutoTypeSelectDialog(); auto* selectDialog = new AutoTypeSelectDialog();
// connect slots, both of which must unlock the m_inGlobalAutoTypeDialog mutex // connect slots, both of which must unlock the m_inGlobalAutoTypeDialog mutex
connect(selectDialog, SIGNAL(matchActivated(AutoTypeMatch)), connect(selectDialog, SIGNAL(matchActivated(AutoTypeMatch)), SLOT(performAutoTypeFromGlobal(AutoTypeMatch)));
SLOT(performAutoTypeFromGlobal(AutoTypeMatch)));
connect(selectDialog, SIGNAL(rejected()), SLOT(autoTypeRejectedFromGlobal())); connect(selectDialog, SIGNAL(rejected()), SLOT(autoTypeRejectedFromGlobal()));
selectDialog->setMatchList(matchList); selectDialog->setMatchList(matchList);
@ -449,11 +448,11 @@ QList<AutoTypeAction*> AutoType::createActionFromTemplate(const QString& tmpl, c
list.append(new AutoTypeKey(Qt::Key_Left)); list.append(new AutoTypeKey(Qt::Key_Left));
} else if (tmplName.compare("right", Qt::CaseInsensitive) == 0) { } else if (tmplName.compare("right", Qt::CaseInsensitive) == 0) {
list.append(new AutoTypeKey(Qt::Key_Right)); list.append(new AutoTypeKey(Qt::Key_Right));
} else if (tmplName.compare("insert", Qt::CaseInsensitive) == 0 || } else if (tmplName.compare("insert", Qt::CaseInsensitive) == 0
tmplName.compare("ins", Qt::CaseInsensitive) == 0) { || tmplName.compare("ins", Qt::CaseInsensitive) == 0) {
list.append(new AutoTypeKey(Qt::Key_Insert)); list.append(new AutoTypeKey(Qt::Key_Insert));
} else if (tmplName.compare("delete", Qt::CaseInsensitive) == 0 || } else if (tmplName.compare("delete", Qt::CaseInsensitive) == 0
tmplName.compare("del", Qt::CaseInsensitive) == 0) { || tmplName.compare("del", Qt::CaseInsensitive) == 0) {
list.append(new AutoTypeKey(Qt::Key_Delete)); list.append(new AutoTypeKey(Qt::Key_Delete));
} else if (tmplName.compare("home", Qt::CaseInsensitive) == 0) { } else if (tmplName.compare("home", Qt::CaseInsensitive) == 0) {
list.append(new AutoTypeKey(Qt::Key_Home)); list.append(new AutoTypeKey(Qt::Key_Home));
@ -463,8 +462,9 @@ QList<AutoTypeAction*> AutoType::createActionFromTemplate(const QString& tmpl, c
list.append(new AutoTypeKey(Qt::Key_PageUp)); list.append(new AutoTypeKey(Qt::Key_PageUp));
} else if (tmplName.compare("pgdown", Qt::CaseInsensitive) == 0) { } else if (tmplName.compare("pgdown", Qt::CaseInsensitive) == 0) {
list.append(new AutoTypeKey(Qt::Key_PageDown)); list.append(new AutoTypeKey(Qt::Key_PageDown));
} else if (tmplName.compare("backspace", Qt::CaseInsensitive) == 0 || } else if (tmplName.compare("backspace", Qt::CaseInsensitive) == 0
tmplName.compare("bs", Qt::CaseInsensitive) == 0 || tmplName.compare("bksp", Qt::CaseInsensitive) == 0) { || tmplName.compare("bs", Qt::CaseInsensitive) == 0
|| tmplName.compare("bksp", Qt::CaseInsensitive) == 0) {
list.append(new AutoTypeKey(Qt::Key_Backspace)); list.append(new AutoTypeKey(Qt::Key_Backspace));
} else if (tmplName.compare("break", Qt::CaseInsensitive) == 0) { } else if (tmplName.compare("break", Qt::CaseInsensitive) == 0) {
list.append(new AutoTypeKey(Qt::Key_Pause)); list.append(new AutoTypeKey(Qt::Key_Pause));
@ -591,13 +591,13 @@ QList<QString> AutoType::autoTypeSequences(const Entry* entry, const QString& wi
} }
} }
if (config()->get("AutoTypeEntryTitleMatch").toBool() && if (config()->get("AutoTypeEntryTitleMatch").toBool()
windowMatchesTitle(windowTitle, entry->resolvePlaceholder(entry->title()))) { && windowMatchesTitle(windowTitle, entry->resolvePlaceholder(entry->title()))) {
sequenceList.append(entry->effectiveAutoTypeSequence()); sequenceList.append(entry->effectiveAutoTypeSequence());
} }
if (config()->get("AutoTypeEntryURLMatch").toBool() && if (config()->get("AutoTypeEntryURLMatch").toBool()
windowMatchesUrl(windowTitle, entry->resolvePlaceholder(entry->url()))) { && windowMatchesUrl(windowTitle, entry->resolvePlaceholder(entry->url()))) {
sequenceList.append(entry->effectiveAutoTypeSequence()); sequenceList.append(entry->effectiveAutoTypeSequence());
} }
@ -673,8 +673,20 @@ bool AutoType::checkSyntax(const QString& string)
// a normal string not in parentheses // a normal string not in parentheses
QString fixedStrings = "[^\\^\\%~\\+@\\{\\}]*"; QString fixedStrings = "[^\\^\\%~\\+@\\{\\}]*";
QRegularExpression autoTypeSyntax("^(?:" + shortcutKeys + "|" + fixedStrings + "|\\{(?:" + normalCommands + "|" + specialLiterals + QRegularExpression autoTypeSyntax(
"|" + functionKeys + "|" + numpad + "|" + delay + "|" + beep + "|" + vkey + ")\\}|\\{" + customAttributes + "\\})*$", "^(?:" + shortcutKeys + "|" + fixedStrings + "|\\{(?:" + normalCommands + "|" + specialLiterals + "|"
+ functionKeys
+ "|"
+ numpad
+ "|"
+ delay
+ "|"
+ beep
+ "|"
+ vkey
+ ")\\}|\\{"
+ customAttributes
+ "\\})*$",
QRegularExpression::CaseInsensitiveOption); QRegularExpression::CaseInsensitiveOption);
QRegularExpressionMatch match = autoTypeSyntax.match(string); QRegularExpressionMatch match = autoTypeSyntax.match(string);
return match.hasMatch(); return match.hasMatch();
@ -724,7 +736,9 @@ bool AutoType::verifyAutoTypeSyntax(const QString& sequence)
return false; return false;
} else if (AutoType::checkHighDelay(sequence)) { } else if (AutoType::checkHighDelay(sequence)) {
QMessageBox::StandardButton reply; QMessageBox::StandardButton reply;
reply = QMessageBox::question(nullptr, tr("Auto-Type"), reply = QMessageBox::question(
nullptr,
tr("Auto-Type"),
tr("This Auto-Type command contains a very long delay. Do you really want to proceed?")); tr("This Auto-Type command contains a very long delay. Do you really want to proceed?"));
if (reply == QMessageBox::No) { if (reply == QMessageBox::No) {
@ -732,7 +746,9 @@ bool AutoType::verifyAutoTypeSyntax(const QString& sequence)
} }
} else if (AutoType::checkSlowKeypress(sequence)) { } else if (AutoType::checkSlowKeypress(sequence)) {
QMessageBox::StandardButton reply; QMessageBox::StandardButton reply;
reply = QMessageBox::question(nullptr, tr("Auto-Type"), reply = QMessageBox::question(
nullptr,
tr("Auto-Type"),
tr("This Auto-Type command contains very slow key presses. Do you really want to proceed?")); tr("This Auto-Type command contains very slow key presses. Do you really want to proceed?"));
if (reply == QMessageBox::No) { if (reply == QMessageBox::No) {
@ -740,8 +756,9 @@ bool AutoType::verifyAutoTypeSyntax(const QString& sequence)
} }
} else if (AutoType::checkHighRepetition(sequence)) { } else if (AutoType::checkHighRepetition(sequence)) {
QMessageBox::StandardButton reply; QMessageBox::StandardButton reply;
reply = QMessageBox::question(nullptr, tr("Auto-Type"), reply =
tr("This Auto-Type command contains arguments which are repeated very often. Do you really want to proceed?")); 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) { if (reply == QMessageBox::No) {
return false; return false;

View File

@ -19,10 +19,10 @@
#ifndef KEEPASSX_AUTOTYPE_H #ifndef KEEPASSX_AUTOTYPE_H
#define KEEPASSX_AUTOTYPE_H #define KEEPASSX_AUTOTYPE_H
#include <QMutex>
#include <QObject> #include <QObject>
#include <QStringList> #include <QStringList>
#include <QWidget> #include <QWidget>
#include <QMutex>
#include "core/AutoTypeMatch.h" #include "core/AutoTypeMatch.h"
@ -47,8 +47,7 @@ public:
static bool checkSlowKeypress(const QString& string); static bool checkSlowKeypress(const QString& string);
static bool checkHighDelay(const QString& string); static bool checkHighDelay(const QString& string);
static bool verifyAutoTypeSyntax(const QString& sequence); static bool verifyAutoTypeSyntax(const QString& sequence);
void performAutoType(const Entry* entry, void performAutoType(const Entry* entry, QWidget* hideWindow = nullptr);
QWidget* hideWindow = nullptr);
inline bool isAvailable() inline bool isAvailable()
{ {

View File

@ -34,7 +34,6 @@ void AutoTypeChar::accept(AutoTypeExecutor* executor)
executor->execChar(this); executor->execChar(this);
} }
AutoTypeKey::AutoTypeKey(Qt::Key key) AutoTypeKey::AutoTypeKey(Qt::Key key)
: key(key) : key(key)
{ {
@ -50,7 +49,6 @@ void AutoTypeKey::accept(AutoTypeExecutor* executor)
executor->execKey(this); executor->execKey(this);
} }
AutoTypeDelay::AutoTypeDelay(int delayMs) AutoTypeDelay::AutoTypeDelay(int delayMs)
: delayMs(delayMs) : delayMs(delayMs)
{ {
@ -66,7 +64,6 @@ void AutoTypeDelay::accept(AutoTypeExecutor* executor)
executor->execDelay(this); executor->execDelay(this);
} }
AutoTypeClearField::AutoTypeClearField() AutoTypeClearField::AutoTypeClearField()
{ {
} }
@ -81,7 +78,6 @@ void AutoTypeClearField::accept(AutoTypeExecutor* executor)
executor->execClearField(this); executor->execClearField(this);
} }
void AutoTypeExecutor::execDelay(AutoTypeDelay* action) void AutoTypeExecutor::execDelay(AutoTypeDelay* action)
{ {
Tools::wait(action->delayMs); Tools::wait(action->delayMs);

View File

@ -19,8 +19,8 @@
#define KEEPASSX_AUTOTYPEACTION_H #define KEEPASSX_AUTOTYPEACTION_H
#include <QChar> #include <QChar>
#include <Qt>
#include <QObject> #include <QObject>
#include <Qt>
#include "core/Global.h" #include "core/Global.h"
@ -29,7 +29,9 @@ class AutoTypeExecutor;
class KEEPASSX_EXPORT AutoTypeAction class KEEPASSX_EXPORT AutoTypeAction
{ {
public: public:
virtual ~AutoTypeAction() {} virtual ~AutoTypeAction()
{
}
virtual AutoTypeAction* clone() = 0; virtual AutoTypeAction* clone() = 0;
virtual void accept(AutoTypeExecutor* executor) = 0; virtual void accept(AutoTypeExecutor* executor) = 0;
}; };
@ -75,7 +77,9 @@ public:
class KEEPASSX_EXPORT AutoTypeExecutor class KEEPASSX_EXPORT AutoTypeExecutor
{ {
public: public:
virtual ~AutoTypeExecutor() {} virtual ~AutoTypeExecutor()
{
}
virtual void execChar(AutoTypeChar* action) = 0; virtual void execChar(AutoTypeChar* action) = 0;
virtual void execKey(AutoTypeKey* action) = 0; virtual void execKey(AutoTypeKey* action) = 0;
virtual void execDelay(AutoTypeDelay* action); virtual void execDelay(AutoTypeDelay* action);

View File

@ -25,7 +25,9 @@
class AutoTypePlatformInterface class AutoTypePlatformInterface
{ {
public: public:
virtual ~AutoTypePlatformInterface() {} virtual ~AutoTypePlatformInterface()
{
}
virtual bool isAvailable() = 0; virtual bool isAvailable() = 0;
virtual QStringList windowTitles() = 0; virtual QStringList windowTitles() = 0;
virtual WId activeWindow() = 0; virtual WId activeWindow() = 0;
@ -35,7 +37,9 @@ public:
virtual int platformEventFilter(void* event) = 0; virtual int platformEventFilter(void* event) = 0;
virtual int initialTimeout() = 0; virtual int initialTimeout() = 0;
virtual bool raiseWindow(WId window) = 0; virtual bool raiseWindow(WId window) = 0;
virtual void unload() {} virtual void unload()
{
}
virtual AutoTypeExecutor* createExecutor() = 0; virtual AutoTypeExecutor* createExecutor() = 0;

View File

@ -61,7 +61,7 @@ AutoTypeSelectDialog::AutoTypeSelectDialog(QWidget* parent)
connect(m_view, SIGNAL(activated(QModelIndex)), SLOT(emitMatchActivated(QModelIndex))); connect(m_view, SIGNAL(activated(QModelIndex)), SLOT(emitMatchActivated(QModelIndex)));
connect(m_view, SIGNAL(clicked(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->model(), SIGNAL(rowsRemoved(QModelIndex, int, int)), SLOT(matchRemoved()));
connect(m_view, SIGNAL(rejected()), SLOT(reject())); connect(m_view, SIGNAL(rejected()), SLOT(reject()));
layout->addWidget(m_view); layout->addWidget(m_view);

View File

@ -36,8 +36,7 @@ void AutoTypeSelectView::mouseMoveEvent(QMouseEvent* event)
if (index.isValid()) { if (index.isValid()) {
setCurrentIndex(index); setCurrentIndex(index);
setCursor(Qt::PointingHandCursor); setCursor(Qt::PointingHandCursor);
} } else {
else {
unsetCursor(); unsetCursor();
} }

View File

@ -50,8 +50,7 @@ void ShortcutWidget::setShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers)
if (autoType()->registerGlobalShortcut(m_key, m_modifiers)) { if (autoType()->registerGlobalShortcut(m_key, m_modifiers)) {
setStyleSheet(""); setStyleSheet("");
} } else {
else {
setStyleSheet("background-color: #FF9696;"); setStyleSheet("background-color: #FF9696;");
} }
} }
@ -112,14 +111,12 @@ void ShortcutWidget::keyEvent(QKeyEvent* event)
if (!release && !keyIsModifier) { if (!release && !keyIsModifier) {
if (modifiers != 0) { if (modifiers != 0) {
setShortcut(key, modifiers); setShortcut(key, modifiers);
} } else {
else {
resetShortcut(); resetShortcut();
setStyleSheet(""); setStyleSheet("");
displayShortcut(key, modifiers); displayShortcut(key, modifiers);
} }
} } else {
else {
if (m_locked) { if (m_locked) {
resetShortcut(); resetShortcut();
setStyleSheet(""); setStyleSheet("");

View File

@ -33,8 +33,7 @@ bool WildcardMatcher::match(const QString& pattern)
if (patternContainsWildcard()) { if (patternContainsWildcard()) {
return matchWithWildcards(); return matchWithWildcards();
} } else {
else {
return patternEqualsText(); return patternEqualsText();
} }
} }
@ -63,8 +62,7 @@ bool WildcardMatcher::matchWithWildcards()
bool WildcardMatcher::startOrEndDoesNotMatch(const QStringList& parts) bool WildcardMatcher::startOrEndDoesNotMatch(const QStringList& parts)
{ {
return !m_text.startsWith(parts.first(), Sensitivity) || return !m_text.startsWith(parts.first(), Sensitivity) || !m_text.endsWith(parts.last(), Sensitivity);
!m_text.endsWith(parts.last(), Sensitivity);
} }
bool WildcardMatcher::partsMatch(const QStringList& parts) bool WildcardMatcher::partsMatch(const QStringList& parts)

View File

@ -20,13 +20,11 @@
#include <QtPlugin> #include <QtPlugin>
#include "autotype/AutoTypePlatformPlugin.h"
#include "autotype/AutoTypeAction.h" #include "autotype/AutoTypeAction.h"
#include "autotype/AutoTypePlatformPlugin.h"
#include "autotype/test/AutoTypeTestInterface.h" #include "autotype/test/AutoTypeTestInterface.h"
class AutoTypePlatformTest : public QObject, class AutoTypePlatformTest : public QObject, public AutoTypePlatformInterface, public AutoTypeTestInterface
public AutoTypePlatformInterface,
public AutoTypeTestInterface
{ {
Q_OBJECT Q_OBJECT
Q_PLUGIN_METADATA(IID "org.keepassx.AutoTypePlatformInterface") Q_PLUGIN_METADATA(IID "org.keepassx.AutoTypePlatformInterface")

View File

@ -23,7 +23,9 @@
class AutoTypeTestInterface class AutoTypeTestInterface
{ {
public: public:
virtual ~AutoTypeTestInterface() {} virtual ~AutoTypeTestInterface()
{
}
virtual void setActiveWindowTitle(const QString& title) = 0; virtual void setActiveWindowTitle(const QString& title) = 0;
virtual QString actionChars() = 0; virtual QString actionChars() = 0;

View File

@ -94,7 +94,7 @@ void AutoTypePlatformWin::unregisterGlobalShortcut(Qt::Key key, Qt::KeyboardModi
// //
int AutoTypePlatformWin::platformEventFilter(void* event) int AutoTypePlatformWin::platformEventFilter(void* event)
{ {
MSG *msg = static_cast<MSG *>(event); MSG* msg = static_cast<MSG*>(event);
if (msg->message == WM_HOTKEY && msg->wParam == HOTKEY_ID) { if (msg->message == WM_HOTKEY && msg->wParam == HOTKEY_ID) {
emit globalShortcutTriggered(); emit globalShortcutTriggered();
@ -480,17 +480,14 @@ BOOL AutoTypePlatformWin::isAltTabWindow(HWND hwnd)
// //
// Window title enum proc // Window title enum proc
// //
BOOL CALLBACK AutoTypePlatformWin::windowTitleEnumProc( BOOL CALLBACK AutoTypePlatformWin::windowTitleEnumProc(_In_ HWND hwnd, _In_ LPARAM lParam)
_In_ HWND hwnd,
_In_ LPARAM lParam
)
{ {
if (!isAltTabWindow(hwnd)) { if (!isAltTabWindow(hwnd)) {
// Skip window // Skip window
return TRUE; return TRUE;
} }
QStringList *list = reinterpret_cast<QStringList *>(lParam); QStringList* list = reinterpret_cast<QStringList*>(lParam);
QString title = windowTitle(hwnd); QString title = windowTitle(hwnd);
if (!title.isEmpty()) { if (!title.isEmpty()) {
@ -508,7 +505,7 @@ QString AutoTypePlatformWin::windowTitle(HWND hwnd)
wchar_t title[MAX_WINDOW_TITLE_LENGTH]; wchar_t title[MAX_WINDOW_TITLE_LENGTH];
int count = ::GetWindowTextW(hwnd, title, MAX_WINDOW_TITLE_LENGTH); int count = ::GetWindowTextW(hwnd, title, MAX_WINDOW_TITLE_LENGTH);
return QString::fromUtf16(reinterpret_cast<const ushort *>(title), count); return QString::fromUtf16(reinterpret_cast<const ushort*>(title), count);
} }
// //

View File

@ -22,8 +22,8 @@
#include <QtPlugin> #include <QtPlugin>
#include <Windows.h> #include <Windows.h>
#include "autotype/AutoTypePlatformPlugin.h"
#include "autotype/AutoTypeAction.h" #include "autotype/AutoTypeAction.h"
#include "autotype/AutoTypePlatformPlugin.h"
class AutoTypePlatformWin : public QObject, public AutoTypePlatformInterface class AutoTypePlatformWin : public QObject, public AutoTypePlatformInterface
{ {
@ -72,4 +72,3 @@ private:
}; };
#endif // KEEPASSX_AUTOTYPEWINDOWS_H #endif // KEEPASSX_AUTOTYPEWINDOWS_H

View File

@ -40,11 +40,14 @@ AutoTypePlatformX11::AutoTypePlatformX11()
m_atomUtf8String = XInternAtom(m_dpy, "UTF8_STRING", True); m_atomUtf8String = XInternAtom(m_dpy, "UTF8_STRING", True);
m_atomNetActiveWindow = XInternAtom(m_dpy, "_NET_ACTIVE_WINDOW", True); m_atomNetActiveWindow = XInternAtom(m_dpy, "_NET_ACTIVE_WINDOW", True);
m_classBlacklist << "desktop_window" << "gnome-panel"; // Gnome m_classBlacklist << "desktop_window"
m_classBlacklist << "kdesktop" << "kicker"; // KDE 3 << "gnome-panel"; // Gnome
m_classBlacklist << "kdesktop"
<< "kicker"; // KDE 3
m_classBlacklist << "Plasma"; // KDE 4 m_classBlacklist << "Plasma"; // KDE 4
m_classBlacklist << "plasmashell"; // KDE 5 m_classBlacklist << "plasmashell"; // KDE 5
m_classBlacklist << "xfdesktop" << "xfce4-panel"; // Xfce 4 m_classBlacklist << "xfdesktop"
<< "xfce4-panel"; // Xfce 4
m_currentGlobalKey = static_cast<Qt::Key>(0); m_currentGlobalKey = static_cast<Qt::Key>(0);
m_currentGlobalModifiers = 0; m_currentGlobalModifiers = 0;
@ -146,12 +149,9 @@ bool AutoTypePlatformX11::registerGlobalShortcut(Qt::Key key, Qt::KeyboardModifi
startCatchXErrors(); startCatchXErrors();
XGrabKey(m_dpy, keycode, nativeModifiers, m_rootWindow, True, GrabModeAsync, GrabModeAsync); XGrabKey(m_dpy, keycode, nativeModifiers, m_rootWindow, True, GrabModeAsync, GrabModeAsync);
XGrabKey(m_dpy, keycode, nativeModifiers | Mod2Mask, m_rootWindow, True, GrabModeAsync, XGrabKey(m_dpy, keycode, nativeModifiers | Mod2Mask, m_rootWindow, True, GrabModeAsync, GrabModeAsync);
GrabModeAsync); XGrabKey(m_dpy, keycode, nativeModifiers | LockMask, m_rootWindow, True, GrabModeAsync, GrabModeAsync);
XGrabKey(m_dpy, keycode, nativeModifiers | LockMask, m_rootWindow, True, GrabModeAsync, XGrabKey(m_dpy, keycode, nativeModifiers | Mod2Mask | LockMask, m_rootWindow, True, GrabModeAsync, GrabModeAsync);
GrabModeAsync);
XGrabKey(m_dpy, keycode, nativeModifiers | Mod2Mask | LockMask, m_rootWindow, True,
GrabModeAsync, GrabModeAsync);
stopCatchXErrors(); stopCatchXErrors();
if (!m_xErrorOccurred) { if (!m_xErrorOccurred) {
@ -160,8 +160,7 @@ bool AutoTypePlatformX11::registerGlobalShortcut(Qt::Key key, Qt::KeyboardModifi
m_currentGlobalKeycode = keycode; m_currentGlobalKeycode = keycode;
m_currentGlobalNativeModifiers = nativeModifiers; m_currentGlobalNativeModifiers = nativeModifiers;
return true; return true;
} } else {
else {
unregisterGlobalShortcut(key, modifiers); unregisterGlobalShortcut(key, modifiers);
return false; return false;
} }
@ -220,20 +219,17 @@ int AutoTypePlatformX11::platformEventFilter(void* event)
return 1; return 1;
} }
} } else if (type == XCB_MAPPING_NOTIFY) {
else if (type == XCB_MAPPING_NOTIFY) {
xcb_mapping_notify_event_t* mappingNotifyEvent = static_cast<xcb_mapping_notify_event_t*>(event); xcb_mapping_notify_event_t* mappingNotifyEvent = static_cast<xcb_mapping_notify_event_t*>(event);
if (mappingNotifyEvent->request == XCB_MAPPING_KEYBOARD if (mappingNotifyEvent->request == XCB_MAPPING_KEYBOARD
|| mappingNotifyEvent->request == XCB_MAPPING_MODIFIER) || mappingNotifyEvent->request == XCB_MAPPING_MODIFIER) {
{
XMappingEvent xMappingEvent; XMappingEvent xMappingEvent;
memset(&xMappingEvent, 0, sizeof(xMappingEvent)); memset(&xMappingEvent, 0, sizeof(xMappingEvent));
xMappingEvent.type = MappingNotify; xMappingEvent.type = MappingNotify;
xMappingEvent.display = m_dpy; xMappingEvent.display = m_dpy;
if (mappingNotifyEvent->request == XCB_MAPPING_KEYBOARD) { if (mappingNotifyEvent->request == XCB_MAPPING_KEYBOARD) {
xMappingEvent.request = MappingKeyboard; xMappingEvent.request = MappingKeyboard;
} } else {
else {
xMappingEvent.request = MappingModifier; xMappingEvent.request = MappingModifier;
} }
xMappingEvent.first_keycode = mappingNotifyEvent->first_keycode; xMappingEvent.first_keycode = mappingNotifyEvent->first_keycode;
@ -263,13 +259,12 @@ QString AutoTypePlatformX11::windowTitle(Window window, bool useBlacklist)
// the window manager spec says we should read _NET_WM_NAME first, then fall back to WM_NAME // the window manager spec says we should read _NET_WM_NAME first, then fall back to WM_NAME
int retVal = XGetWindowProperty(m_dpy, window, m_atomNetWmName, 0, 1000, False, m_atomUtf8String, int retVal = XGetWindowProperty(
&type, &format, &nitems, &after, &data); m_dpy, window, m_atomNetWmName, 0, 1000, False, m_atomUtf8String, &type, &format, &nitems, &after, &data);
if ((retVal == 0) && data) { if ((retVal == 0) && data) {
title = QString::fromUtf8(reinterpret_cast<char*>(data)); title = QString::fromUtf8(reinterpret_cast<char*>(data));
} } else {
else {
XTextProperty textProp; XTextProperty textProp;
retVal = XGetTextProperty(m_dpy, window, &textProp, m_atomWmName); retVal = XGetTextProperty(m_dpy, window, &textProp, m_atomWmName);
if ((retVal != 0) && textProp.value) { if ((retVal != 0) && textProp.value) {
@ -278,12 +273,10 @@ QString AutoTypePlatformX11::windowTitle(Window window, bool useBlacklist)
if (textProp.encoding == m_atomUtf8String) { if (textProp.encoding == m_atomUtf8String) {
title = QString::fromUtf8(reinterpret_cast<char*>(textProp.value)); title = QString::fromUtf8(reinterpret_cast<char*>(textProp.value));
} } else if ((XmbTextPropertyToTextList(m_dpy, &textProp, &textList, &count) == 0) && textList
else if ((XmbTextPropertyToTextList(m_dpy, &textProp, &textList, &count) == 0) && (count > 0)) {
&& textList && (count > 0)) {
title = QString::fromLocal8Bit(textList[0]); title = QString::fromLocal8Bit(textList[0]);
} } else if (textProp.encoding == m_atomString) {
else if (textProp.encoding == m_atomString) {
title = QString::fromLocal8Bit(reinterpret_cast<char*>(textProp.value)); title = QString::fromLocal8Bit(reinterpret_cast<char*>(textProp.value));
} }
@ -386,8 +379,8 @@ bool AutoTypePlatformX11::isTopLevelWindow(Window window)
unsigned long nitems; unsigned long nitems;
unsigned long after; unsigned long after;
unsigned char* data = Q_NULLPTR; unsigned char* data = Q_NULLPTR;
int retVal = XGetWindowProperty(m_dpy, window, m_atomWmState, 0, 2, False, m_atomWmState, &type, &format, int retVal = XGetWindowProperty(
&nitems, &after, &data); m_dpy, window, m_atomWmState, 0, 2, False, m_atomWmState, &type, &format, &nitems, &after, &data);
bool result = false; bool result = false;
@ -408,15 +401,12 @@ KeySym AutoTypePlatformX11::charToKeySym(const QChar& ch)
ushort unicode = ch.unicode(); ushort unicode = ch.unicode();
/* first check for Latin-1 characters (1:1 mapping) */ /* first check for Latin-1 characters (1:1 mapping) */
if ((unicode >= 0x0020 && unicode <= 0x007e) if ((unicode >= 0x0020 && unicode <= 0x007e) || (unicode >= 0x00a0 && unicode <= 0x00ff)) {
|| (unicode >= 0x00a0 && unicode <= 0x00ff)) {
return unicode; return unicode;
} }
/* mapping table generated from keysymdef.h */ /* mapping table generated from keysymdef.h */
const uint* match = Tools::binaryFind(m_unicodeToKeysymKeys, const uint* match = Tools::binaryFind(m_unicodeToKeysymKeys, m_unicodeToKeysymKeys + m_unicodeToKeysymLen, unicode);
m_unicodeToKeysymKeys + m_unicodeToKeysymLen,
unicode);
int index = match - m_unicodeToKeysymKeys; int index = match - m_unicodeToKeysymKeys;
if (index != m_unicodeToKeysymLen) { if (index != m_unicodeToKeysymLen) {
return m_unicodeToKeysymValues[index]; return m_unicodeToKeysymValues[index];
@ -483,8 +473,7 @@ KeySym AutoTypePlatformX11::keyToKeySym(Qt::Key key)
default: default:
if (key >= Qt::Key_F1 && key <= Qt::Key_F16) { if (key >= Qt::Key_F1 && key <= Qt::Key_F16) {
return XK_F1 + (key - Qt::Key_F1); return XK_F1 + (key - Qt::Key_F1);
} } else {
else {
return NoSymbol; return NoSymbol;
} }
} }
@ -499,7 +488,7 @@ void AutoTypePlatformX11::updateKeymap()
{ {
int keycode, inx; int keycode, inx;
int mod_index, mod_key; int mod_index, mod_key;
XModifierKeymap *modifiers; XModifierKeymap* modifiers;
if (m_xkb) { if (m_xkb) {
XkbFreeKeyboard(m_xkb, XkbAllComponentsMask, True); XkbFreeKeyboard(m_xkb, XkbAllComponentsMask, True);
@ -507,10 +496,9 @@ void AutoTypePlatformX11::updateKeymap()
m_xkb = getKeyboard(); m_xkb = getKeyboard();
XDisplayKeycodes(m_dpy, &m_minKeycode, &m_maxKeycode); XDisplayKeycodes(m_dpy, &m_minKeycode, &m_maxKeycode);
if (m_keysymTable != NULL) XFree(m_keysymTable); if (m_keysymTable != NULL)
m_keysymTable = XGetKeyboardMapping(m_dpy, XFree(m_keysymTable);
m_minKeycode, m_maxKeycode - m_minKeycode + 1, m_keysymTable = XGetKeyboardMapping(m_dpy, m_minKeycode, m_maxKeycode - m_minKeycode + 1, &m_keysymPerKeycode);
&m_keysymPerKeycode);
/* determine the keycode to use for remapped keys */ /* determine the keycode to use for remapped keys */
inx = (m_remapKeycode - m_minKeycode) * m_keysymPerKeycode; inx = (m_remapKeycode - m_minKeycode) * m_keysymPerKeycode;
@ -527,7 +515,7 @@ void AutoTypePlatformX11::updateKeymap()
/* determine the keycode to use for modifiers */ /* determine the keycode to use for modifiers */
modifiers = XGetModifierMapping(m_dpy); modifiers = XGetModifierMapping(m_dpy);
for (mod_index = ShiftMapIndex; mod_index <= Mod5MapIndex; mod_index ++) { for (mod_index = ShiftMapIndex; mod_index <= Mod5MapIndex; mod_index++) {
m_modifier_keycode[mod_index] = 0; m_modifier_keycode[mod_index] = 0;
for (mod_key = 0; mod_key < modifiers->max_keypermod; mod_key++) { for (mod_key = 0; mod_key < modifiers->max_keypermod; mod_key++) {
keycode = modifiers->modifiermap[mod_index * modifiers->max_keypermod + mod_key]; keycode = modifiers->modifiermap[mod_index * modifiers->max_keypermod + mod_key];
@ -625,7 +613,7 @@ int AutoTypePlatformX11::AddKeysym(KeySym keysym)
return 0; return 0;
} }
int inx = (m_remapKeycode- m_minKeycode) * m_keysymPerKeycode; int inx = (m_remapKeycode - m_minKeycode) * m_keysymPerKeycode;
m_keysymTable[inx] = keysym; m_keysymTable[inx] = keysym;
m_currentRemapKeysym = keysym; m_currentRemapKeysym = keysym;
@ -644,7 +632,7 @@ int AutoTypePlatformX11::AddKeysym(KeySym keysym)
void AutoTypePlatformX11::SendKeyEvent(unsigned keycode, bool press) void AutoTypePlatformX11::SendKeyEvent(unsigned keycode, bool press)
{ {
XSync(m_dpy, False); XSync(m_dpy, False);
int (*oldHandler) (Display*, XErrorEvent*) = XSetErrorHandler(MyErrorHandler); int (*oldHandler)(Display*, XErrorEvent*) = XSetErrorHandler(MyErrorHandler);
XTestFakeKeyEvent(m_dpy, keycode, press, 0); XTestFakeKeyEvent(m_dpy, keycode, press, 0);
XFlush(m_dpy); XFlush(m_dpy);
@ -659,7 +647,7 @@ void AutoTypePlatformX11::SendKeyEvent(unsigned keycode, bool press)
void AutoTypePlatformX11::SendModifiers(unsigned int mask, bool press) void AutoTypePlatformX11::SendModifiers(unsigned int mask, bool press)
{ {
int mod_index; int mod_index;
for (mod_index = ShiftMapIndex; mod_index <= Mod5MapIndex; mod_index ++) { for (mod_index = ShiftMapIndex; mod_index <= Mod5MapIndex; mod_index++) {
if (mask & (1 << mod_index)) { if (mask & (1 << mod_index)) {
SendKeyEvent(m_modifier_keycode[mod_index], press); SendKeyEvent(m_modifier_keycode[mod_index], press);
} }
@ -670,7 +658,7 @@ void AutoTypePlatformX11::SendModifiers(unsigned int mask, bool press)
* Determines the keycode and modifier mask for the given * Determines the keycode and modifier mask for the given
* keysym. * keysym.
*/ */
int AutoTypePlatformX11::GetKeycode(KeySym keysym, unsigned int *mask) int AutoTypePlatformX11::GetKeycode(KeySym keysym, unsigned int* mask)
{ {
int keycode = XKeysymToKeycode(m_dpy, keysym); int keycode = XKeysymToKeycode(m_dpy, keysym);
@ -688,15 +676,15 @@ int AutoTypePlatformX11::GetKeycode(KeySym keysym, unsigned int *mask)
return 0; return 0;
} }
bool AutoTypePlatformX11::keysymModifiers(KeySym keysym, int keycode, unsigned int *mask) bool AutoTypePlatformX11::keysymModifiers(KeySym keysym, int keycode, unsigned int* mask)
{ {
int shift, mod; int shift, mod;
unsigned int mods_rtrn; unsigned int mods_rtrn;
/* determine whether there is a combination of the modifiers /* determine whether there is a combination of the modifiers
(Mod1-Mod5) with or without shift which returns keysym */ (Mod1-Mod5) with or without shift which returns keysym */
for (shift = 0; shift < 2; shift ++) { for (shift = 0; shift < 2; shift++) {
for (mod = ControlMapIndex; mod <= Mod5MapIndex; mod ++) { for (mod = ControlMapIndex; mod <= Mod5MapIndex; mod++) {
KeySym keysym_rtrn; KeySym keysym_rtrn;
*mask = (mod == ControlMapIndex) ? shift : shift | (1 << mod); *mask = (mod == ControlMapIndex) ? shift : shift | (1 << mod);
XkbTranslateKeyCode(m_xkb, keycode, *mask, &mods_rtrn, &keysym_rtrn); XkbTranslateKeyCode(m_xkb, keycode, *mask, &mods_rtrn, &keysym_rtrn);
@ -709,8 +697,6 @@ bool AutoTypePlatformX11::keysymModifiers(KeySym keysym, int keycode, unsigned i
return false; return false;
} }
/* /*
* Send sequence of KeyPressed/KeyReleased events to the focused * Send sequence of KeyPressed/KeyReleased events to the focused
* window to simulate keyboard. If modifiers (shift, control, etc) * window to simulate keyboard. If modifiers (shift, control, etc)
@ -753,7 +739,7 @@ void AutoTypePlatformX11::SendKey(KeySym keysym, unsigned int modifiers)
if (!modifiers) { if (!modifiers) {
// check every release_check_mask individually if it affects the keysym we would generate // check every release_check_mask individually if it affects the keysym we would generate
// if it doesn't we probably don't need to release it // if it doesn't we probably don't need to release it
for (int mod_index = ShiftMapIndex; mod_index <= Mod5MapIndex; mod_index ++) { for (int mod_index = ShiftMapIndex; mod_index <= Mod5MapIndex; mod_index++) {
if (release_check_mask & (1 << mod_index)) { if (release_check_mask & (1 << mod_index)) {
unsigned int mods_rtrn; unsigned int mods_rtrn;
KeySym keysym_rtrn; KeySym keysym_rtrn;
@ -768,7 +754,8 @@ void AutoTypePlatformX11::SendKey(KeySym keysym, unsigned int modifiers)
// finally check if the combination of pressed modifiers that we chose to ignore affects the keysym // finally check if the combination of pressed modifiers that we chose to ignore affects the keysym
unsigned int mods_rtrn; unsigned int mods_rtrn;
KeySym keysym_rtrn; KeySym keysym_rtrn;
XkbTranslateKeyCode(m_xkb, keycode, wanted_mask | (release_check_mask & ~release_mask), &mods_rtrn, &keysym_rtrn); XkbTranslateKeyCode(
m_xkb, keycode, wanted_mask | (release_check_mask & ~release_mask), &mods_rtrn, &keysym_rtrn);
if (keysym_rtrn != keysym) { if (keysym_rtrn != keysym) {
// oh well, release all the modifiers we don't want // oh well, release all the modifiers we don't want
release_mask = release_check_mask; release_mask = release_check_mask;
@ -810,7 +797,6 @@ int AutoTypePlatformX11::MyErrorHandler(Display* my_dpy, XErrorEvent* event)
return 0; return 0;
} }
AutoTypeExecutorX11::AutoTypeExecutorX11(AutoTypePlatformX11* platform) AutoTypeExecutorX11::AutoTypeExecutorX11(AutoTypePlatformX11* platform)
: m_platform(platform) : m_platform(platform)
{ {
@ -844,7 +830,6 @@ void AutoTypeExecutorX11::execClearField(AutoTypeClearField* action = nullptr)
nanosleep(&ts, nullptr); nanosleep(&ts, nullptr);
} }
int AutoTypePlatformX11::initialTimeout() int AutoTypePlatformX11::initialTimeout()
{ {
return 500; return 500;
@ -870,15 +855,12 @@ bool AutoTypePlatformX11::raiseWindow(WId window)
QWidget* activeWindow = QApplication::activeWindow(); QWidget* activeWindow = QApplication::activeWindow();
if (activeWindow) { if (activeWindow) {
event.xclient.data.l[2] = activeWindow->internalWinId(); event.xclient.data.l[2] = activeWindow->internalWinId();
} } else {
else {
event.xclient.data.l[2] = 0; event.xclient.data.l[2] = 0;
} }
event.xclient.data.l[3] = 0; event.xclient.data.l[3] = 0;
event.xclient.data.l[4] = 0; event.xclient.data.l[4] = 0;
XSendEvent(m_dpy, m_rootWindow, False, XSendEvent(m_dpy, m_rootWindow, False, SubstructureRedirectMask | SubstructureNotifyMask, &event);
SubstructureRedirectMask | SubstructureNotifyMask,
&event);
XFlush(m_dpy); XFlush(m_dpy);
return true; return true;

View File

@ -22,16 +22,16 @@
#include <QApplication> #include <QApplication>
#include <QSet> #include <QSet>
#include <QtPlugin>
#include <QWidget> #include <QWidget>
#include <QX11Info> #include <QX11Info>
#include <QtPlugin>
#include <X11/XKBlib.h>
#include <X11/Xutil.h> #include <X11/Xutil.h>
#include <X11/extensions/XTest.h> #include <X11/extensions/XTest.h>
#include <X11/XKBlib.h>
#include "autotype/AutoTypePlatformPlugin.h"
#include "autotype/AutoTypeAction.h" #include "autotype/AutoTypeAction.h"
#include "autotype/AutoTypePlatformPlugin.h"
#define N_MOD_INDICES (Mod5MapIndex + 1) #define N_MOD_INDICES (Mod5MapIndex + 1)
@ -81,8 +81,8 @@ private:
void AddModifier(KeySym keysym); void AddModifier(KeySym keysym);
void SendKeyEvent(unsigned keycode, bool press); void SendKeyEvent(unsigned keycode, bool press);
void SendModifiers(unsigned int mask, bool press); void SendModifiers(unsigned int mask, bool press);
int GetKeycode(KeySym keysym, unsigned int *mask); int GetKeycode(KeySym keysym, unsigned int* mask);
bool keysymModifiers(KeySym keysym, int keycode, unsigned int *mask); bool keysymModifiers(KeySym keysym, int keycode, unsigned int* mask);
static int MyErrorHandler(Display* my_dpy, XErrorEvent* event); static int MyErrorHandler(Display* my_dpy, XErrorEvent* event);

11
src/browser/BrowserAccessControlDialog.cpp Executable file → Normal file
View File

@ -17,12 +17,12 @@
*/ */
#include "BrowserAccessControlDialog.h" #include "BrowserAccessControlDialog.h"
#include "ui_BrowserAccessControlDialog.h"
#include "core/Entry.h" #include "core/Entry.h"
#include "ui_BrowserAccessControlDialog.h"
BrowserAccessControlDialog::BrowserAccessControlDialog(QWidget* parent) : BrowserAccessControlDialog::BrowserAccessControlDialog(QWidget* parent)
QDialog(parent), : QDialog(parent)
ui(new Ui::BrowserAccessControlDialog()) , ui(new Ui::BrowserAccessControlDialog())
{ {
this->setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); this->setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
@ -38,7 +38,8 @@ BrowserAccessControlDialog::~BrowserAccessControlDialog()
void BrowserAccessControlDialog::setUrl(const QString& url) void BrowserAccessControlDialog::setUrl(const QString& url)
{ {
ui->label->setText(QString(tr("%1 has requested access to passwords for the following item(s).\n" 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) void BrowserAccessControlDialog::setItems(const QList<Entry*>& items)

5
src/browser/BrowserAccessControlDialog.h Executable file → Normal file
View File

@ -24,8 +24,9 @@
class Entry; class Entry;
namespace Ui { namespace Ui
class BrowserAccessControlDialog; {
class BrowserAccessControlDialog;
} }
class BrowserAccessControlDialog : public QDialog class BrowserAccessControlDialog : public QDialog

74
src/browser/BrowserAction.cpp Executable file → Normal file
View File

@ -16,21 +16,20 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <QJsonDocument>
#include <QJsonParseError>
#include "BrowserAction.h" #include "BrowserAction.h"
#include "BrowserSettings.h" #include "BrowserSettings.h"
#include "config-keepassx.h"
#include "sodium.h" #include "sodium.h"
#include "sodium/crypto_box.h" #include "sodium/crypto_box.h"
#include "sodium/randombytes.h" #include "sodium/randombytes.h"
#include "config-keepassx.h" #include <QJsonDocument>
#include <QJsonParseError>
BrowserAction::BrowserAction(BrowserService& browserService) : BrowserAction::BrowserAction(BrowserService& browserService)
m_mutex(QMutex::Recursive), : m_mutex(QMutex::Recursive)
m_browserService(browserService), , m_browserService(browserService)
m_associated(false) , m_associated(false)
{ {
} }
QJsonObject BrowserAction::readResponse(const QJsonObject& json) QJsonObject BrowserAction::readResponse(const QJsonObject& json)
@ -62,7 +61,6 @@ QJsonObject BrowserAction::readResponse(const QJsonObject& json)
return handleAction(json); return handleAction(json);
} }
// Private functions // Private functions
/////////////////////// ///////////////////////
@ -270,7 +268,7 @@ QJsonObject BrowserAction::handleGeneratePassword(const QJsonObject& json, const
QJsonArray arr; QJsonArray arr;
QJsonObject passwd; QJsonObject passwd;
passwd["login"] = QString::number(password.length() * 8); //bits; passwd["login"] = QString::number(password.length() * 8); // bits;
passwd["password"] = password; passwd["password"] = password;
arr.append(passwd); arr.append(passwd);
@ -386,31 +384,49 @@ QJsonObject BrowserAction::buildResponse(const QString& action, const QJsonObjec
QString BrowserAction::getErrorMessage(const int errorCode) const QString BrowserAction::getErrorMessage(const int errorCode) const
{ {
switch (errorCode) { switch (errorCode) {
case ERROR_KEEPASS_DATABASE_NOT_OPENED: return QObject::tr("Database not opened"); case ERROR_KEEPASS_DATABASE_NOT_OPENED:
case ERROR_KEEPASS_DATABASE_HASH_NOT_RECEIVED: return QObject::tr("Database hash not available"); return QObject::tr("Database not opened");
case ERROR_KEEPASS_CLIENT_PUBLIC_KEY_NOT_RECEIVED: return QObject::tr("Client public key not received"); case ERROR_KEEPASS_DATABASE_HASH_NOT_RECEIVED:
case ERROR_KEEPASS_CANNOT_DECRYPT_MESSAGE: return QObject::tr("Cannot decrypt message"); return QObject::tr("Database hash not available");
case ERROR_KEEPASS_TIMEOUT_OR_NOT_CONNECTED: return QObject::tr("Timeout or cannot connect to KeePassXC"); case ERROR_KEEPASS_CLIENT_PUBLIC_KEY_NOT_RECEIVED:
case ERROR_KEEPASS_ACTION_CANCELLED_OR_DENIED: return QObject::tr("Action cancelled or denied"); return QObject::tr("Client public key not received");
case ERROR_KEEPASS_CANNOT_ENCRYPT_MESSAGE: return QObject::tr("Cannot encrypt message or public key not found. Is Native Messaging enabled in KeePassXC?"); case ERROR_KEEPASS_CANNOT_DECRYPT_MESSAGE:
case ERROR_KEEPASS_ASSOCIATION_FAILED: return QObject::tr("KeePassXC association failed, try again"); return QObject::tr("Cannot decrypt message");
case ERROR_KEEPASS_KEY_CHANGE_FAILED: return QObject::tr("Key change was not successful"); case ERROR_KEEPASS_TIMEOUT_OR_NOT_CONNECTED:
case ERROR_KEEPASS_ENCRYPTION_KEY_UNRECOGNIZED: return QObject::tr("Encryption key is not recognized"); return QObject::tr("Timeout or cannot connect to KeePassXC");
case ERROR_KEEPASS_NO_SAVED_DATABASES_FOUND: return QObject::tr("No saved databases found"); case ERROR_KEEPASS_ACTION_CANCELLED_OR_DENIED:
case ERROR_KEEPASS_INCORRECT_ACTION: return QObject::tr("Incorrect action"); return QObject::tr("Action cancelled or denied");
case ERROR_KEEPASS_EMPTY_MESSAGE_RECEIVED: return QObject::tr("Empty message received"); case ERROR_KEEPASS_CANNOT_ENCRYPT_MESSAGE:
case ERROR_KEEPASS_NO_URL_PROVIDED: return QObject::tr("No URL provided"); return QObject::tr("Cannot encrypt message or public key not found. Is Native Messaging enabled in KeePassXC?");
case ERROR_KEEPASS_NO_LOGINS_FOUND: return QObject::tr("No logins found"); case ERROR_KEEPASS_ASSOCIATION_FAILED:
default: return QObject::tr("Unknown error"); return QObject::tr("KeePassXC association failed, try again");
case ERROR_KEEPASS_KEY_CHANGE_FAILED:
return QObject::tr("Key change was not successful");
case ERROR_KEEPASS_ENCRYPTION_KEY_UNRECOGNIZED:
return QObject::tr("Encryption key is not recognized");
case ERROR_KEEPASS_NO_SAVED_DATABASES_FOUND:
return QObject::tr("No saved databases found");
case ERROR_KEEPASS_INCORRECT_ACTION:
return QObject::tr("Incorrect action");
case ERROR_KEEPASS_EMPTY_MESSAGE_RECEIVED:
return QObject::tr("Empty message received");
case ERROR_KEEPASS_NO_URL_PROVIDED:
return QObject::tr("No URL provided");
case ERROR_KEEPASS_NO_LOGINS_FOUND:
return QObject::tr("No logins found");
default:
return QObject::tr("Unknown error");
} }
} }
QString BrowserAction::getDatabaseHash() QString BrowserAction::getDatabaseHash()
{ {
QMutexLocker locker(&m_mutex); QMutexLocker locker(&m_mutex);
QByteArray hash = QCryptographicHash::hash( QByteArray hash =
QCryptographicHash::hash(
(m_browserService.getDatabaseRootUuid() + m_browserService.getDatabaseRecycleBinUuid()).toUtf8(), (m_browserService.getDatabaseRootUuid() + m_browserService.getDatabaseRecycleBinUuid()).toUtf8(),
QCryptographicHash::Sha256).toHex(); QCryptographicHash::Sha256)
.toHex();
return QString(hash); return QString(hash);
} }
@ -491,7 +507,7 @@ QByteArray BrowserAction::decrypt(const QString encrypted, const QString nonce)
} }
if (crypto_box_open_easy(d.data(), m.data(), ma.length(), n.data(), ck.data(), sk.data()) == 0) { if (crypto_box_open_easy(d.data(), m.data(), ma.length(), n.data(), ck.data(), sk.data()) == 0) {
return getQByteArray(d.data(), std::char_traits<char>::length(reinterpret_cast<const char *>(d.data()))); return getQByteArray(d.data(), std::char_traits<char>::length(reinterpret_cast<const char*>(d.data())));
} }
return QByteArray(); return QByteArray();

9
src/browser/BrowserAction.h Executable file → Normal file
View File

@ -19,17 +19,18 @@
#ifndef BROWSERACTION_H #ifndef BROWSERACTION_H
#define BROWSERACTION_H #define BROWSERACTION_H
#include <QtCore> #include "BrowserService.h"
#include <QObject>
#include <QJsonObject> #include <QJsonObject>
#include <QMutex> #include <QMutex>
#include "BrowserService.h" #include <QObject>
#include <QtCore>
class BrowserAction : public QObject class BrowserAction : public QObject
{ {
Q_OBJECT Q_OBJECT
enum { enum
{
ERROR_KEEPASS_DATABASE_NOT_OPENED = 1, ERROR_KEEPASS_DATABASE_NOT_OPENED = 1,
ERROR_KEEPASS_DATABASE_HASH_NOT_RECEIVED = 2, ERROR_KEEPASS_DATABASE_HASH_NOT_RECEIVED = 2,
ERROR_KEEPASS_CLIENT_PUBLIC_KEY_NOT_RECEIVED = 3, ERROR_KEEPASS_CLIENT_PUBLIC_KEY_NOT_RECEIVED = 3,

12
src/browser/BrowserClients.cpp Executable file → Normal file
View File

@ -16,13 +16,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <QJsonValue>
#include <QJsonParseError>
#include "BrowserClients.h" #include "BrowserClients.h"
#include <QJsonParseError>
#include <QJsonValue>
BrowserClients::BrowserClients(BrowserService& browserService) : BrowserClients::BrowserClients(BrowserService& browserService)
m_mutex(QMutex::Recursive), : m_mutex(QMutex::Recursive)
m_browserService(browserService) , m_browserService(browserService)
{ {
m_clients.reserve(1000); m_clients.reserve(1000);
} }
@ -63,7 +63,7 @@ QString BrowserClients::getClientID(const QJsonObject& json) const
BrowserClients::ClientPtr BrowserClients::getClient(const QString& clientID) BrowserClients::ClientPtr BrowserClients::getClient(const QString& clientID)
{ {
QMutexLocker locker(&m_mutex); QMutexLocker locker(&m_mutex);
for (const auto &i : m_clients) { for (const auto& i : m_clients) {
if (i->clientID.compare(clientID, Qt::CaseSensitive) == 0) { if (i->clientID.compare(clientID, Qt::CaseSensitive) == 0) {
return i; return i;
} }

19
src/browser/BrowserClients.h Executable file → Normal file
View File

@ -19,17 +19,22 @@
#ifndef BROWSERCLIENTS_H #ifndef BROWSERCLIENTS_H
#define BROWSERCLIENTS_H #define BROWSERCLIENTS_H
#include <QJsonObject>
#include <QMutex>
#include <QVector>
#include <QSharedPointer>
#include <QLocalSocket>
#include "BrowserAction.h" #include "BrowserAction.h"
#include <QJsonObject>
#include <QLocalSocket>
#include <QMutex>
#include <QSharedPointer>
#include <QVector>
class BrowserClients class BrowserClients
{ {
struct Client { struct Client
Client(const QString& id, QSharedPointer<BrowserAction> ba) : clientID(id), browserAction(ba) {} {
Client(const QString& id, QSharedPointer<BrowserAction> ba)
: clientID(id)
, browserAction(ba)
{
}
QString clientID; QString clientID;
QSharedPointer<BrowserAction> browserAction; QSharedPointer<BrowserAction> browserAction;
}; };

View File

@ -17,15 +17,14 @@
*/ */
#include "BrowserEntryConfig.h" #include "BrowserEntryConfig.h"
#include <QtCore>
#include "core/Entry.h" #include "core/Entry.h"
#include "core/EntryAttributes.h" #include "core/EntryAttributes.h"
#include <QtCore>
static const char KEEPASSBROWSER_NAME[] = "KeePassXC-Browser Settings"; static const char KEEPASSBROWSER_NAME[] = "KeePassXC-Browser Settings";
BrowserEntryConfig::BrowserEntryConfig(QObject* parent)
BrowserEntryConfig::BrowserEntryConfig(QObject* parent) : : QObject(parent)
QObject(parent)
{ {
} }

View File

@ -19,11 +19,11 @@
#ifndef BROWSERENTRYCONFIG_H #ifndef BROWSERENTRYCONFIG_H
#define BROWSERENTRYCONFIG_H #define BROWSERENTRYCONFIG_H
#include "Variant.h"
#include <QtCore/QObject> #include <QtCore/QObject>
#include <QtCore/QSet>
#include <QtCore/QString> #include <QtCore/QString>
#include <QtCore/QStringList> #include <QtCore/QStringList>
#include <QtCore/QSet>
#include "Variant.h"
class Entry; class Entry;
@ -31,8 +31,8 @@ class BrowserEntryConfig : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(QStringList Allow READ allowedHosts WRITE setAllowedHosts) Q_PROPERTY(QStringList Allow READ allowedHosts WRITE setAllowedHosts)
Q_PROPERTY(QStringList Deny READ deniedHosts WRITE setDeniedHosts ) Q_PROPERTY(QStringList Deny READ deniedHosts WRITE setDeniedHosts)
Q_PROPERTY(QString Realm READ realm WRITE setRealm ) Q_PROPERTY(QString Realm READ realm WRITE setRealm)
public: public:
BrowserEntryConfig(QObject* object = 0); BrowserEntryConfig(QObject* object = 0);

21
src/browser/BrowserOptionDialog.cpp Executable file → Normal file
View File

@ -18,23 +18,24 @@
*/ */
#include "BrowserOptionDialog.h" #include "BrowserOptionDialog.h"
#include "ui_BrowserOptionDialog.h"
#include "config-keepassx.h"
#include "BrowserSettings.h" #include "BrowserSettings.h"
#include "config-keepassx.h"
#include "core/FilePath.h" #include "core/FilePath.h"
#include "ui_BrowserOptionDialog.h"
#include <QMessageBox>
#include <QFileDialog> #include <QFileDialog>
#include <QMessageBox>
BrowserOptionDialog::BrowserOptionDialog(QWidget* parent) : BrowserOptionDialog::BrowserOptionDialog(QWidget* parent)
QWidget(parent), : QWidget(parent)
m_ui(new Ui::BrowserOptionDialog()) , m_ui(new Ui::BrowserOptionDialog())
{ {
m_ui->setupUi(this); m_ui->setupUi(this);
connect(m_ui->removeSharedEncryptionKeys, SIGNAL(clicked()), this, SIGNAL(removeSharedEncryptionKeys())); connect(m_ui->removeSharedEncryptionKeys, SIGNAL(clicked()), this, SIGNAL(removeSharedEncryptionKeys()));
connect(m_ui->removeStoredPermissions, SIGNAL(clicked()), this, SIGNAL(removeStoredPermissions())); connect(m_ui->removeStoredPermissions, SIGNAL(clicked()), this, SIGNAL(removeStoredPermissions()));
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->setCloseButtonVisible(false);
m_ui->warningWidget->setAutoHideTimeout(-1); m_ui->warningWidget->setAutoHideTimeout(-1);
@ -95,7 +96,8 @@ void BrowserOptionDialog::loadSettings()
m_ui->enableBrowserSupport->setChecked(false); m_ui->enableBrowserSupport->setChecked(false);
m_ui->enableBrowserSupport->setEnabled(false); m_ui->enableBrowserSupport->setEnabled(false);
m_ui->browserGlobalWarningWidget->showMessage( m_ui->browserGlobalWarningWidget->showMessage(
tr("We're sorry, but KeePassXC-Browser is not supported for Snap releases at the moment."), MessageWidget::Warning); tr("We're sorry, but KeePassXC-Browser is not supported for Snap releases at the moment."),
MessageWidget::Warning);
m_ui->browserGlobalWarningWidget->setCloseButtonVisible(false); m_ui->browserGlobalWarningWidget->setCloseButtonVisible(false);
m_ui->browserGlobalWarningWidget->setAutoHideTimeout(-1); m_ui->browserGlobalWarningWidget->setAutoHideTimeout(-1);
#endif #endif
@ -134,7 +136,8 @@ void BrowserOptionDialog::showProxyLocationFileDialog()
#else #else
QString fileTypeFilter(QString("%1 (*)").arg(tr("Executable Files"))); QString fileTypeFilter(QString("%1 (*)").arg(tr("Executable Files")));
#endif #endif
auto proxyLocation = QFileDialog::getOpenFileName(this, tr("Select custom proxy location"), auto proxyLocation = QFileDialog::getOpenFileName(this,
tr("Select custom proxy location"),
QFileInfo(QCoreApplication::applicationDirPath()).filePath(), QFileInfo(QCoreApplication::applicationDirPath()).filePath(),
fileTypeFilter); fileTypeFilter);
m_ui->customProxyLocation->setText(proxyLocation); m_ui->customProxyLocation->setText(proxyLocation);

7
src/browser/BrowserOptionDialog.h Executable file → Normal file
View File

@ -20,11 +20,12 @@
#ifndef BROWSEROPTIONDIALOG_H #ifndef BROWSEROPTIONDIALOG_H
#define BROWSEROPTIONDIALOG_H #define BROWSEROPTIONDIALOG_H
#include <QWidget>
#include <QScopedPointer> #include <QScopedPointer>
#include <QWidget>
namespace Ui { namespace Ui
class BrowserOptionDialog; {
class BrowserOptionDialog;
} }
class BrowserOptionDialog : public QWidget class BrowserOptionDialog : public QWidget

View File

@ -17,41 +17,43 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <QJsonArray>
#include <QInputDialog>
#include <QProgressDialog>
#include <QMessageBox>
#include "BrowserService.h" #include "BrowserService.h"
#include "BrowserSettings.h"
#include "BrowserEntryConfig.h"
#include "BrowserAccessControlDialog.h" #include "BrowserAccessControlDialog.h"
#include "BrowserEntryConfig.h"
#include "BrowserSettings.h"
#include "core/Database.h" #include "core/Database.h"
#include "core/Group.h"
#include "core/EntrySearcher.h" #include "core/EntrySearcher.h"
#include "core/Group.h"
#include "core/Metadata.h" #include "core/Metadata.h"
#include "core/Uuid.h"
#include "core/PasswordGenerator.h" #include "core/PasswordGenerator.h"
#include "core/Uuid.h"
#include "gui/MainWindow.h" #include "gui/MainWindow.h"
#include <QInputDialog>
#include <QJsonArray>
#include <QMessageBox>
#include <QProgressDialog>
// de887cc3-0363-43b8-974b-5911b8816224 // de887cc3-0363-43b8-974b-5911b8816224
static const unsigned char KEEPASSXCBROWSER_UUID_DATA[] = { static const unsigned char KEEPASSXCBROWSER_UUID_DATA[] =
0xde, 0x88, 0x7c, 0xc3, 0x03, 0x63, 0x43, 0xb8, {0xde, 0x88, 0x7c, 0xc3, 0x03, 0x63, 0x43, 0xb8, 0x97, 0x4b, 0x59, 0x11, 0xb8, 0x81, 0x62, 0x24};
0x97, 0x4b, 0x59, 0x11, 0xb8, 0x81, 0x62, 0x24 static const Uuid KEEPASSXCBROWSER_UUID =
}; Uuid(QByteArray::fromRawData(reinterpret_cast<const char*>(KEEPASSXCBROWSER_UUID_DATA),
static const Uuid KEEPASSXCBROWSER_UUID = Uuid(QByteArray::fromRawData(reinterpret_cast<const char *>(KEEPASSXCBROWSER_UUID_DATA), sizeof(KEEPASSXCBROWSER_UUID_DATA))); sizeof(KEEPASSXCBROWSER_UUID_DATA)));
static const char KEEPASSXCBROWSER_NAME[] = "KeePassXC-Browser Settings"; static const char KEEPASSXCBROWSER_NAME[] = "KeePassXC-Browser Settings";
static const char ASSOCIATE_KEY_PREFIX[] = "Public Key: "; static const char ASSOCIATE_KEY_PREFIX[] = "Public Key: ";
static const char KEEPASSXCBROWSER_GROUP_NAME[] = "KeePassXC-Browser Passwords"; static const char KEEPASSXCBROWSER_GROUP_NAME[] = "KeePassXC-Browser Passwords";
static int KEEPASSXCBROWSER_DEFAULT_ICON = 1; static int KEEPASSXCBROWSER_DEFAULT_ICON = 1;
BrowserService::BrowserService(DatabaseTabWidget* parent) : BrowserService::BrowserService(DatabaseTabWidget* parent)
m_dbTabWidget(parent), : m_dbTabWidget(parent)
m_dialogActive(false) , m_dialogActive(false)
{ {
connect(m_dbTabWidget, SIGNAL(databaseLocked(DatabaseWidget*)), this, SLOT(databaseLocked(DatabaseWidget*))); 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, SLOT(activateDatabaseChanged(DatabaseWidget*))); connect(m_dbTabWidget,
SIGNAL(activateDatabaseChanged(DatabaseWidget*)),
this,
SLOT(activateDatabaseChanged(DatabaseWidget*)));
} }
bool BrowserService::isDatabaseOpened() const bool BrowserService::isDatabaseOpened() const
@ -62,7 +64,6 @@ bool BrowserService::isDatabaseOpened() const
} }
return dbWidget->currentMode() == DatabaseWidget::ViewMode || dbWidget->currentMode() == DatabaseWidget::EditMode; return dbWidget->currentMode() == DatabaseWidget::ViewMode || dbWidget->currentMode() == DatabaseWidget::EditMode;
} }
bool BrowserService::openDatabase(bool triggerUnlock) bool BrowserService::openDatabase(bool triggerUnlock)
@ -167,9 +168,8 @@ QString BrowserService::storeKey(const QString& key)
QString id; QString id;
if (thread() != QThread::currentThread()) { if (thread() != QThread::currentThread()) {
QMetaObject::invokeMethod(this, "storeKey", Qt::BlockingQueuedConnection, QMetaObject::invokeMethod(
Q_RETURN_ARG(QString, id), this, "storeKey", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QString, id), Q_ARG(const QString&, key));
Q_ARG(const QString&, key));
return id; return id;
} }
@ -202,7 +202,8 @@ QString BrowserService::storeKey(const QString& key)
contains = config->attributes()->contains(QLatin1String(ASSOCIATE_KEY_PREFIX) + id); contains = config->attributes()->contains(QLatin1String(ASSOCIATE_KEY_PREFIX) + id);
if (contains) { if (contains) {
dialogResult = QMessageBox::warning(nullptr, tr("KeePassXC: Overwrite existing key?"), dialogResult = QMessageBox::warning(nullptr,
tr("KeePassXC: Overwrite existing key?"),
tr("A shared encryption key with the name \"%1\" " tr("A shared encryption key with the name \"%1\" "
"already exists.\nDo you want to overwrite it?") "already exists.\nDo you want to overwrite it?")
.arg(id), .arg(id),
@ -224,11 +225,16 @@ QString BrowserService::getKey(const QString& id)
return config->attributes()->value(QLatin1String(ASSOCIATE_KEY_PREFIX) + id); return config->attributes()->value(QLatin1String(ASSOCIATE_KEY_PREFIX) + id);
} }
QJsonArray BrowserService::findMatchingEntries(const QString& id, const QString& url, const QString& submitUrl, const QString& realm) QJsonArray BrowserService::findMatchingEntries(const QString& id,
const QString& url,
const QString& submitUrl,
const QString& realm)
{ {
QJsonArray result; QJsonArray result;
if (thread() != QThread::currentThread()) { if (thread() != QThread::currentThread()) {
QMetaObject::invokeMethod(this, "findMatchingEntries", Qt::BlockingQueuedConnection, QMetaObject::invokeMethod(this,
"findMatchingEntries",
Qt::BlockingQueuedConnection,
Q_RETURN_ARG(QJsonArray, result), Q_RETURN_ARG(QJsonArray, result),
Q_ARG(const QString&, id), Q_ARG(const QString&, id),
Q_ARG(const QString&, url), Q_ARG(const QString&, url),
@ -283,7 +289,12 @@ QJsonArray BrowserService::findMatchingEntries(const QString& id, const QString&
return result; return result;
} }
void BrowserService::addEntry(const QString&, const QString& login, const QString& password, const QString& url, const QString& submitUrl, const QString& realm) void BrowserService::addEntry(const QString&,
const QString& login,
const QString& password,
const QString& url,
const QString& submitUrl,
const QString& realm)
{ {
Group* group = findCreateAddEntryGroup(); Group* group = findCreateAddEntryGroup();
if (!group) { if (!group) {
@ -313,10 +324,16 @@ void BrowserService::addEntry(const QString&, const QString& login, const QStrin
config.save(entry); config.save(entry);
} }
void BrowserService::updateEntry(const QString& id, const QString& uuid, const QString& login, const QString& password, const QString& url) void BrowserService::updateEntry(const QString& id,
const QString& uuid,
const QString& login,
const QString& password,
const QString& url)
{ {
if (thread() != QThread::currentThread()) { if (thread() != QThread::currentThread()) {
QMetaObject::invokeMethod(this, "updateEntry", Qt::BlockingQueuedConnection, QMetaObject::invokeMethod(this,
"updateEntry",
Qt::BlockingQueuedConnection,
Q_ARG(const QString&, id), Q_ARG(const QString&, id),
Q_ARG(const QString&, uuid), Q_ARG(const QString&, uuid),
Q_ARG(const QString&, login), Q_ARG(const QString&, login),
@ -339,13 +356,15 @@ void BrowserService::updateEntry(const QString& id, const QString& uuid, const Q
return; 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) {
QMessageBox::StandardButton dialogResult = QMessageBox::No; QMessageBox::StandardButton dialogResult = QMessageBox::No;
if (!BrowserSettings::alwaysAllowUpdate()) { if (!BrowserSettings::alwaysAllowUpdate()) {
dialogResult = QMessageBox::warning(0, tr("KeePassXC: Update Entry"), dialogResult = QMessageBox::warning(
tr("Do you want to update the information in %1 - %2?") 0,
.arg(QUrl(url).host()).arg(username), tr("KeePassXC: Update Entry"),
QMessageBox::Yes|QMessageBox::No); tr("Do you want to update the information in %1 - %2?").arg(QUrl(url).host()).arg(username),
QMessageBox::Yes | QMessageBox::No);
} }
if (BrowserSettings::alwaysAllowUpdate() || dialogResult == QMessageBox::Yes) { if (BrowserSettings::alwaysAllowUpdate() || dialogResult == QMessageBox::Yes) {
@ -370,10 +389,9 @@ QList<Entry*> BrowserService::searchEntries(Database* db, const QString& hostnam
QString url = entry->url(); QString url = entry->url();
// Filter to match hostname in Title and Url fields // Filter to match hostname in Title and Url fields
if ((!title.isEmpty() && hostname.contains(title)) if ((!title.isEmpty() && hostname.contains(title)) || (!url.isEmpty() && hostname.contains(url))
|| (!url.isEmpty() && hostname.contains(url))
|| (matchUrlScheme(title) && hostname.endsWith(QUrl(title).host())) || (matchUrlScheme(title) && hostname.endsWith(QUrl(title).host()))
|| (matchUrlScheme(url) && hostname.endsWith(QUrl(url).host())) ) { || (matchUrlScheme(url) && hostname.endsWith(QUrl(url).host()))) {
entries.append(entry); entries.append(entry);
} }
} }
@ -413,7 +431,8 @@ QList<Entry*> BrowserService::searchEntries(const QString& text)
void BrowserService::removeSharedEncryptionKeys() void BrowserService::removeSharedEncryptionKeys()
{ {
if (!isDatabaseOpened()) { if (!isDatabaseOpened()) {
QMessageBox::critical(0, tr("KeePassXC: Database locked!"), QMessageBox::critical(0,
tr("KeePassXC: Database locked!"),
tr("The active database is locked!\n" tr("The active database is locked!\n"
"Please unlock the selected database or choose another one which is unlocked."), "Please unlock the selected database or choose another one which is unlocked."),
QMessageBox::Ok); QMessageBox::Ok);
@ -422,7 +441,8 @@ void BrowserService::removeSharedEncryptionKeys()
Entry* entry = getConfigEntry(); Entry* entry = getConfigEntry();
if (!entry) { if (!entry) {
QMessageBox::information(0, tr("KeePassXC: Settings not available!"), QMessageBox::information(0,
tr("KeePassXC: Settings not available!"),
tr("The active database does not contain a settings entry."), tr("The active database does not contain a settings entry."),
QMessageBox::Ok); QMessageBox::Ok);
return; return;
@ -436,7 +456,8 @@ void BrowserService::removeSharedEncryptionKeys()
} }
if (keysToRemove.isEmpty()) { if (keysToRemove.isEmpty()) {
QMessageBox::information(0, tr("KeePassXC: No keys found"), QMessageBox::information(0,
tr("KeePassXC: No keys found"),
tr("No shared encryption keys found in KeePassXC settings."), tr("No shared encryption keys found in KeePassXC settings."),
QMessageBox::Ok); QMessageBox::Ok);
return; return;
@ -449,16 +470,17 @@ void BrowserService::removeSharedEncryptionKeys()
entry->endUpdate(); entry->endUpdate();
const int count = keysToRemove.count(); const int count = keysToRemove.count();
QMessageBox::information(0, tr("KeePassXC: Removed keys from database"), QMessageBox::information(0,
tr("KeePassXC: Removed keys from database"),
tr("Successfully removed %n encryption key(s) from KeePassXC settings.", "", count), tr("Successfully removed %n encryption key(s) from KeePassXC settings.", "", count),
QMessageBox::Ok); QMessageBox::Ok);
} }
void BrowserService::removeStoredPermissions() void BrowserService::removeStoredPermissions()
{ {
if (!isDatabaseOpened()) { if (!isDatabaseOpened()) {
QMessageBox::critical(0, tr("KeePassXC: Database locked!"), QMessageBox::critical(0,
tr("KeePassXC: Database locked!"),
tr("The active database is locked!\n" tr("The active database is locked!\n"
"Please unlock the selected database or choose another one which is unlocked."), "Please unlock the selected database or choose another one which is unlocked."),
QMessageBox::Ok); QMessageBox::Ok);
@ -492,11 +514,13 @@ void BrowserService::removeStoredPermissions()
progress.reset(); progress.reset();
if (counter > 0) { if (counter > 0) {
QMessageBox::information(0, tr("KeePassXC: Removed permissions"), QMessageBox::information(0,
tr("KeePassXC: Removed permissions"),
tr("Successfully removed permissions from %n entry(s).", "", counter), tr("Successfully removed permissions from %n entry(s).", "", counter),
QMessageBox::Ok); QMessageBox::Ok);
} else { } else {
QMessageBox::information(0, tr("KeePassXC: No entry with permissions found!"), QMessageBox::information(0,
tr("KeePassXC: No entry with permissions found!"),
tr("The active database does not contain an entry with permissions."), tr("The active database does not contain an entry with permissions."),
QMessageBox::Ok); QMessageBox::Ok);
} }
@ -510,7 +534,8 @@ QList<Entry*> BrowserService::sortEntries(QList<Entry*>& pwEntries, const QStrin
} }
const QString submitUrl = url.toString(QUrl::StripTrailingSlash); const QString submitUrl = url.toString(QUrl::StripTrailingSlash);
const QString baseSubmitUrl = url.toString(QUrl::StripTrailingSlash | QUrl::RemovePath | QUrl::RemoveQuery | QUrl::RemoveFragment); const QString baseSubmitUrl =
url.toString(QUrl::StripTrailingSlash | QUrl::RemovePath | QUrl::RemoveQuery | QUrl::RemoveFragment);
QMultiMap<int, const Entry*> priorities; QMultiMap<int, const Entry*> priorities;
for (const Entry* entry : pwEntries) { for (const Entry* entry : pwEntries) {
@ -529,7 +554,11 @@ QList<Entry*> BrowserService::sortEntries(QList<Entry*>& pwEntries, const QStrin
return pwEntries; return pwEntries;
} }
bool BrowserService::confirmEntries(QList<Entry*>& pwEntriesToConfirm, const QString& url, const QString& host, const QString& submitHost, const QString& realm) bool BrowserService::confirmEntries(QList<Entry*>& pwEntriesToConfirm,
const QString& url,
const QString& host,
const QString& submitHost,
const QString& realm)
{ {
if (pwEntriesToConfirm.isEmpty() || m_dialogActive) { if (pwEntriesToConfirm.isEmpty() || m_dialogActive) {
return false; return false;
@ -593,7 +622,8 @@ QJsonObject BrowserService::prepareEntry(const Entry* entry)
return res; return res;
} }
BrowserService::Access BrowserService::checkAccess(const Entry* entry, const QString& host, const QString& submitHost, const QString& realm) BrowserService::Access
BrowserService::checkAccess(const Entry* entry, const QString& host, const QString& submitHost, const QString& realm)
{ {
BrowserEntryConfig config; BrowserEntryConfig config;
if (!config.load(entry)) { if (!config.load(entry)) {
@ -623,7 +653,8 @@ Group* BrowserService::findCreateAddEntryGroup()
return nullptr; return nullptr;
} }
const QString groupName = QLatin1String(KEEPASSXCBROWSER_GROUP_NAME); //TODO: setting to decide where new keys are created const QString groupName =
QLatin1String(KEEPASSXCBROWSER_GROUP_NAME); // TODO: setting to decide where new keys are created
for (const Group* g : rootGroup->groupsRecursive(true)) { for (const Group* g : rootGroup->groupsRecursive(true)) {
if (g->name() == groupName) { if (g->name() == groupName) {
@ -639,14 +670,18 @@ Group* BrowserService::findCreateAddEntryGroup()
return group; return group;
} }
int BrowserService::sortPriority(const Entry* entry, const QString& host, const QString& submitUrl, const QString& baseSubmitUrl) const int BrowserService::sortPriority(const Entry* entry,
const QString& host,
const QString& submitUrl,
const QString& baseSubmitUrl) const
{ {
QUrl url(entry->url()); QUrl url(entry->url());
if (url.scheme().isEmpty()) { if (url.scheme().isEmpty()) {
url.setScheme("http"); url.setScheme("http");
} }
const QString entryURL = url.toString(QUrl::StripTrailingSlash); const QString entryURL = url.toString(QUrl::StripTrailingSlash);
const QString baseEntryURL = url.toString(QUrl::StripTrailingSlash | QUrl::RemovePath | QUrl::RemoveQuery | QUrl::RemoveFragment); const QString baseEntryURL =
url.toString(QUrl::StripTrailingSlash | QUrl::RemovePath | QUrl::RemoveQuery | QUrl::RemoveFragment);
if (submitUrl == entryURL) { if (submitUrl == entryURL) {
return 100; return 100;

View File

@ -20,12 +20,15 @@
#ifndef BROWSERSERVICE_H #ifndef BROWSERSERVICE_H
#define BROWSERSERVICE_H #define BROWSERSERVICE_H
#include <QtCore>
#include <QObject>
#include "gui/DatabaseTabWidget.h"
#include "core/Entry.h" #include "core/Entry.h"
#include "gui/DatabaseTabWidget.h"
#include <QObject>
#include <QtCore>
enum { max_length = 16*1024 }; enum
{
max_length = 16 * 1024
};
class BrowserService : public QObject class BrowserService : public QObject
{ {
@ -40,16 +43,26 @@ public:
QString getDatabaseRecycleBinUuid(); QString getDatabaseRecycleBinUuid();
Entry* getConfigEntry(bool create = false); Entry* getConfigEntry(bool create = false);
QString getKey(const QString& id); QString getKey(const QString& id);
void addEntry(const QString& id, const QString& login, const QString& password, const QString& url, const QString& submitUrl, const QString& realm); void addEntry(const QString& id,
const QString& login,
const QString& password,
const QString& url,
const QString& submitUrl,
const QString& realm);
QList<Entry*> searchEntries(Database* db, const QString& hostname); QList<Entry*> searchEntries(Database* db, const QString& hostname);
QList<Entry*> searchEntries(const QString& text); QList<Entry*> searchEntries(const QString& text);
void removeSharedEncryptionKeys(); void removeSharedEncryptionKeys();
void removeStoredPermissions(); void removeStoredPermissions();
public slots: public slots:
QJsonArray findMatchingEntries(const QString& id, const QString& url, const QString& submitUrl, const QString& realm); QJsonArray
findMatchingEntries(const QString& id, const QString& url, const QString& submitUrl, const QString& realm);
QString storeKey(const QString& key); QString storeKey(const QString& key);
void updateEntry(const QString& id, const QString& uuid, const QString& login, const QString& password, const QString& url); void updateEntry(const QString& id,
const QString& uuid,
const QString& login,
const QString& password,
const QString& url);
void databaseLocked(DatabaseWidget* dbWidget); void databaseLocked(DatabaseWidget* dbWidget);
void databaseUnlocked(DatabaseWidget* dbWidget); void databaseUnlocked(DatabaseWidget* dbWidget);
void activateDatabaseChanged(DatabaseWidget* dbWidget); void activateDatabaseChanged(DatabaseWidget* dbWidget);
@ -61,15 +74,25 @@ signals:
void databaseChanged(); void databaseChanged();
private: private:
enum Access { Denied, Unknown, Allowed}; enum Access
{
Denied,
Unknown,
Allowed
};
private: private:
QList<Entry*> sortEntries(QList<Entry*>& pwEntries, const QString& host, const QString& submitUrl); QList<Entry*> sortEntries(QList<Entry*>& pwEntries, const QString& host, const QString& submitUrl);
bool confirmEntries(QList<Entry*>& pwEntriesToConfirm, const QString& url, const QString& host, const QString& submitHost, const QString& realm); bool confirmEntries(QList<Entry*>& pwEntriesToConfirm,
const QString& url,
const QString& host,
const QString& submitHost,
const QString& realm);
QJsonObject prepareEntry(const Entry* entry); QJsonObject prepareEntry(const Entry* entry);
Access checkAccess(const Entry* entry, const QString& host, const QString& submitHost, const QString& realm); Access checkAccess(const Entry* entry, const QString& host, const QString& submitHost, const QString& realm);
Group* findCreateAddEntryGroup(); Group* findCreateAddEntryGroup();
int sortPriority(const Entry* entry, const QString &host, const QString& submitUrl, const QString& baseSubmitUrl) const; int
sortPriority(const Entry* entry, const QString& host, const QString& submitUrl, const QString& baseSubmitUrl) const;
bool matchUrlScheme(const QString& url); bool matchUrlScheme(const QString& url);
bool removeFirstDomain(QString& hostname); bool removeFirstDomain(QString& hostname);
Database* getDatabase(); Database* getDatabase();

36
src/browser/BrowserSettings.cpp Executable file → Normal file
View File

@ -177,36 +177,48 @@ void BrowserSettings::setUpdateBinaryPath(bool enabled)
config()->set("Browser/UpdateBinaryPath", enabled); config()->set("Browser/UpdateBinaryPath", enabled);
} }
bool BrowserSettings::chromeSupport() { bool BrowserSettings::chromeSupport()
{
return m_hostInstaller.checkIfInstalled(HostInstaller::SupportedBrowsers::CHROME); return m_hostInstaller.checkIfInstalled(HostInstaller::SupportedBrowsers::CHROME);
} }
void BrowserSettings::setChromeSupport(bool enabled) { void BrowserSettings::setChromeSupport(bool enabled)
m_hostInstaller.installBrowser(HostInstaller::SupportedBrowsers::CHROME, enabled, supportBrowserProxy(), customProxyLocation()); {
m_hostInstaller.installBrowser(
HostInstaller::SupportedBrowsers::CHROME, enabled, supportBrowserProxy(), customProxyLocation());
} }
bool BrowserSettings::chromiumSupport() { bool BrowserSettings::chromiumSupport()
{
return m_hostInstaller.checkIfInstalled(HostInstaller::SupportedBrowsers::CHROMIUM); return m_hostInstaller.checkIfInstalled(HostInstaller::SupportedBrowsers::CHROMIUM);
} }
void BrowserSettings::setChromiumSupport(bool enabled) { void BrowserSettings::setChromiumSupport(bool enabled)
m_hostInstaller.installBrowser(HostInstaller::SupportedBrowsers::CHROMIUM, enabled, supportBrowserProxy(), customProxyLocation()); {
m_hostInstaller.installBrowser(
HostInstaller::SupportedBrowsers::CHROMIUM, enabled, supportBrowserProxy(), customProxyLocation());
} }
bool BrowserSettings::firefoxSupport() { bool BrowserSettings::firefoxSupport()
{
return m_hostInstaller.checkIfInstalled(HostInstaller::SupportedBrowsers::FIREFOX); return m_hostInstaller.checkIfInstalled(HostInstaller::SupportedBrowsers::FIREFOX);
} }
void BrowserSettings::setFirefoxSupport(bool enabled) { void BrowserSettings::setFirefoxSupport(bool enabled)
m_hostInstaller.installBrowser(HostInstaller::SupportedBrowsers::FIREFOX, enabled, supportBrowserProxy(), customProxyLocation()); {
m_hostInstaller.installBrowser(
HostInstaller::SupportedBrowsers::FIREFOX, enabled, supportBrowserProxy(), customProxyLocation());
} }
bool BrowserSettings::vivaldiSupport() { bool BrowserSettings::vivaldiSupport()
{
return m_hostInstaller.checkIfInstalled(HostInstaller::SupportedBrowsers::VIVALDI); return m_hostInstaller.checkIfInstalled(HostInstaller::SupportedBrowsers::VIVALDI);
} }
void BrowserSettings::setVivaldiSupport(bool enabled) { void BrowserSettings::setVivaldiSupport(bool enabled)
m_hostInstaller.installBrowser(HostInstaller::SupportedBrowsers::VIVALDI, enabled, supportBrowserProxy(), customProxyLocation()); {
m_hostInstaller.installBrowser(
HostInstaller::SupportedBrowsers::VIVALDI, enabled, supportBrowserProxy(), customProxyLocation());
} }
bool BrowserSettings::passwordUseNumbers() bool BrowserSettings::passwordUseNumbers()

10
src/browser/BrowserSettings.h Executable file → Normal file
View File

@ -20,9 +20,9 @@
#ifndef BROWSERSETTINGS_H #ifndef BROWSERSETTINGS_H
#define BROWSERSETTINGS_H #define BROWSERSETTINGS_H
#include "core/PasswordGenerator.h"
#include "core/PassphraseGenerator.h"
#include "HostInstaller.h" #include "HostInstaller.h"
#include "core/PassphraseGenerator.h"
#include "core/PasswordGenerator.h"
class BrowserSettings class BrowserSettings
{ {
@ -30,9 +30,9 @@ public:
static bool isEnabled(); static bool isEnabled();
static void setEnabled(bool enabled); static void setEnabled(bool enabled);
static bool showNotification(); //TODO!! static bool showNotification(); // TODO!!
static void setShowNotification(bool showNotification); static void setShowNotification(bool showNotification);
static bool bestMatchOnly(); //TODO!! static bool bestMatchOnly(); // TODO!!
static void setBestMatchOnly(bool bestMatchOnly); static void setBestMatchOnly(bool bestMatchOnly);
static bool unlockDatabase(); static bool unlockDatabase();
static void setUnlockDatabase(bool unlockDatabase); static void setUnlockDatabase(bool unlockDatabase);
@ -46,7 +46,7 @@ public:
static void setAlwaysAllowAccess(bool alwaysAllowAccess); static void setAlwaysAllowAccess(bool alwaysAllowAccess);
static bool alwaysAllowUpdate(); static bool alwaysAllowUpdate();
static void setAlwaysAllowUpdate(bool alwaysAllowUpdate); static void setAlwaysAllowUpdate(bool alwaysAllowUpdate);
static bool searchInAllDatabases();//TODO!! static bool searchInAllDatabases(); // TODO!!
static void setSearchInAllDatabases(bool searchInAllDatabases); static void setSearchInAllDatabases(bool searchInAllDatabases);
static bool supportKphFields(); static bool supportKphFields();
static void setSupportKphFields(bool supportKphFields); static void setSupportKphFields(bool supportKphFields);

View File

@ -18,43 +18,45 @@
#include "HostInstaller.h" #include "HostInstaller.h"
#include "config-keepassx.h" #include "config-keepassx.h"
#include <QCoreApplication>
#include <QDir> #include <QDir>
#include <QFile> #include <QFile>
#include <QStandardPaths>
#include <QJsonArray> #include <QJsonArray>
#include <QJsonDocument> #include <QJsonDocument>
#include <QCoreApplication>
#include <QProcessEnvironment>
#include <QMessageBox> #include <QMessageBox>
#include <QProcessEnvironment>
#include <QStandardPaths>
const QString HostInstaller::HOST_NAME = "org.keepassxc.keepassxc_browser"; const QString HostInstaller::HOST_NAME = "org.keepassxc.keepassxc_browser";
const QStringList HostInstaller::ALLOWED_ORIGINS = QStringList() const QStringList HostInstaller::ALLOWED_ORIGINS = QStringList()
<< "chrome-extension://iopaggbpplllidnfmcghoonnokmjoicf/" << "chrome-extension://iopaggbpplllidnfmcghoonnokmjoicf/"
<< "chrome-extension://oboonakemofpalcgghocfoadofidjkkk/"; << "chrome-extension://oboonakemofpalcgghocfoadofidjkkk/";
const QStringList HostInstaller::ALLOWED_EXTENSIONS = QStringList() const QStringList HostInstaller::ALLOWED_EXTENSIONS = QStringList() << "keepassxc-browser@keepassxc.org";
<< "keepassxc-browser@keepassxc.org";
#if defined(Q_OS_OSX) #if defined(Q_OS_OSX)
const QString HostInstaller::TARGET_DIR_CHROME = "/Library/Application Support/Google/Chrome/NativeMessagingHosts"; const QString HostInstaller::TARGET_DIR_CHROME = "/Library/Application Support/Google/Chrome/NativeMessagingHosts";
const QString HostInstaller::TARGET_DIR_CHROMIUM = "/Library/Application Support/Chromium/NativeMessagingHosts"; const QString HostInstaller::TARGET_DIR_CHROMIUM = "/Library/Application Support/Chromium/NativeMessagingHosts";
const QString HostInstaller::TARGET_DIR_FIREFOX = "/Library/Application Support/Mozilla/NativeMessagingHosts"; const QString HostInstaller::TARGET_DIR_FIREFOX = "/Library/Application Support/Mozilla/NativeMessagingHosts";
const QString HostInstaller::TARGET_DIR_VIVALDI = "/Library/Application Support/Vivaldi/NativeMessagingHosts"; const QString HostInstaller::TARGET_DIR_VIVALDI = "/Library/Application Support/Vivaldi/NativeMessagingHosts";
#elif defined(Q_OS_LINUX) #elif defined(Q_OS_LINUX)
const QString HostInstaller::TARGET_DIR_CHROME = "/.config/google-chrome/NativeMessagingHosts"; const QString HostInstaller::TARGET_DIR_CHROME = "/.config/google-chrome/NativeMessagingHosts";
const QString HostInstaller::TARGET_DIR_CHROMIUM = "/.config/chromium/NativeMessagingHosts"; const QString HostInstaller::TARGET_DIR_CHROMIUM = "/.config/chromium/NativeMessagingHosts";
const QString HostInstaller::TARGET_DIR_FIREFOX = "/.mozilla/native-messaging-hosts"; const QString HostInstaller::TARGET_DIR_FIREFOX = "/.mozilla/native-messaging-hosts";
const QString HostInstaller::TARGET_DIR_VIVALDI = "/.config/vivaldi/NativeMessagingHosts"; const QString HostInstaller::TARGET_DIR_VIVALDI = "/.config/vivaldi/NativeMessagingHosts";
#elif defined(Q_OS_WIN) #elif defined(Q_OS_WIN)
const QString HostInstaller::TARGET_DIR_CHROME = "HKEY_CURRENT_USER\\Software\\Google\\Chrome\\NativeMessagingHosts\\" + HostInstaller::HOST_NAME; const QString HostInstaller::TARGET_DIR_CHROME =
const QString HostInstaller::TARGET_DIR_CHROMIUM = "HKEY_CURRENT_USER\\Software\\Chromium\\NativeMessagingHosts\\" + HostInstaller::HOST_NAME; "HKEY_CURRENT_USER\\Software\\Google\\Chrome\\NativeMessagingHosts\\" + HostInstaller::HOST_NAME;
const QString HostInstaller::TARGET_DIR_FIREFOX = "HKEY_CURRENT_USER\\Software\\Mozilla\\NativeMessagingHosts\\" + HostInstaller::HOST_NAME; const QString HostInstaller::TARGET_DIR_CHROMIUM =
const QString HostInstaller::TARGET_DIR_VIVALDI = "HKEY_CURRENT_USER\\Software\\Vivaldi\\NativeMessagingHosts\\" + HostInstaller::HOST_NAME; "HKEY_CURRENT_USER\\Software\\Chromium\\NativeMessagingHosts\\" + HostInstaller::HOST_NAME;
const QString HostInstaller::TARGET_DIR_FIREFOX =
"HKEY_CURRENT_USER\\Software\\Mozilla\\NativeMessagingHosts\\" + HostInstaller::HOST_NAME;
const QString HostInstaller::TARGET_DIR_VIVALDI =
"HKEY_CURRENT_USER\\Software\\Vivaldi\\NativeMessagingHosts\\" + HostInstaller::HOST_NAME;
#endif #endif
HostInstaller::HostInstaller() HostInstaller::HostInstaller()
{ {
} }
bool HostInstaller::checkIfInstalled(SupportedBrowsers browser) bool HostInstaller::checkIfInstalled(SupportedBrowsers browser)
@ -68,33 +70,38 @@ bool HostInstaller::checkIfInstalled(SupportedBrowsers browser)
#endif #endif
} }
void HostInstaller::installBrowser(SupportedBrowsers browser, const bool& enabled, const bool& proxy, const QString& location) void HostInstaller::installBrowser(SupportedBrowsers browser,
const bool& enabled,
const bool& proxy,
const QString& location)
{ {
if (enabled) { if (enabled) {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
// Create a registry key // Create a registry key
QSettings settings(getTargetPath(browser), QSettings::NativeFormat); QSettings settings(getTargetPath(browser), QSettings::NativeFormat);
if (!registryEntryFound(settings)) { if (!registryEntryFound(settings)) {
settings.setValue("Default", getPath(browser)); settings.setValue("Default", getPath(browser));
} }
#endif #endif
// Always create the script file // Always create the script file
QJsonObject script = constructFile(browser, proxy, location); QJsonObject script = constructFile(browser, proxy, location);
if (!saveFile(browser, script)) { if (!saveFile(browser, script)) {
QMessageBox::critical(0, tr("KeePassXC: Cannot save file!"), QMessageBox::critical(0,
tr("Cannot save the native messaging script file."), QMessageBox::Ok); tr("KeePassXC: Cannot save file!"),
tr("Cannot save the native messaging script file."),
QMessageBox::Ok);
} }
} else { } else {
// Remove the script file // Remove the script file
QString fileName = getPath(browser); QString fileName = getPath(browser);
QFile::remove(fileName); QFile::remove(fileName);
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
// Remove the registry entry // Remove the registry entry
QSettings settings(getTargetPath(browser), QSettings::NativeFormat); QSettings settings(getTargetPath(browser), QSettings::NativeFormat);
if (registryEntryFound(settings)) { if (registryEntryFound(settings)) {
settings.remove("Default"); settings.remove("Default");
} }
#endif #endif
} }
} }
@ -110,22 +117,32 @@ void HostInstaller::updateBinaryPaths(const bool& proxy, const QString& location
QString HostInstaller::getTargetPath(SupportedBrowsers browser) const QString HostInstaller::getTargetPath(SupportedBrowsers browser) const
{ {
switch (browser) { switch (browser) {
case SupportedBrowsers::CHROME: return HostInstaller::TARGET_DIR_CHROME; case SupportedBrowsers::CHROME:
case SupportedBrowsers::CHROMIUM: return HostInstaller::TARGET_DIR_CHROMIUM; return HostInstaller::TARGET_DIR_CHROME;
case SupportedBrowsers::FIREFOX: return HostInstaller::TARGET_DIR_FIREFOX; case SupportedBrowsers::CHROMIUM:
case SupportedBrowsers::VIVALDI: return HostInstaller::TARGET_DIR_VIVALDI; return HostInstaller::TARGET_DIR_CHROMIUM;
default: return QString(); case SupportedBrowsers::FIREFOX:
return HostInstaller::TARGET_DIR_FIREFOX;
case SupportedBrowsers::VIVALDI:
return HostInstaller::TARGET_DIR_VIVALDI;
default:
return QString();
} }
} }
QString HostInstaller::getBrowserName(SupportedBrowsers browser) const QString HostInstaller::getBrowserName(SupportedBrowsers browser) const
{ {
switch (browser) { switch (browser) {
case SupportedBrowsers::CHROME: return "chrome"; case SupportedBrowsers::CHROME:
case SupportedBrowsers::CHROMIUM: return "chromium"; return "chrome";
case SupportedBrowsers::FIREFOX: return "firefox"; case SupportedBrowsers::CHROMIUM:
case SupportedBrowsers::VIVALDI: return "vivaldi"; return "chromium";
default: return QString(); case SupportedBrowsers::FIREFOX:
return "firefox";
case SupportedBrowsers::VIVALDI:
return "vivaldi";
default:
return QString();
} }
} }
@ -142,7 +159,7 @@ QString HostInstaller::getPath(SupportedBrowsers browser) const
} }
QString winPath = QString("%1/%2_%3.json").arg(userPath, HostInstaller::HOST_NAME, getBrowserName(browser)); QString winPath = QString("%1/%2_%3.json").arg(userPath, HostInstaller::HOST_NAME, getBrowserName(browser));
winPath.replace("/","\\"); winPath.replace("/", "\\");
return winPath; return winPath;
#else #else
QString path = getTargetPath(browser); QString path = getTargetPath(browser);
@ -184,7 +201,7 @@ QJsonObject HostInstaller::constructFile(SupportedBrowsers browser, const bool&
path = QFileInfo(QCoreApplication::applicationFilePath()).absoluteFilePath(); path = QFileInfo(QCoreApplication::applicationFilePath()).absoluteFilePath();
} }
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
path.replace("/","\\"); path.replace("/", "\\");
#endif #endif
#endif // #ifdef KEEPASSXC_DIST_APPIMAGE #endif // #ifdef KEEPASSXC_DIST_APPIMAGE

View File

@ -19,8 +19,8 @@
#ifndef HOSTINSTALLER_H #ifndef HOSTINSTALLER_H
#define HOSTINSTALLER_H #define HOSTINSTALLER_H
#include <QObject>
#include <QJsonObject> #include <QJsonObject>
#include <QObject>
#include <QSettings> #include <QSettings>
class HostInstaller : public QObject class HostInstaller : public QObject
@ -28,7 +28,8 @@ class HostInstaller : public QObject
Q_OBJECT Q_OBJECT
public: public:
enum SupportedBrowsers : int { enum SupportedBrowsers : int
{
CHROME = 0, CHROME = 0,
CHROMIUM = 1, CHROMIUM = 1,
FIREFOX = 2, FIREFOX = 2,
@ -38,7 +39,10 @@ public:
public: public:
HostInstaller(); HostInstaller();
bool checkIfInstalled(SupportedBrowsers browser); bool checkIfInstalled(SupportedBrowsers browser);
void installBrowser(SupportedBrowsers browser, const bool& enabled, const bool& proxy = false, const QString& location = ""); void installBrowser(SupportedBrowsers browser,
const bool& enabled,
const bool& proxy = false,
const QString& location = "");
void updateBinaryPaths(const bool& proxy, const QString& location = ""); void updateBinaryPaths(const bool& proxy, const QString& location = "");
private: private:

View File

@ -20,9 +20,9 @@
#include <QStandardPaths> #include <QStandardPaths>
#if defined(Q_OS_UNIX) && !defined(Q_OS_LINUX) #if defined(Q_OS_UNIX) && !defined(Q_OS_LINUX)
#include <sys/types.h>
#include <sys/event.h> #include <sys/event.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#endif #endif
@ -51,7 +51,7 @@ void NativeMessagingBase::newNativeMessage()
{ {
#if defined(Q_OS_UNIX) && !defined(Q_OS_LINUX) #if defined(Q_OS_UNIX) && !defined(Q_OS_LINUX)
struct kevent ev[1]; struct kevent ev[1];
struct timespec ts = { 5, 0 }; struct timespec ts = {5, 0};
int fd = kqueue(); int fd = kqueue();
if (fd == -1) { if (fd == -1) {
@ -123,7 +123,8 @@ void NativeMessagingBase::sendReply(const QString& reply)
if (!reply.isEmpty()) { if (!reply.isEmpty()) {
QByteArray bytes = reply.toUtf8(); QByteArray bytes = reply.toUtf8();
uint len = bytes.size(); uint len = bytes.size();
std::cout << char(((len>>0) & 0xFF)) << char(((len>>8) & 0xFF)) << char(((len>>16) & 0xFF)) << char(((len>>24) & 0xFF)); std::cout << char(((len >> 0) & 0xFF)) << char(((len >> 8) & 0xFF)) << char(((len >> 16) & 0xFF))
<< char(((len >> 24) & 0xFF));
std::cout << reply.toStdString() << std::flush; std::cout << reply.toStdString() << std::flush;
} }
} }

View File

@ -19,16 +19,16 @@
#ifndef NATIVEMESSAGINGBASE_H #ifndef NATIVEMESSAGINGBASE_H
#define NATIVEMESSAGINGBASE_H #define NATIVEMESSAGINGBASE_H
#include <QObject> #include <QAtomicInteger>
#include <QJsonObject>
#include <QJsonDocument>
#include <QFuture> #include <QFuture>
#include <QtConcurrent/QtConcurrent> #include <QJsonDocument>
#include <QMutex> #include <QJsonObject>
#include <QSocketNotifier>
#include <QLocalServer> #include <QLocalServer>
#include <QLocalSocket> #include <QLocalSocket>
#include <QAtomicInteger> #include <QMutex>
#include <QObject>
#include <QSocketNotifier>
#include <QtConcurrent/QtConcurrent>
#include <iostream> #include <iostream>
#include <unistd.h> #include <unistd.h>

22
src/browser/NativeMessagingHost.cpp Executable file → Normal file
View File

@ -16,18 +16,18 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "NativeMessagingHost.h"
#include "BrowserSettings.h"
#include "sodium.h"
#include <QMutexLocker> #include <QMutexLocker>
#include <QtNetwork> #include <QtNetwork>
#include <iostream> #include <iostream>
#include "sodium.h"
#include "NativeMessagingHost.h"
#include "BrowserSettings.h"
NativeMessagingHost::NativeMessagingHost(DatabaseTabWidget* parent) : NativeMessagingHost::NativeMessagingHost(DatabaseTabWidget* parent)
NativeMessagingBase(), : NativeMessagingBase()
m_mutex(QMutex::Recursive), , m_mutex(QMutex::Recursive)
m_browserClients(m_browserService), , m_browserClients(m_browserService)
m_browserService(parent) , m_browserService(parent)
{ {
m_localServer.reset(new QLocalServer(this)); m_localServer.reset(new QLocalServer(this));
m_localServer->setSocketOptions(QLocalServer::UserAccessOption); m_localServer->setSocketOptions(QLocalServer::UserAccessOption);
@ -61,12 +61,14 @@ void NativeMessagingHost::run()
// Update KeePassXC/keepassxc-proxy binary paths to Native Messaging scripts // Update KeePassXC/keepassxc-proxy binary paths to Native Messaging scripts
if (BrowserSettings::updateBinaryPath()) { if (BrowserSettings::updateBinaryPath()) {
BrowserSettings::updateBinaryPaths(BrowserSettings::useCustomProxy() ? BrowserSettings::customProxyLocation() : ""); BrowserSettings::updateBinaryPaths(BrowserSettings::useCustomProxy() ? BrowserSettings::customProxyLocation()
: "");
} }
m_running.store(true); m_running.store(true);
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
m_future = QtConcurrent::run(this, static_cast<void(NativeMessagingHost::*)()>(&NativeMessagingHost::readNativeMessages)); m_future =
QtConcurrent::run(this, static_cast<void (NativeMessagingHost::*)()>(&NativeMessagingHost::readNativeMessages));
#endif #endif
if (BrowserSettings::supportBrowserProxy()) { if (BrowserSettings::supportBrowserProxy()) {

2
src/browser/NativeMessagingHost.h Executable file → Normal file
View File

@ -19,9 +19,9 @@
#ifndef NATIVEMESSAGINGHOST_H #ifndef NATIVEMESSAGINGHOST_H
#define NATIVEMESSAGINGHOST_H #define NATIVEMESSAGINGHOST_H
#include "NativeMessagingBase.h"
#include "BrowserClients.h" #include "BrowserClients.h"
#include "BrowserService.h" #include "BrowserService.h"
#include "NativeMessagingBase.h"
#include "gui/DatabaseTabWidget.h" #include "gui/DatabaseTabWidget.h"
class NativeMessagingHost : public NativeMessagingBase class NativeMessagingHost : public NativeMessagingBase

View File

@ -20,6 +20,7 @@
#include <QtCore> #include <QtCore>
QVariantMap qo2qv(const QObject* object, const QStringList& ignoredProperties = QStringList(QString(QLatin1String("objectName")))); QVariantMap qo2qv(const QObject* object,
const QStringList& ignoredProperties = QStringList(QString(QLatin1String("objectName"))));
#endif // VARIANT_H #endif // VARIANT_H

View File

@ -42,7 +42,8 @@ int Diceware::execute(const QStringList& arguments)
QCommandLineParser parser; QCommandLineParser parser;
parser.setApplicationDescription(this->description); parser.setApplicationDescription(this->description);
QCommandLineOption words(QStringList() << "W" << "words", QCommandLineOption words(QStringList() << "W"
<< "words",
QObject::tr("Word count for the diceware passphrase."), QObject::tr("Word count for the diceware passphrase."),
QObject::tr("count")); QObject::tr("count"));
parser.addOption(words); parser.addOption(words);

View File

@ -115,8 +115,9 @@ int Edit::execute(const QStringList& arguments)
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (parser.value("username").isEmpty() && parser.value("url").isEmpty() && parser.value("title").isEmpty() && 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)) {
qCritical("Not changing any field for entry %s.", qPrintable(entryPath)); qCritical("Not changing any field for entry %s.", qPrintable(entryPath));
return EXIT_FAILURE; return EXIT_FAILURE;
} }

View File

@ -42,24 +42,20 @@ int Generate::execute(const QStringList& arguments)
QCommandLineParser parser; QCommandLineParser parser;
parser.setApplicationDescription(this->description); parser.setApplicationDescription(this->description);
QCommandLineOption len(QStringList() << "L" << "length", QCommandLineOption len(QStringList() << "L"
<< "length",
QObject::tr("Length of the generated password."), QObject::tr("Length of the generated password."),
QObject::tr("length")); QObject::tr("length"));
parser.addOption(len); parser.addOption(len);
QCommandLineOption lower(QStringList() << "l", QCommandLineOption lower(QStringList() << "l", QObject::tr("Use lowercase characters in the generated password."));
QObject::tr("Use lowercase characters in the generated password."));
parser.addOption(lower); parser.addOption(lower);
QCommandLineOption upper(QStringList() << "u", QCommandLineOption upper(QStringList() << "u", QObject::tr("Use uppercase characters in the generated password."));
QObject::tr("Use uppercase characters in the generated password."));
parser.addOption(upper); parser.addOption(upper);
QCommandLineOption numeric(QStringList() << "n", QCommandLineOption numeric(QStringList() << "n", QObject::tr("Use numbers in the generated password."));
QObject::tr("Use numbers in the generated password."));
parser.addOption(numeric); parser.addOption(numeric);
QCommandLineOption special(QStringList() << "s", QCommandLineOption special(QStringList() << "s", QObject::tr("Use special characters in the generated password."));
QObject::tr("Use special characters in the generated password."));
parser.addOption(special); parser.addOption(special);
QCommandLineOption extended(QStringList() << "e", QCommandLineOption extended(QStringList() << "e", QObject::tr("Use extended ASCII in the generated password."));
QObject::tr("Use extended ASCII in the generated password."));
parser.addOption(extended); parser.addOption(extended);
parser.process(arguments); parser.process(arguments);

View File

@ -49,9 +49,11 @@ int Show::execute(const QStringList& arguments)
QObject::tr("Key file of the database."), QObject::tr("Key file of the database."),
QObject::tr("path")); QObject::tr("path"));
parser.addOption(keyFile); parser.addOption(keyFile);
QCommandLineOption attributes(QStringList() << "a" QCommandLineOption attributes(
QStringList() << "a"
<< "attributes", << "attributes",
QObject::tr("Names of the attributes to show. " 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. " "This option can be specified more than once, with each attribute shown one-per-line in the given order. "
"If no attributes are specified, a summary of the default attributes is given."), "If no attributes are specified, a summary of the default attributes is given."),
QObject::tr("attribute")); QObject::tr("attribute"));

View File

@ -22,42 +22,42 @@
#include <QFutureWatcher> #include <QFutureWatcher>
#include <QtConcurrent> #include <QtConcurrent>
/** /**
* Asynchronously run computations outside the GUI thread. * Asynchronously run computations outside the GUI thread.
*/ */
namespace AsyncTask namespace AsyncTask
{ {
/** /**
* Wait for the given future without blocking the event loop. * Wait for the given future without blocking the event loop.
* *
* @param future future to wait for * @param future future to wait for
* @return async task result * @return async task result
*/ */
template<typename FunctionObject> template <typename FunctionObject>
typename std::result_of<FunctionObject()>::type waitForFuture(QFuture<typename std::result_of<FunctionObject()>::type> future) typename std::result_of<FunctionObject()>::type
{ waitForFuture(QFuture<typename std::result_of<FunctionObject()>::type> future)
{
QEventLoop loop; QEventLoop loop;
QFutureWatcher<typename std::result_of<FunctionObject()>::type> watcher; QFutureWatcher<typename std::result_of<FunctionObject()>::type> watcher;
QObject::connect(&watcher, SIGNAL(finished()), &loop, SLOT(quit())); QObject::connect(&watcher, SIGNAL(finished()), &loop, SLOT(quit()));
watcher.setFuture(future); watcher.setFuture(future);
loop.exec(); loop.exec();
return future.result(); return future.result();
} }
/** /**
* Run a given task and wait for it to finish without blocking the event loop. * Run a given task and wait for it to finish without blocking the event loop.
* *
* @param task std::function object to run * @param task std::function object to run
* @return async task result * @return async task result
*/ */
template<typename FunctionObject> template <typename FunctionObject>
typename std::result_of<FunctionObject()>::type runAndWaitForFuture(FunctionObject task) typename std::result_of<FunctionObject()>::type runAndWaitForFuture(FunctionObject task)
{ {
return waitForFuture<FunctionObject>(QtConcurrent::run(task)); return waitForFuture<FunctionObject>(QtConcurrent::run(task));
} }
}; // namespace AsyncTask }; // namespace AsyncTask
#endif //KEEPASSXC_ASYNCTASK_HPP #endif // KEEPASSXC_ASYNCTASK_HPP

View File

@ -27,7 +27,6 @@ bool AutoTypeAssociations::Association::operator!=(const AutoTypeAssociations::A
return window != other.window || sequence != other.sequence; return window != other.window || sequence != other.sequence;
} }
AutoTypeAssociations::AutoTypeAssociations(QObject* parent) AutoTypeAssociations::AutoTypeAssociations(QObject* parent)
: QObject(parent) : QObject(parent)
{ {
@ -106,7 +105,7 @@ int AutoTypeAssociations::size() const
int AutoTypeAssociations::associationsSize() const int AutoTypeAssociations::associationsSize() const
{ {
int size = 0; int size = 0;
for (const Association &association : m_associations) { for (const Association& association : m_associations) {
size += association.sequence.toUtf8().size() + association.window.toUtf8().size(); size += association.sequence.toUtf8().size() + association.window.toUtf8().size();
} }
return size; return size;

View File

@ -19,14 +19,16 @@
#include "AutoTypeMatch.h" #include "AutoTypeMatch.h"
AutoTypeMatch::AutoTypeMatch() AutoTypeMatch::AutoTypeMatch()
: entry(nullptr), : entry(nullptr)
sequence() , sequence()
{} {
}
AutoTypeMatch::AutoTypeMatch(Entry* entry, QString sequence) AutoTypeMatch::AutoTypeMatch(Entry* entry, QString sequence)
: entry(entry), : entry(entry)
sequence(sequence) , sequence(sequence)
{} {
}
bool AutoTypeMatch::operator==(const AutoTypeMatch& other) const bool AutoTypeMatch::operator==(const AutoTypeMatch& other) const
{ {

View File

@ -21,8 +21,8 @@
#include <QCoreApplication> #include <QCoreApplication>
#include <QDir> #include <QDir>
#include <QSettings> #include <QSettings>
#include <QTemporaryFile>
#include <QStandardPaths> #include <QStandardPaths>
#include <QTemporaryFile>
Config* Config::m_instance(nullptr); Config* Config::m_instance(nullptr);
@ -80,7 +80,7 @@ Config::Config(QObject* parent)
QString userPath; QString userPath;
QString homePath = QDir::homePath(); QString homePath = QDir::homePath();
#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) #if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
// we can't use QStandardPaths on X11 as it uses XDG_DATA_HOME instead of XDG_CONFIG_HOME // we can't use QStandardPaths on X11 as it uses XDG_DATA_HOME instead of XDG_CONFIG_HOME
QByteArray env = qgetenv("XDG_CONFIG_HOME"); QByteArray env = qgetenv("XDG_CONFIG_HOME");
if (env.isEmpty()) { if (env.isEmpty()) {
@ -95,17 +95,17 @@ Config::Config(QObject* parent)
} }
userPath += "/keepassxc/"; userPath += "/keepassxc/";
#else #else
userPath = QDir::fromNativeSeparators(QStandardPaths::writableLocation(QStandardPaths::DataLocation)); userPath = QDir::fromNativeSeparators(QStandardPaths::writableLocation(QStandardPaths::DataLocation));
// storageLocation() appends the application name ("/keepassxc") to the end // storageLocation() appends the application name ("/keepassxc") to the end
userPath += "/"; userPath += "/";
#endif #endif
#ifdef QT_DEBUG #ifdef QT_DEBUG
userPath += "keepassxc_debug.ini"; userPath += "keepassxc_debug.ini";
#else #else
userPath += "keepassxc.ini"; userPath += "keepassxc.ini";
#endif #endif
init(userPath); init(userPath);
} }

View File

@ -26,7 +26,7 @@ class QSettings;
class Config : public QObject class Config : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
Q_DISABLE_COPY(Config) Q_DISABLE_COPY(Config)
@ -54,7 +54,8 @@ private:
QHash<QString, QVariant> m_defaults; QHash<QString, QVariant> m_defaults;
}; };
inline Config* config() { inline Config* config()
{
return Config::instance(); return Config::instance();
} }

View File

@ -18,8 +18,8 @@
#include "CsvParser.h" #include "CsvParser.h"
#include <QTextCodec>
#include <QObject> #include <QObject>
#include <QTextCodec>
#include "core/Tools.h" #include "core/Tools.h"
@ -44,21 +44,24 @@ CsvParser::CsvParser()
m_ts.setCodec("UTF-8"); m_ts.setCodec("UTF-8");
} }
CsvParser::~CsvParser() { CsvParser::~CsvParser()
{
m_csv.close(); m_csv.close();
} }
bool CsvParser::isFileLoaded() { bool CsvParser::isFileLoaded()
{
return m_isFileLoaded; return m_isFileLoaded;
} }
bool CsvParser::reparse() { bool CsvParser::reparse()
{
reset(); reset();
return parseFile(); return parseFile();
} }
bool CsvParser::parse(QFile* device)
bool CsvParser::parse(QFile *device) { {
clear(); clear();
if (nullptr == device) { if (nullptr == device) {
appendStatusMsg(QObject::tr("NULL device"), true); appendStatusMsg(QObject::tr("NULL device"), true);
@ -69,7 +72,8 @@ bool CsvParser::parse(QFile *device) {
return parseFile(); return parseFile();
} }
bool CsvParser::readFile(QFile *device) { bool CsvParser::readFile(QFile* device)
{
if (device->isOpen()) if (device->isOpen())
device->close(); device->close();
@ -77,8 +81,7 @@ bool CsvParser::readFile(QFile *device) {
if (!Tools::readAllFromDevice(device, m_array)) { if (!Tools::readAllFromDevice(device, m_array)) {
appendStatusMsg(QObject::tr("error reading from device"), true); appendStatusMsg(QObject::tr("error reading from device"), true);
m_isFileLoaded = false; m_isFileLoaded = false;
} } else {
else {
device->close(); device->close();
m_array.replace("\r\n", "\n"); m_array.replace("\r\n", "\n");
@ -90,7 +93,8 @@ bool CsvParser::readFile(QFile *device) {
return m_isFileLoaded; return m_isFileLoaded;
} }
void CsvParser::reset() { void CsvParser::reset()
{
m_ch = 0; m_ch = 0;
m_currCol = 1; m_currCol = 1;
m_currRow = 1; m_currRow = 1;
@ -101,21 +105,23 @@ void CsvParser::reset() {
m_statusMsg = ""; m_statusMsg = "";
m_ts.seek(0); m_ts.seek(0);
m_table.clear(); m_table.clear();
//the following are users' concern :) // the following are users' concern :)
//m_comment = '#'; // m_comment = '#';
//m_backslashSyntax = false; // m_backslashSyntax = false;
//m_comment = '#'; // m_comment = '#';
//m_qualifier = '"'; // m_qualifier = '"';
//m_separator = ','; // m_separator = ',';
} }
void CsvParser::clear() { void CsvParser::clear()
{
reset(); reset();
m_isFileLoaded = false; m_isFileLoaded = false;
m_array.clear(); m_array.clear();
} }
bool CsvParser::parseFile() { bool CsvParser::parseFile()
{
parseRecord(); parseRecord();
while (!m_isEof) { while (!m_isEof) {
if (!skipEndline()) if (!skipEndline())
@ -128,7 +134,8 @@ bool CsvParser::parseFile() {
return m_isGood; return m_isGood;
} }
void CsvParser::parseRecord() { void CsvParser::parseRecord()
{
CsvRow row; CsvRow row;
if (isComment()) { if (isComment()) {
skipLine(); skipLine();
@ -151,7 +158,8 @@ void CsvParser::parseRecord() {
m_currCol++; m_currCol++;
} }
void CsvParser::parseField(CsvRow& row) { void CsvParser::parseField(CsvRow& row)
{
QString field; QString field;
peek(m_ch); peek(m_ch);
if (!isTerminator(m_ch)) { if (!isTerminator(m_ch)) {
@ -163,7 +171,8 @@ void CsvParser::parseField(CsvRow& row) {
row.push_back(field); row.push_back(field);
} }
void CsvParser::parseSimple(QString &s) { void CsvParser::parseSimple(QString& s)
{
QChar c; QChar c;
getChar(c); getChar(c);
while ((isText(c)) && (!m_isEof)) { while ((isText(c)) && (!m_isEof)) {
@ -174,16 +183,18 @@ void CsvParser::parseSimple(QString &s) {
ungetChar(); ungetChar();
} }
void CsvParser::parseQuoted(QString &s) { void CsvParser::parseQuoted(QString& s)
//read and discard initial qualifier (e.g. quote) {
// read and discard initial qualifier (e.g. quote)
getChar(m_ch); getChar(m_ch);
parseEscaped(s); parseEscaped(s);
//getChar(m_ch); // getChar(m_ch);
if (!isQualifier(m_ch)) if (!isQualifier(m_ch))
appendStatusMsg(QObject::tr("missing closing quote"), true); appendStatusMsg(QObject::tr("missing closing quote"), true);
} }
void CsvParser::parseEscaped(QString &s) { void CsvParser::parseEscaped(QString& s)
{
parseEscapedText(s); parseEscapedText(s);
while (processEscapeMark(s, m_ch)) while (processEscapeMark(s, m_ch))
parseEscapedText(s); parseEscapedText(s);
@ -191,7 +202,8 @@ void CsvParser::parseEscaped(QString &s) {
ungetChar(); ungetChar();
} }
void CsvParser::parseEscapedText(QString &s) { void CsvParser::parseEscapedText(QString& s)
{
getChar(m_ch); getChar(m_ch);
while ((!isQualifier(m_ch)) && !m_isEof) { while ((!isQualifier(m_ch)) && !m_isEof) {
s.append(m_ch); s.append(m_ch);
@ -199,19 +211,20 @@ void CsvParser::parseEscapedText(QString &s) {
} }
} }
bool CsvParser::processEscapeMark(QString &s, QChar c) { bool CsvParser::processEscapeMark(QString& s, QChar c)
{
QChar buf; QChar buf;
peek(buf); peek(buf);
QChar c2; QChar c2;
if (true == m_isBackslashSyntax) { if (true == m_isBackslashSyntax) {
//escape-character syntax, e.g. \" // escape-character syntax, e.g. \"
if (c != '\\') { if (c != '\\') {
return false; return false;
} }
//consume (and append) second qualifier // consume (and append) second qualifier
getChar(c2); getChar(c2);
if (m_isEof) { if (m_isEof) {
c2='\\'; c2 = '\\';
s.append('\\'); s.append('\\');
return false; return false;
} else { } else {
@ -219,11 +232,11 @@ bool CsvParser::processEscapeMark(QString &s, QChar c) {
return true; return true;
} }
} else { } else {
//double quote syntax, e.g. "" // double quote syntax, e.g. ""
if (!isQualifier(c)) if (!isQualifier(c))
return false; return false;
peek(c2); peek(c2);
if (!m_isEof) { //not EOF, can read one char if (!m_isEof) { // not EOF, can read one char
if (isQualifier(c2)) { if (isQualifier(c2)) {
s.append(c2); s.append(c2);
getChar(c2); getChar(c2);
@ -234,10 +247,11 @@ bool CsvParser::processEscapeMark(QString &s, QChar c) {
} }
} }
void CsvParser::fillColumns() { void CsvParser::fillColumns()
//fill shorter rows with empty placeholder columns {
// fill shorter rows with empty placeholder columns
for (int i = 0; i < m_table.size(); ++i) { for (int i = 0; i < m_table.size(); ++i) {
int gap = m_maxCols-m_table.at(i).size(); int gap = m_maxCols - m_table.at(i).size();
if (gap > 0) { if (gap > 0) {
CsvRow r = m_table.at(i); CsvRow r = m_table.at(i);
for (int j = 0; j < gap; ++j) { for (int j = 0; j < gap; ++j) {
@ -248,18 +262,20 @@ void CsvParser::fillColumns() {
} }
} }
void CsvParser::skipLine() { void CsvParser::skipLine()
{
m_ts.readLine(); m_ts.readLine();
m_ts.seek(m_ts.pos() - 1); m_ts.seek(m_ts.pos() - 1);
} }
bool CsvParser::skipEndline() { bool CsvParser::skipEndline()
{
getChar(m_ch); getChar(m_ch);
return (m_ch == '\n'); return (m_ch == '\n');
} }
void CsvParser::getChar(QChar& c)
void CsvParser::getChar(QChar& c) { {
m_isEof = m_ts.atEnd(); m_isEof = m_ts.atEnd();
if (!m_isEof) { if (!m_isEof) {
m_lastPos = m_ts.pos(); m_lastPos = m_ts.pos();
@ -267,32 +283,37 @@ void CsvParser::getChar(QChar& c) {
} }
} }
void CsvParser::ungetChar() { void CsvParser::ungetChar()
{
if (!m_ts.seek(m_lastPos)) { if (!m_ts.seek(m_lastPos)) {
qWarning("CSV Parser: unget lower bound exceeded"); qWarning("CSV Parser: unget lower bound exceeded");
m_isGood = false; m_isGood = false;
} }
} }
void CsvParser::peek(QChar& c) { void CsvParser::peek(QChar& c)
{
getChar(c); getChar(c);
if (!m_isEof) if (!m_isEof)
ungetChar(); ungetChar();
} }
bool CsvParser::isQualifier(const QChar &c) const { bool CsvParser::isQualifier(const QChar& c) const
{
if (true == m_isBackslashSyntax && (c != m_qualifier)) if (true == m_isBackslashSyntax && (c != m_qualifier))
return (c == '\\'); return (c == '\\');
else else
return (c == m_qualifier); return (c == m_qualifier);
} }
bool CsvParser::isComment() { bool CsvParser::isComment()
{
bool result = false; bool result = false;
QChar c2; QChar c2;
qint64 pos = m_ts.pos(); qint64 pos = m_ts.pos();
do getChar(c2); do
getChar(c2);
while ((isSpace(c2) || isTab(c2)) && (!m_isEof)); while ((isSpace(c2) || isTab(c2)) && (!m_isEof));
if (c2 == m_comment) if (c2 == m_comment)
@ -301,84 +322,100 @@ bool CsvParser::isComment() {
return result; return result;
} }
bool CsvParser::isText(QChar c) const { bool CsvParser::isText(QChar c) const
return !( (isCRLF(c)) || (isSeparator(c)) ); {
return !((isCRLF(c)) || (isSeparator(c)));
} }
bool CsvParser::isEmptyRow(CsvRow row) const { bool CsvParser::isEmptyRow(CsvRow row) const
{
CsvRow::const_iterator it = row.constBegin(); CsvRow::const_iterator it = row.constBegin();
for (; it != row.constEnd(); ++it) for (; it != row.constEnd(); ++it)
if ( ((*it) != "\n") && ((*it) != "") ) if (((*it) != "\n") && ((*it) != ""))
return false; return false;
return true; return true;
} }
bool CsvParser::isCRLF(const QChar &c) const { bool CsvParser::isCRLF(const QChar& c) const
{
return (c == '\n'); return (c == '\n');
} }
bool CsvParser::isSpace(const QChar &c) const { bool CsvParser::isSpace(const QChar& c) const
{
return (c == ' '); return (c == ' ');
} }
bool CsvParser::isTab(const QChar &c) const { bool CsvParser::isTab(const QChar& c) const
{
return (c == '\t'); return (c == '\t');
} }
bool CsvParser::isSeparator(const QChar &c) const { bool CsvParser::isSeparator(const QChar& c) const
{
return (c == m_separator); return (c == m_separator);
} }
bool CsvParser::isTerminator(const QChar &c) const { bool CsvParser::isTerminator(const QChar& c) const
{
return (isSeparator(c) || (c == '\n') || (c == '\r')); return (isSeparator(c) || (c == '\n') || (c == '\r'));
} }
void CsvParser::setBackslashSyntax(bool set) { void CsvParser::setBackslashSyntax(bool set)
{
m_isBackslashSyntax = set; m_isBackslashSyntax = set;
} }
void CsvParser::setComment(const QChar &c) { void CsvParser::setComment(const QChar& c)
{
m_comment = c.unicode(); m_comment = c.unicode();
} }
void CsvParser::setCodec(const QString &s) { void CsvParser::setCodec(const QString& s)
{
m_ts.setCodec(QTextCodec::codecForName(s.toLocal8Bit())); m_ts.setCodec(QTextCodec::codecForName(s.toLocal8Bit()));
} }
void CsvParser::setFieldSeparator(const QChar &c) { void CsvParser::setFieldSeparator(const QChar& c)
{
m_separator = c.unicode(); m_separator = c.unicode();
} }
void CsvParser::setTextQualifier(const QChar &c) { void CsvParser::setTextQualifier(const QChar& c)
{
m_qualifier = c.unicode(); m_qualifier = c.unicode();
} }
int CsvParser::getFileSize() const { int CsvParser::getFileSize() const
{
return m_csv.size(); return m_csv.size();
} }
const CsvTable CsvParser::getCsvTable() const { const CsvTable CsvParser::getCsvTable() const
{
return m_table; return m_table;
} }
QString CsvParser::getStatus() const { QString CsvParser::getStatus() const
{
return m_statusMsg; return m_statusMsg;
} }
int CsvParser::getCsvCols() const { int CsvParser::getCsvCols() const
{
if ((m_table.size() > 0) && (m_table.at(0).size() > 0)) if ((m_table.size() > 0) && (m_table.at(0).size() > 0))
return m_table.at(0).size(); return m_table.at(0).size();
else return 0; else
return 0;
} }
int CsvParser::getCsvRows() const { int CsvParser::getCsvRows() const
{
return m_table.size(); return m_table.size();
} }
void CsvParser::appendStatusMsg(QString s, bool isCritical)
void CsvParser::appendStatusMsg(QString s, bool isCritical) { {
m_statusMsg += QObject::tr("%1: (row, col) %2,%3") m_statusMsg += QObject::tr("%1: (row, col) %2,%3").arg(s, m_currRow, m_currCol).append("\n");
.arg(s, m_currRow, m_currCol)
.append("\n");
m_isGood = !isCritical; m_isGood = !isCritical;
} }

View File

@ -19,28 +19,29 @@
#ifndef KEEPASSX_CSVPARSER_H #ifndef KEEPASSX_CSVPARSER_H
#define KEEPASSX_CSVPARSER_H #define KEEPASSX_CSVPARSER_H
#include <QFile>
#include <QBuffer> #include <QBuffer>
#include <QFile>
#include <QQueue> #include <QQueue>
#include <QTextStream> #include <QTextStream>
typedef QStringList CsvRow; typedef QStringList CsvRow;
typedef QList<CsvRow> CsvTable; typedef QList<CsvRow> CsvTable;
class CsvParser { class CsvParser
{
public: public:
CsvParser(); CsvParser();
~CsvParser(); ~CsvParser();
//read data from device and parse it // read data from device and parse it
bool parse(QFile *device); bool parse(QFile* device);
bool isFileLoaded(); bool isFileLoaded();
//reparse the same buffer (device is not opened again) // reparse the same buffer (device is not opened again)
bool reparse(); bool reparse();
void setCodec(const QString &s); void setCodec(const QString& s);
void setComment(const QChar &c); void setComment(const QChar& c);
void setFieldSeparator(const QChar &c); void setFieldSeparator(const QChar& c);
void setTextQualifier(const QChar &c); void setTextQualifier(const QChar& c);
void setBackslashSyntax(bool set); void setBackslashSyntax(bool set);
int getFileSize() const; int getFileSize() const;
int getCsvRows() const; int getCsvRows() const;
@ -69,28 +70,28 @@ private:
QString m_statusMsg; QString m_statusMsg;
QTextStream m_ts; QTextStream m_ts;
void getChar(QChar &c); void getChar(QChar& c);
void ungetChar(); void ungetChar();
void peek(QChar &c); void peek(QChar& c);
void fillColumns(); void fillColumns();
bool isTerminator(const QChar &c) const; bool isTerminator(const QChar& c) const;
bool isSeparator(const QChar &c) const; bool isSeparator(const QChar& c) const;
bool isQualifier(const QChar &c) const; bool isQualifier(const QChar& c) const;
bool processEscapeMark(QString &s, QChar c); bool processEscapeMark(QString& s, QChar c);
bool isText(QChar c) const; bool isText(QChar c) const;
bool isComment(); bool isComment();
bool isCRLF(const QChar &c) const; bool isCRLF(const QChar& c) const;
bool isSpace(const QChar &c) const; bool isSpace(const QChar& c) const;
bool isTab(const QChar &c) const; bool isTab(const QChar& c) const;
bool isEmptyRow(CsvRow row) const; bool isEmptyRow(CsvRow row) const;
bool parseFile(); bool parseFile();
void parseRecord(); void parseRecord();
void parseField(CsvRow &row); void parseField(CsvRow& row);
void parseSimple(QString &s); void parseSimple(QString& s);
void parseQuoted(QString &s); void parseQuoted(QString& s);
void parseEscaped(QString &s); void parseEscaped(QString& s);
void parseEscapedText(QString &s); void parseEscapedText(QString& s);
bool readFile(QFile *device); bool readFile(QFile* device);
void reset(); void reset();
void clear(); void clear();
bool skipEndline(); bool skipEndline();
@ -98,5 +99,4 @@ private:
void appendStatusMsg(QString s, bool isCritical = false); void appendStatusMsg(QString s, bool isCritical = false);
}; };
#endif //CSVPARSER_H #endif // CSVPARSER_H

View File

@ -25,7 +25,7 @@
class CustomData : public QObject class CustomData : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit CustomData(QObject* parent = nullptr); explicit CustomData(QObject* parent = nullptr);
@ -45,7 +45,6 @@ public:
bool operator==(const CustomData& other) const; bool operator==(const CustomData& other) const;
bool operator!=(const CustomData& other) const; bool operator!=(const CustomData& other) const;
signals: signals:
void modified(); void modified();
void aboutToBeAdded(const QString& key); void aboutToBeAdded(const QString& key);

View File

@ -32,8 +32,8 @@
#include "format/KeePass2.h" #include "format/KeePass2.h"
#include "format/KeePass2Reader.h" #include "format/KeePass2Reader.h"
#include "format/KeePass2Writer.h" #include "format/KeePass2Writer.h"
#include "keys/PasswordKey.h"
#include "keys/FileKey.h" #include "keys/FileKey.h"
#include "keys/PasswordKey.h"
QHash<Uuid, Database*> Database::m_uuidMap; QHash<Uuid, Database*> Database::m_uuidMap;
@ -129,7 +129,8 @@ Entry* Database::findEntryRecursive(const Uuid& uuid, Group* group)
Entry* Database::findEntryRecursive(const QString& text, EntryReferenceType referenceType, Group* group) Entry* Database::findEntryRecursive(const QString& text, EntryReferenceType referenceType, Group* group)
{ {
Q_ASSERT_X(referenceType != EntryReferenceType::Unknown, "Database::findEntryRecursive", Q_ASSERT_X(referenceType != EntryReferenceType::Unknown,
"Database::findEntryRecursive",
"Can't search entry with \"referenceType\" parameter equal to \"Unknown\""); "Can't search entry with \"referenceType\" parameter equal to \"Unknown\"");
bool found = false; bool found = false;
@ -335,7 +336,6 @@ void Database::setPublicCustomData(const QVariantMap& customData)
m_data.publicCustomData = customData; m_data.publicCustomData = customData;
} }
void Database::createRecycleBin() void Database::createRecycleBin()
{ {
Group* recycleBin = Group::createRecycleBin(); Group* recycleBin = Group::createRecycleBin();
@ -407,7 +407,6 @@ void Database::setEmitModified(bool value)
m_emitModified = value; m_emitModified = value;
} }
Uuid Database::uuid() Uuid Database::uuid()
{ {
return m_uuid; return m_uuid;

View File

@ -23,8 +23,8 @@
#include <QHash> #include <QHash>
#include <QObject> #include <QObject>
#include "crypto/kdf/Kdf.h"
#include "core/Uuid.h" #include "core/Uuid.h"
#include "crypto/kdf/Kdf.h"
#include "keys/CompositeKey.h" #include "keys/CompositeKey.h"
class Entry; class Entry;
@ -101,8 +101,7 @@ public:
void setCipher(const Uuid& cipher); void setCipher(const Uuid& cipher);
void setCompressionAlgo(Database::CompressionAlgorithm algo); void setCompressionAlgo(Database::CompressionAlgorithm algo);
void setKdf(QSharedPointer<Kdf> kdf); void setKdf(QSharedPointer<Kdf> kdf);
bool setKey(const CompositeKey& key, bool updateChangedTime = true, bool setKey(const CompositeKey& key, bool updateChangedTime = true, bool updateTransformSalt = false);
bool updateTransformSalt = false);
bool hasKey() const; bool hasKey() const;
bool verifyKey(const CompositeKey& key) const; bool verifyKey(const CompositeKey& key) const;
QVariantMap& publicCustomData(); QVariantMap& publicCustomData();

View File

@ -106,8 +106,7 @@ QImage DatabaseIcons::icon(int index)
if (!m_iconCache[index].isNull()) { if (!m_iconCache[index].isNull()) {
return m_iconCache[index]; return m_iconCache[index];
} } else {
else {
QString iconPath = QString("icons/database/").append(m_indexToName[index]); QString iconPath = QString("icons/database/").append(m_indexToName[index]);
QImage icon(filePath()->dataPath(iconPath)); QImage icon(filePath()->dataPath(iconPath));

View File

@ -46,7 +46,8 @@ private:
Q_DISABLE_COPY(DatabaseIcons) Q_DISABLE_COPY(DatabaseIcons)
}; };
inline DatabaseIcons* databaseIcons() { inline DatabaseIcons* databaseIcons()
{
return DatabaseIcons::instance(); return DatabaseIcons::instance();
} }

View File

@ -20,27 +20,25 @@
#define KEEPASSX_ENDIAN_H #define KEEPASSX_ENDIAN_H
#include <QByteArray> #include <QByteArray>
#include <QIODevice>
#include <QSysInfo> #include <QSysInfo>
#include <QtEndian> #include <QtEndian>
#include <QIODevice>
namespace Endian namespace Endian
{ {
template<typename SizedQInt> template <typename SizedQInt> SizedQInt bytesToSizedInt(const QByteArray& ba, QSysInfo::Endian byteOrder)
SizedQInt bytesToSizedInt(const QByteArray& ba, QSysInfo::Endian byteOrder) {
{
Q_ASSERT(ba.size() == sizeof(SizedQInt)); Q_ASSERT(ba.size() == sizeof(SizedQInt));
if (byteOrder == QSysInfo::LittleEndian) { if (byteOrder == QSysInfo::LittleEndian) {
return qFromLittleEndian<SizedQInt>(reinterpret_cast<const uchar*>(ba.constData())); return qFromLittleEndian<SizedQInt>(reinterpret_cast<const uchar*>(ba.constData()));
} }
return qFromBigEndian<SizedQInt>(reinterpret_cast<const uchar*>(ba.constData())); return qFromBigEndian<SizedQInt>(reinterpret_cast<const uchar*>(ba.constData()));
} }
template<typename SizedQInt> template <typename SizedQInt> SizedQInt readSizedInt(QIODevice* device, QSysInfo::Endian byteOrder, bool* ok)
SizedQInt readSizedInt(QIODevice* device, QSysInfo::Endian byteOrder, bool* ok) {
{
QByteArray ba = device->read(sizeof(SizedQInt)); QByteArray ba = device->read(sizeof(SizedQInt));
if (ba.size() != sizeof(SizedQInt)) { if (ba.size() != sizeof(SizedQInt)) {
@ -49,11 +47,10 @@ SizedQInt readSizedInt(QIODevice* device, QSysInfo::Endian byteOrder, bool* ok)
} }
*ok = true; *ok = true;
return bytesToSizedInt<SizedQInt>(ba, byteOrder); return bytesToSizedInt<SizedQInt>(ba, byteOrder);
} }
template<typename SizedQInt> template <typename SizedQInt> QByteArray sizedIntToBytes(SizedQInt num, QSysInfo::Endian byteOrder)
QByteArray sizedIntToBytes(SizedQInt num, QSysInfo::Endian byteOrder) {
{
QByteArray ba; QByteArray ba;
ba.resize(sizeof(SizedQInt)); ba.resize(sizeof(SizedQInt));
@ -64,15 +61,14 @@ QByteArray sizedIntToBytes(SizedQInt num, QSysInfo::Endian byteOrder)
} }
return ba; return ba;
} }
template<typename SizedQInt> template <typename SizedQInt> bool writeSizedInt(SizedQInt num, QIODevice* device, QSysInfo::Endian byteOrder)
bool writeSizedInt(SizedQInt num, QIODevice* device, QSysInfo::Endian byteOrder) {
{
QByteArray ba = sizedIntToBytes<SizedQInt>(num, byteOrder); QByteArray ba = sizedIntToBytes<SizedQInt>(num, byteOrder);
qint64 bytesWritten = device->write(ba); qint64 bytesWritten = device->write(ba);
return (bytesWritten == ba.size()); return (bytesWritten == ba.size());
} }
} // namespace Endian } // namespace Endian

View File

@ -32,7 +32,6 @@ const int Entry::ResolveMaximumDepth = 10;
const QString Entry::AutoTypeSequenceUsername = "{USERNAME}{ENTER}"; const QString Entry::AutoTypeSequenceUsername = "{USERNAME}{ENTER}";
const QString Entry::AutoTypeSequencePassword = "{PASSWORD}{ENTER}"; const QString Entry::AutoTypeSequencePassword = "{PASSWORD}{ENTER}";
Entry::Entry() Entry::Entry()
: m_attributes(new EntryAttributes(this)) : m_attributes(new EntryAttributes(this))
, m_attachments(new EntryAttachments(this)) , m_attachments(new EntryAttachments(this))
@ -78,8 +77,7 @@ template <class T> inline bool Entry::set(T& property, const T& value)
property = value; property = value;
emit modified(); emit modified();
return true; return true;
} } else {
else {
return false; return false;
} }
} }
@ -129,14 +127,12 @@ QImage Entry::icon() const
{ {
if (m_data.customIcon.isNull()) { if (m_data.customIcon.isNull()) {
return databaseIcons()->icon(m_data.iconNumber); return databaseIcons()->icon(m_data.iconNumber);
} } else {
else {
Q_ASSERT(database()); Q_ASSERT(database());
if (database()) { if (database()) {
return database()->metadata()->customIcon(m_data.customIcon); return database()->metadata()->customIcon(m_data.customIcon);
} } else {
else {
return QImage(); return QImage();
} }
} }
@ -146,14 +142,12 @@ QPixmap Entry::iconPixmap() const
{ {
if (m_data.customIcon.isNull()) { if (m_data.customIcon.isNull()) {
return databaseIcons()->iconPixmap(m_data.iconNumber); return databaseIcons()->iconPixmap(m_data.iconNumber);
} } else {
else {
Q_ASSERT(database()); Q_ASSERT(database());
if (database()) { if (database()) {
return database()->metadata()->customIconPixmap(m_data.customIcon); return database()->metadata()->customIconPixmap(m_data.customIcon);
} } else {
else {
return QPixmap(); return QPixmap();
} }
} }
@ -164,8 +158,7 @@ QPixmap Entry::iconScaledPixmap() const
if (m_data.customIcon.isNull()) { if (m_data.customIcon.isNull()) {
// built-in icons are 16x16 so don't need to be scaled // built-in icons are 16x16 so don't need to be scaled
return databaseIcons()->iconPixmap(m_data.iconNumber); return databaseIcons()->iconPixmap(m_data.iconNumber);
} } else {
else {
Q_ASSERT(database()); Q_ASSERT(database());
return database()->metadata()->customIconScaledPixmap(m_data.customIcon); return database()->metadata()->customIconScaledPixmap(m_data.customIcon);
@ -381,7 +374,7 @@ void Entry::setTotp(const QString& seed, quint8& step, quint8& digits)
} }
QString data; QString data;
const Totp::Encoder & enc = Totp::encoders.value(digits, Totp::defaultEncoder); const Totp::Encoder& enc = Totp::encoders.value(digits, Totp::defaultEncoder);
if (m_attributes->hasKey("otp")) { if (m_attributes->hasKey("otp")) {
data = QString("key=%1&step=%2&size=%3").arg(seed).arg(step).arg(enc.digits == 0 ? digits : enc.digits); data = QString("key=%1&step=%2&size=%3").arg(seed).arg(step).arg(enc.digits == 0 ? digits : enc.digits);
@ -503,9 +496,9 @@ void Entry::setTitle(const QString& title)
void Entry::setUrl(const QString& url) void Entry::setUrl(const QString& url)
{ {
bool remove = url != m_attributes->value(EntryAttributes::URLKey) && bool remove = url != m_attributes->value(EntryAttributes::URLKey)
(m_attributes->value(EntryAttributes::RememberCmdExecAttr) == "1" || && (m_attributes->value(EntryAttributes::RememberCmdExecAttr) == "1"
m_attributes->value(EntryAttributes::RememberCmdExecAttr) == "0"); || m_attributes->value(EntryAttributes::RememberCmdExecAttr) == "0");
if (remove) { if (remove) {
m_attributes->remove(EntryAttributes::RememberCmdExecAttr); m_attributes->remove(EntryAttributes::RememberCmdExecAttr);
} }
@ -640,8 +633,7 @@ Entry* Entry::clone(CloneFlags flags) const
entry->setUpdateTimeinfo(false); entry->setUpdateTimeinfo(false);
if (flags & CloneNewUuid) { if (flags & CloneNewUuid) {
entry->m_uuid = Uuid::random(); entry->m_uuid = Uuid::random();
} } else {
else {
entry->m_uuid = m_uuid; entry->m_uuid = m_uuid;
} }
entry->m_data = m_data; entry->m_data = m_data;
@ -652,12 +644,14 @@ Entry* Entry::clone(CloneFlags flags) const
if (flags & CloneUserAsRef) { if (flags & CloneUserAsRef) {
// Build the username reference // Build the username reference
QString username = "{REF:U@I:" + m_uuid.toHex() + "}"; QString username = "{REF:U@I:" + m_uuid.toHex() + "}";
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) { if (flags & ClonePassAsRef) {
QString password = "{REF:P@I:" + m_uuid.toHex() + "}"; QString password = "{REF:P@I:" + m_uuid.toHex() + "}";
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); entry->m_autoTypeAssociations->copyDataFrom(m_autoTypeAssociations);
@ -719,8 +713,7 @@ bool Entry::endUpdate()
m_tmpHistoryItem->setUpdateTimeinfo(true); m_tmpHistoryItem->setUpdateTimeinfo(true);
addHistoryItem(m_tmpHistoryItem); addHistoryItem(m_tmpHistoryItem);
truncateHistory(); truncateHistory();
} } else {
else {
delete m_tmpHistoryItem; delete m_tmpHistoryItem;
} }
@ -959,8 +952,7 @@ const Database* Entry::database() const
{ {
if (m_group) { if (m_group) {
return m_group->database(); return m_group->database();
} } else {
else {
return nullptr; return nullptr;
} }
} }
@ -1028,26 +1020,25 @@ Entry::PlaceholderType Entry::placeholderType(const QString& placeholder) const
return PlaceholderType::Reference; return PlaceholderType::Reference;
} }
static const QMap<QString, PlaceholderType> placeholders { static const QMap<QString, PlaceholderType> placeholders{
{ QStringLiteral("{TITLE}"), PlaceholderType::Title }, {QStringLiteral("{TITLE}"), PlaceholderType::Title},
{ QStringLiteral("{USERNAME}"), PlaceholderType::UserName }, {QStringLiteral("{USERNAME}"), PlaceholderType::UserName},
{ QStringLiteral("{PASSWORD}"), PlaceholderType::Password }, {QStringLiteral("{PASSWORD}"), PlaceholderType::Password},
{ QStringLiteral("{NOTES}"), PlaceholderType::Notes }, {QStringLiteral("{NOTES}"), PlaceholderType::Notes},
{ QStringLiteral("{TOTP}"), PlaceholderType::Totp }, {QStringLiteral("{TOTP}"), PlaceholderType::Totp},
{ QStringLiteral("{URL}"), PlaceholderType::Url }, {QStringLiteral("{URL}"), PlaceholderType::Url},
{ QStringLiteral("{URL:RMVSCM}"), PlaceholderType::UrlWithoutScheme }, {QStringLiteral("{URL:RMVSCM}"), PlaceholderType::UrlWithoutScheme},
{ QStringLiteral("{URL:WITHOUTSCHEME}"), PlaceholderType::UrlWithoutScheme }, {QStringLiteral("{URL:WITHOUTSCHEME}"), PlaceholderType::UrlWithoutScheme},
{ QStringLiteral("{URL:SCM}"), PlaceholderType::UrlScheme }, {QStringLiteral("{URL:SCM}"), PlaceholderType::UrlScheme},
{ QStringLiteral("{URL:SCHEME}"), PlaceholderType::UrlScheme }, {QStringLiteral("{URL:SCHEME}"), PlaceholderType::UrlScheme},
{ QStringLiteral("{URL:HOST}"), PlaceholderType::UrlHost }, {QStringLiteral("{URL:HOST}"), PlaceholderType::UrlHost},
{ QStringLiteral("{URL:PORT}"), PlaceholderType::UrlPort }, {QStringLiteral("{URL:PORT}"), PlaceholderType::UrlPort},
{ QStringLiteral("{URL:PATH}"), PlaceholderType::UrlPath }, {QStringLiteral("{URL:PATH}"), PlaceholderType::UrlPath},
{ QStringLiteral("{URL:QUERY}"), PlaceholderType::UrlQuery }, {QStringLiteral("{URL:QUERY}"), PlaceholderType::UrlQuery},
{ QStringLiteral("{URL:FRAGMENT}"), PlaceholderType::UrlFragment }, {QStringLiteral("{URL:FRAGMENT}"), PlaceholderType::UrlFragment},
{ QStringLiteral("{URL:USERINFO}"), PlaceholderType::UrlUserInfo }, {QStringLiteral("{URL:USERINFO}"), PlaceholderType::UrlUserInfo},
{ QStringLiteral("{URL:USERNAME}"), PlaceholderType::UrlUserName }, {QStringLiteral("{URL:USERNAME}"), PlaceholderType::UrlUserName},
{ QStringLiteral("{URL:PASSWORD}"), PlaceholderType::UrlPassword } {QStringLiteral("{URL:PASSWORD}"), PlaceholderType::UrlPassword}};
};
return placeholders.value(placeholder.toUpper(), PlaceholderType::Unknown); return placeholders.value(placeholder.toUpper(), PlaceholderType::Unknown);
} }
@ -1062,7 +1053,7 @@ QString Entry::resolveUrl(const QString& url) const
if (newUrl.startsWith("cmd://")) { if (newUrl.startsWith("cmd://")) {
QStringList cmdList = newUrl.split(" "); QStringList cmdList = newUrl.split(" ");
for (int i=1; i < cmdList.size(); ++i) { for (int i = 1; i < cmdList.size(); ++i) {
// Don't pass arguments to the resolveUrl function (they look like URL's) // Don't pass arguments to the resolveUrl function (they look like URL's)
if (!cmdList[i].startsWith("-") && !cmdList[i].startsWith("/")) { if (!cmdList[i].startsWith("-") && !cmdList[i].startsWith("/")) {
return resolveUrl(cmdList[i].remove(QRegExp("'|\""))); return resolveUrl(cmdList[i].remove(QRegExp("'|\"")));

View File

@ -37,7 +37,8 @@
class Database; class Database;
class Group; class Group;
enum class EntryReferenceType { enum class EntryReferenceType
{
Unknown, Unknown,
Title, Title,
UserName, UserName,
@ -142,7 +143,8 @@ public:
void removeHistoryItems(const QList<Entry*>& historyEntries); void removeHistoryItems(const QList<Entry*>& historyEntries);
void truncateHistory(); void truncateHistory();
enum CloneFlag { enum CloneFlag
{
CloneNoFlags = 0, CloneNoFlags = 0,
CloneNewUuid = 1, // generate a random uuid for the clone CloneNewUuid = 1, // generate a random uuid for the clone
CloneResetTimeInfo = 2, // set all TimeInfo attributes to the current time CloneResetTimeInfo = 2, // set all TimeInfo attributes to the current time
@ -153,7 +155,8 @@ public:
}; };
Q_DECLARE_FLAGS(CloneFlags, CloneFlag) Q_DECLARE_FLAGS(CloneFlags, CloneFlag)
enum class PlaceholderType { enum class PlaceholderType
{
NotPlaceholder, NotPlaceholder,
Unknown, Unknown,
Title, Title,

View File

@ -17,8 +17,8 @@
#include "EntryAttachments.h" #include "EntryAttachments.h"
#include <QStringList>
#include <QSet> #include <QSet>
#include <QStringList>
EntryAttachments::EntryAttachments(QObject* parent) EntryAttachments::EntryAttachments(QObject* parent)
: QObject(parent) : QObject(parent)
@ -61,8 +61,7 @@ void EntryAttachments::set(const QString& key, const QByteArray& value)
if (addAttachment) { if (addAttachment) {
emit added(key); emit added(key);
} } else {
else {
emit keyModified(key); emit keyModified(key);
} }
@ -74,8 +73,7 @@ void EntryAttachments::set(const QString& key, const QByteArray& value)
void EntryAttachments::remove(const QString& key) void EntryAttachments::remove(const QString& key)
{ {
if (!m_attachments.contains(key)) { if (!m_attachments.contains(key)) {
Q_ASSERT_X(false, "EntryAttachments::remove", Q_ASSERT_X(false, "EntryAttachments::remove", qPrintable(QString("Can't find attachment for key %1").arg(key)));
qPrintable(QString("Can't find attachment for key %1").arg(key)));
return; return;
} }
@ -94,10 +92,10 @@ void EntryAttachments::remove(const QStringList& keys)
} }
bool isModified = false; bool isModified = false;
for (const QString &key: keys) { for (const QString& key : keys) {
if (!m_attachments.contains(key)) { if (!m_attachments.contains(key)) {
Q_ASSERT_X(false, "EntryAttachments::remove", Q_ASSERT_X(
qPrintable(QString("Can't find attachment for key %1").arg(key))); false, "EntryAttachments::remove", qPrintable(QString("Can't find attachment for key %1").arg(key)));
continue; continue;
} }

View File

@ -23,8 +23,8 @@ const QString EntryAttributes::UserNameKey = "UserName";
const QString EntryAttributes::PasswordKey = "Password"; const QString EntryAttributes::PasswordKey = "Password";
const QString EntryAttributes::URLKey = "URL"; const QString EntryAttributes::URLKey = "URL";
const QString EntryAttributes::NotesKey = "Notes"; const QString EntryAttributes::NotesKey = "Notes";
const QStringList EntryAttributes::DefaultAttributes(QStringList() << TitleKey << UserNameKey const QStringList EntryAttributes::DefaultAttributes(QStringList() << TitleKey << UserNameKey << PasswordKey << URLKey
<< PasswordKey << URLKey << NotesKey); << NotesKey);
const QString EntryAttributes::WantedFieldGroupName = "WantedField"; const QString EntryAttributes::WantedFieldGroupName = "WantedField";
const QString EntryAttributes::SearchInGroupName = "SearchIn"; const QString EntryAttributes::SearchInGroupName = "SearchIn";
@ -113,8 +113,7 @@ void EntryAttributes::set(const QString& key, const QString& value, bool protect
emitModified = true; emitModified = true;
} }
m_protectedAttributes.insert(key); m_protectedAttributes.insert(key);
} } else if (m_protectedAttributes.remove(key)) {
else if (m_protectedAttributes.remove(key)) {
emitModified = true; emitModified = true;
} }
@ -124,11 +123,9 @@ void EntryAttributes::set(const QString& key, const QString& value, bool protect
if (defaultAttribute && changeValue) { if (defaultAttribute && changeValue) {
emit defaultKeyModified(); emit defaultKeyModified();
} } else if (addAttribute) {
else if (addAttribute) {
emit added(key); emit added(key);
} } else if (emitModified) {
else if (emitModified) {
emit customKeyModified(key); emit customKeyModified(key);
} }
} }
@ -249,14 +246,12 @@ void EntryAttributes::copyDataFrom(const EntryAttributes* other)
bool EntryAttributes::operator==(const EntryAttributes& other) const bool EntryAttributes::operator==(const EntryAttributes& other) const
{ {
return (m_attributes == other.m_attributes return (m_attributes == other.m_attributes && m_protectedAttributes == other.m_protectedAttributes);
&& m_protectedAttributes == other.m_protectedAttributes);
} }
bool EntryAttributes::operator!=(const EntryAttributes& other) const bool EntryAttributes::operator!=(const EntryAttributes& other) const
{ {
return (m_attributes != other.m_attributes return (m_attributes != other.m_attributes || m_protectedAttributes != other.m_protectedAttributes);
|| m_protectedAttributes != other.m_protectedAttributes);
} }
QRegularExpressionMatch EntryAttributes::matchReference(const QString& text) QRegularExpressionMatch EntryAttributes::matchReference(const QString& text)

View File

@ -20,8 +20,7 @@
#include "core/Group.h" #include "core/Group.h"
QList<Entry*> EntrySearcher::search(const QString& searchTerm, const Group* group, QList<Entry*> EntrySearcher::search(const QString& searchTerm, const Group* group, Qt::CaseSensitivity caseSensitivity)
Qt::CaseSensitivity caseSensitivity)
{ {
if (!group->resolveSearchingEnabled()) { if (!group->resolveSearchingEnabled()) {
return QList<Entry*>(); return QList<Entry*>();
@ -30,8 +29,8 @@ QList<Entry*> EntrySearcher::search(const QString& searchTerm, const Group* grou
return searchEntries(searchTerm, group, caseSensitivity); return searchEntries(searchTerm, group, caseSensitivity);
} }
QList<Entry*> EntrySearcher::searchEntries(const QString& searchTerm, const Group* group, QList<Entry*>
Qt::CaseSensitivity caseSensitivity) EntrySearcher::searchEntries(const QString& searchTerm, const Group* group, Qt::CaseSensitivity caseSensitivity)
{ {
QList<Entry*> searchResult; QList<Entry*> searchResult;
@ -54,8 +53,7 @@ QList<Entry*> EntrySearcher::searchEntries(const QString& searchTerm, const Grou
return searchResult; return searchResult;
} }
QList<Entry*> EntrySearcher::matchEntry(const QString& searchTerm, Entry* entry, QList<Entry*> EntrySearcher::matchEntry(const QString& searchTerm, Entry* entry, Qt::CaseSensitivity caseSensitivity)
Qt::CaseSensitivity caseSensitivity)
{ {
const QStringList wordList = searchTerm.split(QRegExp("\\s"), QString::SkipEmptyParts); const QStringList wordList = searchTerm.split(QRegExp("\\s"), QString::SkipEmptyParts);
for (const QString& word : wordList) { for (const QString& word : wordList) {
@ -69,10 +67,10 @@ QList<Entry*> EntrySearcher::matchEntry(const QString& searchTerm, Entry* entry,
bool EntrySearcher::wordMatch(const QString& word, Entry* entry, Qt::CaseSensitivity caseSensitivity) bool EntrySearcher::wordMatch(const QString& word, Entry* entry, Qt::CaseSensitivity caseSensitivity)
{ {
return entry->resolvePlaceholder(entry->title()).contains(word, caseSensitivity) || return entry->resolvePlaceholder(entry->title()).contains(word, caseSensitivity)
entry->resolvePlaceholder(entry->username()).contains(word, caseSensitivity) || || entry->resolvePlaceholder(entry->username()).contains(word, caseSensitivity)
entry->resolvePlaceholder(entry->url()).contains(word, caseSensitivity) || || entry->resolvePlaceholder(entry->url()).contains(word, caseSensitivity)
entry->resolvePlaceholder(entry->notes()).contains(word, caseSensitivity); || entry->resolvePlaceholder(entry->notes()).contains(word, caseSensitivity);
} }
bool EntrySearcher::matchGroup(const QString& searchTerm, const Group* group, Qt::CaseSensitivity caseSensitivity) bool EntrySearcher::matchGroup(const QString& searchTerm, const Group* group, Qt::CaseSensitivity caseSensitivity)
@ -89,6 +87,5 @@ bool EntrySearcher::matchGroup(const QString& searchTerm, const Group* group, Qt
bool EntrySearcher::wordMatch(const QString& word, const Group* group, Qt::CaseSensitivity caseSensitivity) bool EntrySearcher::wordMatch(const QString& word, const Group* group, Qt::CaseSensitivity caseSensitivity)
{ {
return group->name().contains(word, caseSensitivity) || return group->name().contains(word, caseSensitivity) || group->notes().contains(word, caseSensitivity);
group->notes().contains(word, caseSensitivity);
} }

View File

@ -21,7 +21,6 @@
#include <QString> #include <QString>
class Group; class Group;
class Entry; class Entry;

View File

@ -8,7 +8,9 @@ class Exporter
{ {
public: public:
virtual Database* exportGroup(Group* group) = 0; virtual Database* exportGroup(Group* group) = 0;
virtual ~Exporter() {} virtual ~Exporter()
{
}
}; };
#endif // KEEPASSX_EXPORTER_H #endif // KEEPASSX_EXPORTER_H

View File

@ -23,8 +23,8 @@
#include <QLibrary> #include <QLibrary>
#include "config-keepassx.h" #include "config-keepassx.h"
#include "core/Global.h"
#include "core/Config.h" #include "core/Config.h"
#include "core/Global.h"
FilePath* FilePath::m_instance(nullptr); FilePath* FilePath::m_instance(nullptr);
@ -32,8 +32,7 @@ QString FilePath::dataPath(const QString& name)
{ {
if (name.isEmpty() || name.startsWith('/')) { if (name.isEmpty() || name.startsWith('/')) {
return m_dataPath + name; return m_dataPath + name;
} } else {
else {
return m_dataPath + "/" + name; return m_dataPath + "/" + name;
} }
} }
@ -61,14 +60,12 @@ QString FilePath::pluginPath(const QString& name)
if (configuredPluginDir != ".") { if (configuredPluginDir != ".") {
if (QDir(configuredPluginDir).isAbsolute()) { if (QDir(configuredPluginDir).isAbsolute()) {
pluginPaths << configuredPluginDir; pluginPaths << configuredPluginDir;
} } else {
else { QString relativePluginDir =
QString relativePluginDir = QString("%1/../%2") QString("%1/../%2").arg(QCoreApplication::applicationDirPath(), configuredPluginDir);
.arg(QCoreApplication::applicationDirPath(), configuredPluginDir);
pluginPaths << QDir(relativePluginDir).canonicalPath(); pluginPaths << QDir(relativePluginDir).canonicalPath();
QString absolutePluginDir = QString("%1/%2") QString absolutePluginDir = QString("%1/%2").arg(KEEPASSX_PREFIX_DIR, configuredPluginDir);
.arg(KEEPASSX_PREFIX_DIR, configuredPluginDir);
pluginPaths << QDir(absolutePluginDir).canonicalPath(); pluginPaths << QDir(absolutePluginDir).canonicalPath();
} }
} }
@ -151,11 +148,11 @@ QIcon FilePath::icon(const QString& category, const QString& name, bool fromThem
} }
if (icon.isNull()) { if (icon.isNull()) {
const QList<int> pngSizes = { 16, 22, 24, 32, 48, 64, 128 }; const QList<int> pngSizes = {16, 22, 24, 32, 48, 64, 128};
QString filename; QString filename;
for (int size : pngSizes) { for (int size : pngSizes) {
filename = QString("%1/icons/application/%2x%2/%3.png").arg(m_dataPath, QString::number(size), filename =
combinedName); QString("%1/icons/application/%2x%2/%3.png").arg(m_dataPath, QString::number(size), combinedName);
if (QFile::exists(filename)) { if (QFile::exists(filename)) {
icon.addFile(filename, QSize(size, size)); icon.addFile(filename, QSize(size, size));
} }
@ -189,17 +186,16 @@ QIcon FilePath::onOffIcon(const QString& category, const QString& name)
if (i == 0) { if (i == 0) {
state = QIcon::Off; state = QIcon::Off;
stateName = "off"; stateName = "off";
} } else {
else {
state = QIcon::On; state = QIcon::On;
stateName = "on"; stateName = "on";
} }
const QList<int> pngSizes = { 16, 22, 24, 32, 48, 64, 128 }; const QList<int> pngSizes = {16, 22, 24, 32, 48, 64, 128};
QString filename; QString filename;
for (int size : pngSizes) { for (int size : pngSizes) {
filename = QString("%1/icons/application/%2x%2/%3-%4.png").arg(m_dataPath, QString::number(size), filename = QString("%1/icons/application/%2x%2/%3-%4.png")
combinedName, stateName); .arg(m_dataPath, QString::number(size), combinedName, stateName);
if (QFile::exists(filename)) { if (QFile::exists(filename)) {
icon.addFile(filename, QSize(size, size), QIcon::Normal, state); icon.addFile(filename, QSize(size, size), QIcon::Normal, state);
} }
@ -229,10 +225,8 @@ FilePath::FilePath()
#endif #endif
#if defined(Q_OS_UNIX) && !(defined(Q_OS_MAC) && defined(WITH_APP_BUNDLE)) #if defined(Q_OS_UNIX) && !(defined(Q_OS_MAC) && defined(WITH_APP_BUNDLE))
else if (isDataDirAbsolute && testSetDir(KEEPASSX_DATA_DIR)) { else if (isDataDirAbsolute && testSetDir(KEEPASSX_DATA_DIR)) {
} } else if (!isDataDirAbsolute && testSetDir(QString("%1/../%2").arg(appDirPath, KEEPASSX_DATA_DIR))) {
else if (!isDataDirAbsolute && testSetDir(QString("%1/../%2").arg(appDirPath, KEEPASSX_DATA_DIR))) { } else if (!isDataDirAbsolute && testSetDir(QString("%1/%2").arg(KEEPASSX_PREFIX_DIR, KEEPASSX_DATA_DIR))) {
}
else if (!isDataDirAbsolute && testSetDir(QString("%1/%2").arg(KEEPASSX_PREFIX_DIR, KEEPASSX_DATA_DIR))) {
} }
#endif #endif
#if defined(Q_OS_MAC) && defined(WITH_APP_BUNDLE) #if defined(Q_OS_MAC) && defined(WITH_APP_BUNDLE)
@ -249,8 +243,7 @@ FilePath::FilePath()
if (m_dataPath.isEmpty()) { if (m_dataPath.isEmpty()) {
qWarning("FilePath::DataPath: can't find data dir"); qWarning("FilePath::DataPath: can't find data dir");
} } else {
else {
m_dataPath = QDir::cleanPath(m_dataPath); m_dataPath = QDir::cleanPath(m_dataPath);
} }
} }
@ -260,8 +253,7 @@ bool FilePath::testSetDir(const QString& dir)
if (QFile::exists(dir + "/icons/database/C00_Password.png")) { if (QFile::exists(dir + "/icons/database/C00_Password.png")) {
m_dataPath = dir; m_dataPath = dir;
return true; return true;
} } else {
else {
return false; return false;
} }
} }

View File

@ -50,7 +50,8 @@ private:
Q_DISABLE_COPY(FilePath) Q_DISABLE_COPY(FilePath)
}; };
inline FilePath* filePath() { inline FilePath* filePath()
{
return FilePath::instance(); return FilePath::instance();
} }

View File

@ -23,26 +23,30 @@
#include <QtGlobal> #include <QtGlobal>
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
# if defined(KEEPASSX_BUILDING_CORE) #if defined(KEEPASSX_BUILDING_CORE)
# define KEEPASSX_EXPORT Q_DECL_IMPORT #define KEEPASSX_EXPORT Q_DECL_IMPORT
# else
# define KEEPASSX_EXPORT Q_DECL_EXPORT
# endif
#else #else
# define KEEPASSX_EXPORT Q_DECL_EXPORT #define KEEPASSX_EXPORT Q_DECL_EXPORT
#endif
#else
#define KEEPASSX_EXPORT Q_DECL_EXPORT
#endif #endif
#ifndef QUINT32_MAX #ifndef QUINT32_MAX
#define QUINT32_MAX 4294967295U #define QUINT32_MAX 4294967295U
#endif #endif
template <typename T> struct AddConst { typedef const T Type; }; template <typename T> struct AddConst
{
typedef const T Type;
};
// this adds const to non-const objects (like std::as_const) // this adds const to non-const objects (like std::as_const)
template <typename T> template <typename T> constexpr typename AddConst<T>::Type& asConst(T& t) noexcept
constexpr typename AddConst<T>::Type& asConst(T &t) noexcept { return t; } {
return t;
}
// prevent rvalue arguments: // prevent rvalue arguments:
template <typename T> template <typename T> void asConst(const T&&) = delete;
void asConst(const T&&) = delete;
#endif // KEEPASSX_GLOBAL_H #endif // KEEPASSX_GLOBAL_H

View File

@ -27,10 +27,10 @@ const int Group::DefaultIconNumber = 48;
const int Group::RecycleBinIconNumber = 43; const int Group::RecycleBinIconNumber = 43;
const QString Group::RootAutoTypeSequence = "{USERNAME}{TAB}{PASSWORD}{ENTER}"; const QString Group::RootAutoTypeSequence = "{USERNAME}{TAB}{PASSWORD}{ENTER}";
Group::CloneFlags Group::DefaultCloneFlags = static_cast<Group::CloneFlags>( Group::CloneFlags Group::DefaultCloneFlags =
Group::CloneNewUuid | Group::CloneResetTimeInfo | Group::CloneIncludeEntries); static_cast<Group::CloneFlags>(Group::CloneNewUuid | Group::CloneResetTimeInfo | Group::CloneIncludeEntries);
Entry::CloneFlags Group::DefaultEntryCloneFlags = static_cast<Entry::CloneFlags>( Entry::CloneFlags Group::DefaultEntryCloneFlags =
Entry::CloneNewUuid | Entry::CloneResetTimeInfo); static_cast<Entry::CloneFlags>(Entry::CloneNewUuid | Entry::CloneResetTimeInfo);
Group::Group() Group::Group()
: m_customData(new CustomData(this)) : m_customData(new CustomData(this))
@ -81,7 +81,8 @@ Group* Group::createRecycleBin()
return recycleBin; return recycleBin;
} }
template <class P, class V> inline bool Group::set(P& property, const V& value) { template <class P, class V> inline bool Group::set(P& property, const V& value)
{
if (property != value) { if (property != value) {
property = value; property = value;
emit modified(); emit modified();
@ -123,14 +124,12 @@ QImage Group::icon() const
{ {
if (m_data.customIcon.isNull()) { if (m_data.customIcon.isNull()) {
return databaseIcons()->icon(m_data.iconNumber); return databaseIcons()->icon(m_data.iconNumber);
} } else {
else {
Q_ASSERT(m_db); Q_ASSERT(m_db);
if (m_db) { if (m_db) {
return m_db->metadata()->customIcon(m_data.customIcon); return m_db->metadata()->customIcon(m_data.customIcon);
} } else {
else {
return QImage(); return QImage();
} }
} }
@ -140,14 +139,12 @@ QPixmap Group::iconPixmap() const
{ {
if (m_data.customIcon.isNull()) { if (m_data.customIcon.isNull()) {
return databaseIcons()->iconPixmap(m_data.iconNumber); return databaseIcons()->iconPixmap(m_data.iconNumber);
} } else {
else {
Q_ASSERT(m_db); Q_ASSERT(m_db);
if (m_db) { if (m_db) {
return m_db->metadata()->customIconPixmap(m_data.customIcon); return m_db->metadata()->customIconPixmap(m_data.customIcon);
} } else {
else {
return QPixmap(); return QPixmap();
} }
} }
@ -158,14 +155,12 @@ QPixmap Group::iconScaledPixmap() const
if (m_data.customIcon.isNull()) { if (m_data.customIcon.isNull()) {
// built-in icons are 16x16 so don't need to be scaled // built-in icons are 16x16 so don't need to be scaled
return databaseIcons()->iconPixmap(m_data.iconNumber); return databaseIcons()->iconPixmap(m_data.iconNumber);
} } else {
else {
Q_ASSERT(m_db); Q_ASSERT(m_db);
if (m_db) { if (m_db) {
return m_db->metadata()->customIconScaledPixmap(m_data.customIcon); return m_db->metadata()->customIconScaledPixmap(m_data.customIcon);
} } else {
else {
return QPixmap(); return QPixmap();
} }
} }
@ -401,8 +396,7 @@ void Group::setParent(Group* parent, int index)
recCreateDelObjects(); recCreateDelObjects();
// copy custom icon to the new database // copy custom icon to the new database
if (!iconUuid().isNull() && parent->m_db if (!iconUuid().isNull() && parent->m_db && m_db->metadata()->containsCustomIcon(iconUuid())
&& m_db->metadata()->containsCustomIcon(iconUuid())
&& !parent->m_db->metadata()->containsCustomIcon(iconUuid())) { && !parent->m_db->metadata()->containsCustomIcon(iconUuid())) {
parent->m_db->metadata()->addCustomIcon(iconUuid(), icon()); parent->m_db->metadata()->addCustomIcon(iconUuid(), icon());
} }
@ -414,8 +408,7 @@ void Group::setParent(Group* parent, int index)
emit aboutToAdd(this, index); emit aboutToAdd(this, index);
Q_ASSERT(index <= parent->m_children.size()); Q_ASSERT(index <= parent->m_children.size());
parent->m_children.insert(index, this); parent->m_children.insert(index, this);
} } else {
else {
emit aboutToMove(this, parent, index); emit aboutToMove(this, parent, index);
m_parent->m_children.removeAll(this); m_parent->m_children.removeAll(this);
m_parent = parent; m_parent = parent;
@ -432,8 +425,7 @@ void Group::setParent(Group* parent, int index)
if (!moveWithinDatabase) { if (!moveWithinDatabase) {
emit added(); emit added();
} } else {
else {
emit moved(); emit moved();
} }
} }
@ -733,7 +725,6 @@ void Group::merge(const Group* other)
resolveGroupConflict(existingGroup, group); resolveGroupConflict(existingGroup, group);
existingGroup->merge(group); existingGroup->merge(group);
} }
} }
emit modified(); emit modified();
@ -849,9 +840,9 @@ void Group::recSetDatabase(Database* db)
disconnect(SIGNAL(dataChanged(Group*)), m_db); disconnect(SIGNAL(dataChanged(Group*)), m_db);
disconnect(SIGNAL(aboutToRemove(Group*)), m_db); disconnect(SIGNAL(aboutToRemove(Group*)), m_db);
disconnect(SIGNAL(removed()), m_db); disconnect(SIGNAL(removed()), m_db);
disconnect(SIGNAL(aboutToAdd(Group*,int)), m_db); disconnect(SIGNAL(aboutToAdd(Group*, int)), m_db);
disconnect(SIGNAL(added()), m_db); disconnect(SIGNAL(added()), m_db);
disconnect(SIGNAL(aboutToMove(Group*,Group*,int)), m_db); disconnect(SIGNAL(aboutToMove(Group*, Group*, int)), m_db);
disconnect(SIGNAL(moved()), m_db); disconnect(SIGNAL(moved()), m_db);
disconnect(SIGNAL(modified()), m_db); disconnect(SIGNAL(modified()), m_db);
} }
@ -869,9 +860,9 @@ void Group::recSetDatabase(Database* db)
connect(this, SIGNAL(dataChanged(Group*)), db, SIGNAL(groupDataChanged(Group*))); connect(this, SIGNAL(dataChanged(Group*)), db, SIGNAL(groupDataChanged(Group*)));
connect(this, SIGNAL(aboutToRemove(Group*)), db, SIGNAL(groupAboutToRemove(Group*))); connect(this, SIGNAL(aboutToRemove(Group*)), db, SIGNAL(groupAboutToRemove(Group*)));
connect(this, SIGNAL(removed()), db, SIGNAL(groupRemoved())); connect(this, SIGNAL(removed()), db, SIGNAL(groupRemoved()));
connect(this, SIGNAL(aboutToAdd(Group*,int)), db, SIGNAL(groupAboutToAdd(Group*,int))); connect(this, SIGNAL(aboutToAdd(Group*, int)), db, SIGNAL(groupAboutToAdd(Group*, int)));
connect(this, SIGNAL(added()), db, SIGNAL(groupAdded())); connect(this, SIGNAL(added()), db, SIGNAL(groupAdded()));
connect(this, SIGNAL(aboutToMove(Group*,Group*,int)), db, SIGNAL(groupAboutToMove(Group*,Group*,int))); connect(this, SIGNAL(aboutToMove(Group*, Group*, int)), db, SIGNAL(groupAboutToMove(Group*, Group*, int)));
connect(this, SIGNAL(moved()), db, SIGNAL(groupMoved())); connect(this, SIGNAL(moved()), db, SIGNAL(groupMoved()));
connect(this, SIGNAL(modified()), db, SIGNAL(modifiedImmediate())); connect(this, SIGNAL(modified()), db, SIGNAL(modifiedImmediate()));
} }
@ -910,8 +901,7 @@ void Group::recCreateDelObjects()
void Group::markOlderEntry(Entry* entry) void Group::markOlderEntry(Entry* entry)
{ {
entry->attributes()->set( entry->attributes()->set(
"merged", "merged", tr("older entry merged from database \"%1\"").arg(entry->group()->database()->metadata()->name()));
tr("older entry merged from database \"%1\"").arg(entry->group()->database()->metadata()->name()));
} }
bool Group::resolveSearchingEnabled() const bool Group::resolveSearchingEnabled() const
@ -920,8 +910,7 @@ bool Group::resolveSearchingEnabled() const
case Inherit: case Inherit:
if (!m_parent) { if (!m_parent) {
return true; return true;
} } else {
else {
return m_parent->resolveSearchingEnabled(); return m_parent->resolveSearchingEnabled();
} }
case Enable: case Enable:
@ -940,8 +929,7 @@ bool Group::resolveAutoTypeEnabled() const
case Inherit: case Inherit:
if (!m_parent) { if (!m_parent) {
return true; return true;
} } else {
else {
return m_parent->resolveAutoTypeEnabled(); return m_parent->resolveAutoTypeEnabled();
} }
case Enable: case Enable:
@ -1009,7 +997,6 @@ void Group::resolveGroupConflict(Group* existingGroup, Group* otherGroup)
} }
existingGroup->setExpiryTime(otherGroup->timeInfo().expiryTime()); existingGroup->setExpiryTime(otherGroup->timeInfo().expiryTime());
} }
} }
QStringList Group::locate(QString locateTerm, QString currentPath) QStringList Group::locate(QString locateTerm, QString currentPath)
@ -1059,5 +1046,4 @@ Entry* Group::addEntryWithPath(QString entryPath)
entry->setGroup(group); entry->setGroup(group);
return entry; return entry;
} }

View File

@ -24,9 +24,9 @@
#include <QPixmapCache> #include <QPixmapCache>
#include <QPointer> #include <QPointer>
#include "core/CustomData.h"
#include "core/Database.h" #include "core/Database.h"
#include "core/Entry.h" #include "core/Entry.h"
#include "core/CustomData.h"
#include "core/TimeInfo.h" #include "core/TimeInfo.h"
#include "core/Uuid.h" #include "core/Uuid.h"
@ -35,10 +35,22 @@ class Group : public QObject
Q_OBJECT Q_OBJECT
public: public:
enum TriState { Inherit, Enable, Disable }; enum TriState
enum MergeMode { ModeInherit, KeepBoth, KeepNewer, KeepExisting }; {
Inherit,
Enable,
Disable
};
enum MergeMode
{
ModeInherit,
KeepBoth,
KeepNewer,
KeepExisting
};
enum CloneFlag { enum CloneFlag
{
CloneNoFlags = 0, CloneNoFlags = 0,
CloneNewUuid = 1, // generate a random uuid for the clone CloneNewUuid = 1, // generate a random uuid for the clone
CloneResetTimeInfo = 2, // set all TimeInfo attributes to the current time CloneResetTimeInfo = 2, // set all TimeInfo attributes to the current time

View File

@ -56,9 +56,9 @@ bool InactivityTimer::eventFilter(QObject* watched, QEvent* event)
{ {
const QEvent::Type type = event->type(); const QEvent::Type type = event->type();
if ( (type >= QEvent::MouseButtonPress && type <= QEvent::KeyRelease) if ((type >= QEvent::MouseButtonPress && type <= QEvent::KeyRelease)
|| (type >= QEvent::HoverEnter && type <= QEvent::HoverMove) || (type >= QEvent::HoverEnter && type <= QEvent::HoverMove)
|| (type == QEvent::Wheel) ) { || (type == QEvent::Wheel)) {
m_timer->start(); m_timer->start();
} }

View File

@ -20,12 +20,15 @@
#include <QList> #include <QList>
template <typename T> template <typename T> class ListDeleter
class ListDeleter
{ {
public: public:
inline explicit ListDeleter(QList<T>* list) : m_list(list) {} inline explicit ListDeleter(QList<T>* list)
inline ~ListDeleter() { : m_list(list)
{
}
inline ~ListDeleter()
{
qDeleteAll(*m_list); qDeleteAll(*m_list);
} }

View File

@ -17,9 +17,13 @@
#include "MacPasteboard.h" #include "MacPasteboard.h"
QString MacPasteboard::convertorName() { return QLatin1String("MacPasteboard"); } QString MacPasteboard::convertorName()
{
return QLatin1String("MacPasteboard");
}
QString MacPasteboard::flavorFor(const QString& mimetype) { QString MacPasteboard::flavorFor(const QString& mimetype)
{
if (mimetype == QLatin1String("text/plain")) { if (mimetype == QLatin1String("text/plain")) {
return QLatin1String("public.utf8-plain-text"); return QLatin1String("public.utf8-plain-text");
} else if (mimetype == QLatin1String("application/x-nspasteboard-concealed-type")) { } else if (mimetype == QLatin1String("application/x-nspasteboard-concealed-type")) {
@ -38,15 +42,15 @@ QString MacPasteboard::flavorFor(const QString& mimetype) {
if (cs == QLatin1String("system")) { if (cs == QLatin1String("system")) {
return QLatin1String("public.utf8-plain-text"); return QLatin1String("public.utf8-plain-text");
} else if (cs == QLatin1String("iso-10646-ucs-2") || } else if (cs == QLatin1String("iso-10646-ucs-2") || cs == QLatin1String("utf16")) {
cs == QLatin1String("utf16")) {
return QLatin1String("public.utf16-plain-text"); return QLatin1String("public.utf16-plain-text");
} }
} }
return QString(); return QString();
} }
QString MacPasteboard::mimeFor(QString flavor) { QString MacPasteboard::mimeFor(QString flavor)
{
if (flavor == QLatin1String("public.utf8-plain-text")) if (flavor == QLatin1String("public.utf8-plain-text"))
return QLatin1String("text/plain"); return QLatin1String("text/plain");
if (flavor == QLatin1String("org.nspasteboard.ConcealedType")) if (flavor == QLatin1String("org.nspasteboard.ConcealedType"))
@ -56,13 +60,15 @@ QString MacPasteboard::mimeFor(QString flavor) {
return QString(); return QString();
} }
bool MacPasteboard::canConvert(const QString& mimetype, QString flavor) { bool MacPasteboard::canConvert(const QString& mimetype, QString flavor)
{
Q_UNUSED(mimetype); Q_UNUSED(mimetype);
Q_UNUSED(flavor); Q_UNUSED(flavor);
return true; return true;
} }
QVariant MacPasteboard::convertToMime(const QString& mimetype, QList<QByteArray> data, QString flavor) { QVariant MacPasteboard::convertToMime(const QString& mimetype, QList<QByteArray> data, QString flavor)
{
if (data.count() > 1) if (data.count() > 1)
qWarning("QMime::convertToMime: Cannot handle multiple member data"); qWarning("QMime::convertToMime: Cannot handle multiple member data");
const QByteArray& firstData = data.first(); const QByteArray& firstData = data.first();
@ -74,13 +80,13 @@ QVariant MacPasteboard::convertToMime(const QString& mimetype, QList<QByteArray>
} else if (flavor == QLatin1String("public.utf16-plain-text")) { } else if (flavor == QLatin1String("public.utf16-plain-text")) {
ret = QTextCodec::codecForName("UTF-16")->toUnicode(firstData); ret = QTextCodec::codecForName("UTF-16")->toUnicode(firstData);
} else { } else {
qWarning("QMime::convertToMime: unhandled mimetype: %s", qWarning("QMime::convertToMime: unhandled mimetype: %s", qPrintable(mimetype));
qPrintable(mimetype));
} }
return ret; return ret;
} }
QList<QByteArray> MacPasteboard::convertFromMime(const QString&, QVariant data, QString flavor) { QList<QByteArray> MacPasteboard::convertFromMime(const QString&, QVariant data, QString flavor)
{
QList<QByteArray> ret; QList<QByteArray> ret;
QString string = data.toString(); QString string = data.toString();
if (flavor == QLatin1String("public.utf8-plain-text")) if (flavor == QLatin1String("public.utf8-plain-text"))
@ -91,4 +97,3 @@ QList<QByteArray> MacPasteboard::convertFromMime(const QString&, QVariant data,
ret.append(QTextCodec::codecForName("UTF-16")->fromUnicode(string)); ret.append(QTextCodec::codecForName("UTF-16")->fromUnicode(string));
return ret; return ret;
} }

View File

@ -19,20 +19,23 @@
#define KEEPASSXC_MACPASTEBOARD_H #define KEEPASSXC_MACPASTEBOARD_H
#include <QMacPasteboardMime> #include <QMacPasteboardMime>
#include <QTextCodec>
#include <QObject> #include <QObject>
#include <QTextCodec>
class MacPasteboard : public QObject, public QMacPasteboardMime class MacPasteboard : public QObject, public QMacPasteboardMime
{ {
public: public:
explicit MacPasteboard() : QMacPasteboardMime(MIME_ALL) {} explicit MacPasteboard()
: QMacPasteboardMime(MIME_ALL)
{
}
QString convertorName() override; QString convertorName() override;
bool canConvert(const QString &mime, QString flav) override; bool canConvert(const QString& mime, QString flav) override;
QString mimeFor(QString flav) override; QString mimeFor(QString flav) override;
QString flavorFor(const QString &mime) override; QString flavorFor(const QString& mime) override;
QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav) override; QVariant convertToMime(const QString& mime, QList<QByteArray> data, QString flav) override;
QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav) override; QList<QByteArray> convertFromMime(const QString& mime, QVariant data, QString flav) override;
}; };
#endif // KEEPASSXC_MACPASTEBOARD_H #endif // KEEPASSXC_MACPASTEBOARD_H

View File

@ -15,8 +15,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <QtCore/QCryptographicHash>
#include "Metadata.h" #include "Metadata.h"
#include <QtCore/QCryptographicHash>
#include "core/Entry.h" #include "core/Entry.h"
#include "core/Group.h" #include "core/Group.h"
@ -61,13 +61,13 @@ template <class P, class V> bool Metadata::set(P& property, const V& value)
property = value; property = value;
emit modified(); emit modified();
return true; return true;
} } else {
else {
return false; return false;
} }
} }
template <class P, class V> bool Metadata::set(P& property, const V& value, QDateTime& dateTime) { template <class P, class V> bool Metadata::set(P& property, const V& value, QDateTime& dateTime)
{
if (property != value) { if (property != value) {
property = value; property = value;
if (m_updateDatetime) { if (m_updateDatetime) {
@ -75,8 +75,7 @@ template <class P, class V> bool Metadata::set(P& property, const V& value, QDat
} }
emit modified(); emit modified();
return true; return true;
} } else {
else {
return false; return false;
} }
} }
@ -402,10 +401,8 @@ void Metadata::addCustomIconScaled(const Uuid& uuid, const QImage& icon)
// scale down to 128x128 if icon is larger // scale down to 128x128 if icon is larger
if (icon.width() > 128 || icon.height() > 128) { if (icon.width() > 128 || icon.height() > 128) {
iconScaled = icon.scaled(QSize(128, 128), Qt::KeepAspectRatio, iconScaled = icon.scaled(QSize(128, 128), Qt::KeepAspectRatio, Qt::SmoothTransformation);
Qt::SmoothTransformation); } else {
}
else {
iconScaled = icon; iconScaled = icon;
} }
@ -433,7 +430,7 @@ void Metadata::removeCustomIcon(const Uuid& uuid)
emit modified(); emit modified();
} }
Uuid Metadata::findCustomIcon(const QImage &candidate) Uuid Metadata::findCustomIcon(const QImage& candidate)
{ {
QByteArray hash = hashImage(candidate); QByteArray hash = hashImage(candidate);
return m_customIconsHashes.value(hash, Uuid()); return m_customIconsHashes.value(hash, Uuid());

View File

@ -26,8 +26,8 @@
#include <QPixmapCache> #include <QPixmapCache>
#include <QPointer> #include <QPointer>
#include "core/Uuid.h"
#include "core/CustomData.h" #include "core/CustomData.h"
#include "core/Uuid.h"
class Database; class Database;
class Group; class Group;

View File

@ -17,12 +17,12 @@
#include "PassphraseGenerator.h" #include "PassphraseGenerator.h"
#include <cmath>
#include <QFile> #include <QFile>
#include <QTextStream> #include <QTextStream>
#include <cmath>
#include "crypto/Random.h"
#include "core/FilePath.h" #include "core/FilePath.h"
#include "crypto/Random.h"
const char* PassphraseGenerator::DefaultSeparator = " "; const char* PassphraseGenerator::DefaultSeparator = " ";
const char* PassphraseGenerator::DefaultWordList = "eff_large.wordlist"; const char* PassphraseGenerator::DefaultWordList = "eff_large.wordlist";
@ -52,7 +52,6 @@ void PassphraseGenerator::setWordCount(int wordCount)
// safe default if something goes wrong // safe default if something goes wrong
m_wordCount = DefaultWordCount; m_wordCount = DefaultWordCount;
} }
} }
void PassphraseGenerator::setWordList(const QString& path) void PassphraseGenerator::setWordList(const QString& path)
@ -82,7 +81,8 @@ void PassphraseGenerator::setDefaultWordList()
setWordList(path); setWordList(path);
} }
void PassphraseGenerator::setWordSeparator(const QString& separator) { void PassphraseGenerator::setWordSeparator(const QString& separator)
{
m_separator = separator; m_separator = separator;
} }
@ -91,7 +91,7 @@ QString PassphraseGenerator::generatePassphrase() const
Q_ASSERT(isValid()); Q_ASSERT(isValid());
// In case there was an error loading the wordlist // In case there was an error loading the wordlist
if(m_wordlist.length() == 0) { if (m_wordlist.length() == 0) {
return QString(); return QString();
} }

View File

@ -92,8 +92,7 @@ QString PasswordGenerator::generatePassword() const
password[i] = password[j]; password[i] = password[j];
password[j] = tmp; password[j] = tmp;
} }
} } else {
else {
for (int i = 0; i < m_length; i++) { for (int i = 0; i < m_length; i++) {
int pos = randomGen()->randomUInt(passwordChars.size()); int pos = randomGen()->randomUInt(passwordChars.size());
@ -110,7 +109,7 @@ int PasswordGenerator::getbits() const
int bits = 0; int bits = 0;
QVector<QChar> passwordChars; QVector<QChar> passwordChars;
for (const PasswordGroup& group: groups) { for (const PasswordGroup& group : groups) {
bits += group.size(); bits += group.size();
} }
@ -119,13 +118,11 @@ int PasswordGenerator::getbits() const
return bits; return bits;
} }
bool PasswordGenerator::isValid() const bool PasswordGenerator::isValid() const
{ {
if (m_classes == 0) { if (m_classes == 0) {
return false; return false;
} } else if (m_length == 0) {
else if (m_length == 0) {
return false; return false;
} }

View File

@ -18,11 +18,13 @@
#include "ScreenLockListener.h" #include "ScreenLockListener.h"
#include "ScreenLockListenerPrivate.h" #include "ScreenLockListenerPrivate.h"
ScreenLockListener::ScreenLockListener(QWidget* parent): ScreenLockListener::ScreenLockListener(QWidget* parent)
QObject(parent){ : QObject(parent)
{
m_listener = ScreenLockListenerPrivate::instance(parent); m_listener = ScreenLockListenerPrivate::instance(parent);
connect(m_listener,SIGNAL(screenLocked()), this,SIGNAL(screenLocked())); connect(m_listener, SIGNAL(screenLocked()), this, SIGNAL(screenLocked()));
} }
ScreenLockListener::~ScreenLockListener(){ ScreenLockListener::~ScreenLockListener()
{
} }

View File

@ -21,7 +21,8 @@
class ScreenLockListenerPrivate; class ScreenLockListenerPrivate;
class ScreenLockListener : public QObject { class ScreenLockListener : public QObject
{
Q_OBJECT Q_OBJECT
public: public:

View File

@ -22,59 +22,53 @@
#include <QDBusReply> #include <QDBusReply>
#include <QProcessEnvironment> #include <QProcessEnvironment>
ScreenLockListenerDBus::ScreenLockListenerDBus(QWidget *parent): ScreenLockListenerDBus::ScreenLockListenerDBus(QWidget* parent)
ScreenLockListenerPrivate(parent) : ScreenLockListenerPrivate(parent)
{ {
QDBusConnection sessionBus = QDBusConnection::sessionBus(); QDBusConnection sessionBus = QDBusConnection::sessionBus();
QDBusConnection systemBus = QDBusConnection::systemBus(); QDBusConnection systemBus = QDBusConnection::systemBus();
sessionBus.connect( sessionBus.connect("org.freedesktop.ScreenSaver", // service
"org.freedesktop.ScreenSaver", // service
"/org/freedesktop/ScreenSaver", // path "/org/freedesktop/ScreenSaver", // path
"org.freedesktop.ScreenSaver", // interface "org.freedesktop.ScreenSaver", // interface
"ActiveChanged", // signal name "ActiveChanged", // signal name
this, //receiver this, // receiver
SLOT(freedesktopScreenSaver(bool))); SLOT(freedesktopScreenSaver(bool)));
sessionBus.connect( sessionBus.connect("org.gnome.ScreenSaver", // service
"org.gnome.ScreenSaver", // service
"/org/gnome/ScreenSaver", // path "/org/gnome/ScreenSaver", // path
"org.gnome.ScreenSaver", // interface "org.gnome.ScreenSaver", // interface
"ActiveChanged", // signal name "ActiveChanged", // signal name
this, //receiver this, // receiver
SLOT(freedesktopScreenSaver(bool))); SLOT(freedesktopScreenSaver(bool)));
sessionBus.connect( sessionBus.connect("org.gnome.SessionManager", // service
"org.gnome.SessionManager", // service
"/org/gnome/SessionManager/Presence", // path "/org/gnome/SessionManager/Presence", // path
"org.gnome.SessionManager.Presence", // interface "org.gnome.SessionManager.Presence", // interface
"StatusChanged", // signal name "StatusChanged", // signal name
this, //receiver this, // receiver
SLOT(gnomeSessionStatusChanged(uint))); SLOT(gnomeSessionStatusChanged(uint)));
systemBus.connect( systemBus.connect("org.freedesktop.login1", // service
"org.freedesktop.login1", // service
"/org/freedesktop/login1", // path "/org/freedesktop/login1", // path
"org.freedesktop.login1.Manager", // interface "org.freedesktop.login1.Manager", // interface
"PrepareForSleep", // signal name "PrepareForSleep", // signal name
this, //receiver this, // receiver
SLOT(logindPrepareForSleep(bool))); SLOT(logindPrepareForSleep(bool)));
QString sessionId = QProcessEnvironment::systemEnvironment().value("XDG_SESSION_ID"); QString sessionId = QProcessEnvironment::systemEnvironment().value("XDG_SESSION_ID");
systemBus.connect( systemBus.connect("", // service
"", // service
QString("/org/freedesktop/login1/session/") + sessionId, // path QString("/org/freedesktop/login1/session/") + sessionId, // path
"org.freedesktop.login1.Session", // interface "org.freedesktop.login1.Session", // interface
"Lock", // signal name "Lock", // signal name
this, //receiver this, // receiver
SLOT(unityLocked())); SLOT(unityLocked()));
sessionBus.connect( sessionBus.connect("com.canonical.Unity", // service
"com.canonical.Unity", // service
"/com/canonical/Unity/Session", // path "/com/canonical/Unity/Session", // path
"com.canonical.Unity.Session", // interface "com.canonical.Unity.Session", // interface
"Locked", // signal name "Locked", // signal name
this, //receiver this, // receiver
SLOT(unityLocked())); SLOT(unityLocked()));
} }

View File

@ -17,15 +17,15 @@
#ifndef SCREENLOCKLISTENERDBUS_H #ifndef SCREENLOCKLISTENERDBUS_H
#define SCREENLOCKLISTENERDBUS_H #define SCREENLOCKLISTENERDBUS_H
#include "ScreenLockListenerPrivate.h"
#include <QObject> #include <QObject>
#include <QWidget> #include <QWidget>
#include "ScreenLockListenerPrivate.h"
class ScreenLockListenerDBus : public ScreenLockListenerPrivate class ScreenLockListenerDBus : public ScreenLockListenerPrivate
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit ScreenLockListenerDBus(QWidget *parent = 0); explicit ScreenLockListenerDBus(QWidget* parent = 0);
private slots: private slots:
void gnomeSessionStatusChanged(uint status); void gnomeSessionStatusChanged(uint status);

View File

@ -36,20 +36,17 @@ ScreenLockListenerWin::ScreenLockListenerWin(QWidget* parent)
// This call requests a notification from windows when a laptop is closed // This call requests a notification from windows when a laptop is closed
HPOWERNOTIFY hPnotify = RegisterPowerSettingNotification( HPOWERNOTIFY hPnotify = RegisterPowerSettingNotification(
reinterpret_cast<HWND>(parent->winId()), reinterpret_cast<HWND>(parent->winId()), &GUID_LIDSWITCH_STATE_CHANGE, DEVICE_NOTIFY_WINDOW_HANDLE);
&GUID_LIDSWITCH_STATE_CHANGE, DEVICE_NOTIFY_WINDOW_HANDLE);
m_powerNotificationHandle = reinterpret_cast<void*>(hPnotify); m_powerNotificationHandle = reinterpret_cast<void*>(hPnotify);
// This call requests a notification for session changes // This call requests a notification for session changes
if (!WTSRegisterSessionNotification( if (!WTSRegisterSessionNotification(reinterpret_cast<HWND>(parent->winId()), NOTIFY_FOR_THIS_SESSION)) {
reinterpret_cast<HWND>(parent->winId()),
NOTIFY_FOR_THIS_SESSION)) {
} }
} }
ScreenLockListenerWin::~ScreenLockListenerWin() ScreenLockListenerWin::~ScreenLockListenerWin()
{ {
HWND h= reinterpret_cast<HWND>(static_cast<QWidget*>(parent())->winId()); HWND h = reinterpret_cast<HWND>(static_cast<QWidget*>(parent())->winId());
WTSUnRegisterSessionNotification(h); WTSUnRegisterSessionNotification(h);
if (m_powerNotificationHandle) { if (m_powerNotificationHandle) {

View File

@ -17,9 +17,9 @@
#ifndef SCREENLOCKLISTENERWIN_H #ifndef SCREENLOCKLISTENERWIN_H
#define SCREENLOCKLISTENERWIN_H #define SCREENLOCKLISTENERWIN_H
#include <QAbstractNativeEventFilter>
#include <QObject> #include <QObject>
#include <QWidget> #include <QWidget>
#include <QAbstractNativeEventFilter>
#include "ScreenLockListenerPrivate.h" #include "ScreenLockListenerPrivate.h"
@ -29,10 +29,10 @@ class ScreenLockListenerWin : public ScreenLockListenerPrivate, public QAbstract
public: public:
explicit ScreenLockListenerWin(QWidget* parent = 0); explicit ScreenLockListenerWin(QWidget* parent = 0);
~ScreenLockListenerWin(); ~ScreenLockListenerWin();
virtual bool nativeEventFilter(const QByteArray &eventType, void* message, long*) override; virtual bool nativeEventFilter(const QByteArray& eventType, void* message, long*) override;
private: private:
void* m_powerNotificationHandle ; void* m_powerNotificationHandle;
}; };
#endif // SCREENLOCKLISTENERWIN_H #endif // SCREENLOCKLISTENERWIN_H

View File

@ -131,8 +131,7 @@ void SignalMultiplexer::connect(const Connection& con)
if (con.sender) { if (con.sender) {
QObject::connect(con.sender, con.signal, m_currentObject, con.slot); QObject::connect(con.sender, con.signal, m_currentObject, con.slot);
} } else {
else {
QObject::connect(m_currentObject, con.signal, con.receiver, con.slot); QObject::connect(m_currentObject, con.signal, con.receiver, con.slot);
} }
} }
@ -143,8 +142,7 @@ void SignalMultiplexer::disconnect(const Connection& con)
if (con.sender) { if (con.sender) {
QObject::disconnect(con.sender, con.signal, m_currentObject, con.slot); QObject::disconnect(con.sender, con.signal, m_currentObject, con.slot);
} } else {
else {
QObject::disconnect(m_currentObject, con.signal, con.receiver, con.slot); QObject::disconnect(m_currentObject, con.signal, con.receiver, con.slot);
} }
} }

View File

@ -19,10 +19,9 @@
#include <QDateTime> #include <QDateTime>
QDateTime operator+(const QDateTime& dateTime, const TimeDelta& delta) { QDateTime operator+(const QDateTime& dateTime, const TimeDelta& delta)
return dateTime.addDays(delta.getDays()) {
.addMonths(delta.getMonths()) return dateTime.addDays(delta.getDays()).addMonths(delta.getMonths()).addYears(delta.getYears());
.addYears(delta.getYears());
} }
TimeDelta TimeDelta::fromDays(int days) TimeDelta TimeDelta::fromDays(int days)

View File

@ -20,16 +20,16 @@
#include "Tools.h" #include "Tools.h"
#include <QCoreApplication> #include <QCoreApplication>
#include <QImageReader>
#include <QIODevice> #include <QIODevice>
#include <QImageReader>
#include <QLocale> #include <QLocale>
#include <QStringList> #include <QStringList>
#include <QElapsedTimer> #include <QElapsedTimer>
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#include <windows.h> // for Sleep(), SetDllDirectoryA(), SetSearchPathMode(), ...
#include <aclapi.h> // for SetSecurityInfo() #include <aclapi.h> // for SetSecurityInfo()
#include <windows.h> // for Sleep(), SetDllDirectoryA(), SetSearchPathMode(), ...
#endif #endif
#ifdef Q_OS_UNIX #ifdef Q_OS_UNIX
@ -47,17 +47,21 @@
#endif #endif
#ifdef HAVE_PT_DENY_ATTACH #ifdef HAVE_PT_DENY_ATTACH
#include <sys/types.h>
#include <sys/ptrace.h> #include <sys/ptrace.h>
#include <sys/types.h>
#endif #endif
namespace Tools { namespace Tools
QString humanReadableFileSize(qint64 bytes)
{ {
QString humanReadableFileSize(qint64 bytes)
{
double size = bytes; double size = bytes;
QStringList units = QStringList() << "B" << "KiB" << "MiB" << "GiB"; QStringList units = QStringList() << "B"
<< "KiB"
<< "MiB"
<< "GiB";
int i = 0; int i = 0;
int maxI = units.size() - 1; int maxI = units.size() - 1;
@ -67,10 +71,10 @@ QString humanReadableFileSize(qint64 bytes)
} }
return QString("%1 %2").arg(QLocale().toString(size, 'f', 2), units.at(i)); return QString("%1 %2").arg(QLocale().toString(size, 'f', 2), units.at(i));
} }
bool hasChild(const QObject* parent, const QObject* child) bool hasChild(const QObject* parent, const QObject* child)
{ {
if (!parent || !child) { if (!parent || !child) {
return false; return false;
} }
@ -82,26 +86,25 @@ bool hasChild(const QObject* parent, const QObject* child)
} }
} }
return false; return false;
} }
bool readFromDevice(QIODevice* device, QByteArray& data, int size) bool readFromDevice(QIODevice* device, QByteArray& data, int size)
{ {
QByteArray buffer; QByteArray buffer;
buffer.resize(size); buffer.resize(size);
qint64 readResult = device->read(buffer.data(), size); qint64 readResult = device->read(buffer.data(), size);
if (readResult == -1) { if (readResult == -1) {
return false; return false;
} } else {
else {
buffer.resize(readResult); buffer.resize(readResult);
data = buffer; data = buffer;
return true; return true;
} }
} }
bool readAllFromDevice(QIODevice* device, QByteArray& data) bool readAllFromDevice(QIODevice* device, QByteArray& data)
{ {
QByteArray result; QByteArray result;
qint64 readBytes = 0; qint64 readBytes = 0;
qint64 readResult; qint64 readResult;
@ -115,16 +118,15 @@ bool readAllFromDevice(QIODevice* device, QByteArray& data)
if (readResult == -1) { if (readResult == -1) {
return false; return false;
} } else {
else {
result.resize(static_cast<int>(readBytes)); result.resize(static_cast<int>(readBytes));
data = result; data = result;
return true; return true;
} }
} }
QString imageReaderFilter() QString imageReaderFilter()
{ {
const QList<QByteArray> formats = QImageReader::supportedImageFormats(); const QList<QByteArray> formats = QImageReader::supportedImageFormats();
QStringList formatsStringList; QStringList formatsStringList;
@ -139,31 +141,31 @@ QString imageReaderFilter()
} }
return formatsStringList.join(" "); return formatsStringList.join(" ");
} }
bool isHex(const QByteArray& ba) bool isHex(const QByteArray& ba)
{ {
for (char c : ba) { for (char c : ba) {
if ( !( (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') ) ) { if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))) {
return false; return false;
} }
} }
return true; return true;
} }
bool isBase64(const QByteArray& ba) bool isBase64(const QByteArray& ba)
{ {
QRegExp regexp("^(?:[a-z0-9+/]{4})*(?:[a-z0-9+/]{3}=|[a-z0-9+/]{2}==)?$", QRegExp regexp(
Qt::CaseInsensitive, QRegExp::RegExp2); "^(?:[a-z0-9+/]{4})*(?:[a-z0-9+/]{3}=|[a-z0-9+/]{2}==)?$", Qt::CaseInsensitive, QRegExp::RegExp2);
QString base64 = QString::fromLatin1(ba.constData(), ba.size()); QString base64 = QString::fromLatin1(ba.constData(), ba.size());
return regexp.exactMatch(base64); return regexp.exactMatch(base64);
} }
void sleep(int ms) void sleep(int ms)
{ {
Q_ASSERT(ms >= 0); Q_ASSERT(ms >= 0);
if (ms == 0) { if (ms == 0) {
@ -178,10 +180,10 @@ void sleep(int ms)
ts.tv_nsec = (ms % 1000) * 1000 * 1000; ts.tv_nsec = (ms % 1000) * 1000 * 1000;
nanosleep(&ts, nullptr); nanosleep(&ts, nullptr);
#endif #endif
} }
void wait(int ms) void wait(int ms)
{ {
Q_ASSERT(ms >= 0); Q_ASSERT(ms >= 0);
if (ms == 0) { if (ms == 0) {
@ -194,8 +196,7 @@ void wait(int ms)
if (ms <= 50) { if (ms <= 50) {
QCoreApplication::processEvents(QEventLoop::AllEvents, ms); QCoreApplication::processEvents(QEventLoop::AllEvents, ms);
sleep(qMax(ms - static_cast<int>(timer.elapsed()), 0)); sleep(qMax(ms - static_cast<int>(timer.elapsed()), 0));
} } else {
else {
int timeLeft; int timeLeft;
do { do {
timeLeft = ms - timer.elapsed(); timeLeft = ms - timer.elapsed();
@ -205,10 +206,10 @@ void wait(int ms)
} }
} while (!timer.hasExpired(ms)); } while (!timer.hasExpired(ms));
} }
} }
void disableCoreDumps() void disableCoreDumps()
{ {
// default to true // default to true
// there is no point in printing a warning if this is not implemented on the platform // there is no point in printing a warning if this is not implemented on the platform
bool success = true; bool success = true;
@ -224,7 +225,7 @@ void disableCoreDumps()
success = success && (prctl(PR_SET_DUMPABLE, 0) == 0); success = success && (prctl(PR_SET_DUMPABLE, 0) == 0);
#endif #endif
// Mac OS X // Mac OS X
#ifdef HAVE_PT_DENY_ATTACH #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 #endif
@ -236,28 +237,28 @@ void disableCoreDumps()
if (!success) { if (!success) {
qWarning("Unable to disable core dumps."); qWarning("Unable to disable core dumps.");
} }
} }
void setupSearchPaths() void setupSearchPaths()
{ {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
// Make sure Windows doesn't load DLLs from the current working directory // Make sure Windows doesn't load DLLs from the current working directory
SetDllDirectoryA(""); SetDllDirectoryA("");
SetSearchPathMode(BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE); SetSearchPathMode(BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE);
#endif #endif
} }
// //
// This function grants the user associated with the process token minimal access rights and // 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 // denies everything else on Windows. This includes PROCESS_QUERY_INFORMATION and
// PROCESS_VM_READ access rights that are required for MiniDumpWriteDump() or ReadProcessMemory(). // 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 // 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 // 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 // as you do not have admin privileges, since then you are able to grant yourself the
// SeDebugPrivilege or SeTakeOwnershipPrivilege and circumvent the DACL. // SeDebugPrivilege or SeTakeOwnershipPrivilege and circumvent the DACL.
// //
bool createWindowsDACL() bool createWindowsDACL()
{ {
bool bSuccess = false; bool bSuccess = false;
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
@ -271,35 +272,19 @@ bool createWindowsDACL()
DWORD cbACL = 0; DWORD cbACL = 0;
// Open the access token associated with the calling process // Open the access token associated with the calling process
if (!OpenProcessToken( if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) {
GetCurrentProcess(),
TOKEN_QUERY,
&hToken
)) {
goto Cleanup; goto Cleanup;
} }
// Retrieve the token information in a TOKEN_USER structure // Retrieve the token information in a TOKEN_USER structure
GetTokenInformation( GetTokenInformation(hToken, TokenUser, nullptr, 0, &cbBufferSize);
hToken,
TokenUser,
nullptr,
0,
&cbBufferSize
);
pTokenUser = static_cast<PTOKEN_USER>(HeapAlloc(GetProcessHeap(), 0, cbBufferSize)); pTokenUser = static_cast<PTOKEN_USER>(HeapAlloc(GetProcessHeap(), 0, cbBufferSize));
if (pTokenUser == nullptr) { if (pTokenUser == nullptr) {
goto Cleanup; goto Cleanup;
} }
if (!GetTokenInformation( if (!GetTokenInformation(hToken, TokenUser, pTokenUser, cbBufferSize, &cbBufferSize)) {
hToken,
TokenUser,
pTokenUser,
cbBufferSize,
&cbBufferSize
)) {
goto Cleanup; goto Cleanup;
} }
@ -308,8 +293,7 @@ bool createWindowsDACL()
} }
// Calculate the amount of memory that must be allocated for the DACL // Calculate the amount of memory that must be allocated for the DACL
cbACL = sizeof(ACL) cbACL = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pTokenUser->User.Sid);
+ sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pTokenUser->User.Sid);
// Create and initialize an ACL // Create and initialize an ACL
pACL = static_cast<PACL>(HeapAlloc(GetProcessHeap(), 0, cbACL)); pACL = static_cast<PACL>(HeapAlloc(GetProcessHeap(), 0, cbACL));
@ -332,16 +316,16 @@ bool createWindowsDACL()
} }
// Set discretionary access control list // Set discretionary access control list
bSuccess = ERROR_SUCCESS == SetSecurityInfo( bSuccess = ERROR_SUCCESS == SetSecurityInfo(GetCurrentProcess(), // object handle
GetCurrentProcess(), // object handle
SE_KERNEL_OBJECT, // type of object SE_KERNEL_OBJECT, // type of object
DACL_SECURITY_INFORMATION, // change only the objects DACL DACL_SECURITY_INFORMATION, // change only the objects DACL
nullptr, nullptr, // do not change owner or group nullptr,
nullptr, // do not change owner or group
pACL, // DACL specified pACL, // DACL specified
nullptr // do not change SACL nullptr // do not change SACL
); );
Cleanup: Cleanup:
if (pACL != nullptr) { if (pACL != nullptr) {
HeapFree(GetProcessHeap(), 0, pACL); HeapFree(GetProcessHeap(), 0, pACL);
@ -355,6 +339,6 @@ Cleanup:
#endif #endif
return bSuccess; return bSuccess;
} }
} // namespace Tools } // namespace Tools

View File

@ -29,33 +29,33 @@
class QIODevice; class QIODevice;
namespace Tools { namespace Tools
QString humanReadableFileSize(qint64 bytes);
bool hasChild(const QObject* parent, const QObject* child);
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);
void disableCoreDumps();
void setupSearchPaths();
bool createWindowsDACL();
template <typename RandomAccessIterator, typename T>
RandomAccessIterator binaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T& value)
{ {
QString humanReadableFileSize(qint64 bytes);
bool hasChild(const QObject* parent, const QObject* child);
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);
void disableCoreDumps();
void setupSearchPaths();
bool createWindowsDACL();
template <typename RandomAccessIterator, typename T>
RandomAccessIterator binaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T& value)
{
RandomAccessIterator it = std::lower_bound(begin, end, value); RandomAccessIterator it = std::lower_bound(begin, end, value);
if ((it == end) || (value < *it)) { if ((it == end) || (value < *it)) {
return end; return end;
} } else {
else {
return it; return it;
} }
} }
} // namespace Tools } // namespace Tools

View File

@ -22,8 +22,8 @@
#include <QDir> #include <QDir>
#include <QLibraryInfo> #include <QLibraryInfo>
#include <QLocale> #include <QLocale>
#include <QTranslator>
#include <QRegularExpression> #include <QRegularExpression>
#include <QTranslator>
#include "config-keepassx.h" #include "config-keepassx.h"
#include "core/Config.h" #include "core/Config.h"
@ -47,8 +47,7 @@ void Translator::installTranslators()
#ifdef QT_DEBUG #ifdef QT_DEBUG
QString("%1/share/translations").arg(KEEPASSX_BINARY_DIR), QString("%1/share/translations").arg(KEEPASSX_BINARY_DIR),
#endif #endif
filePath()->dataPath("translations") filePath()->dataPath("translations")};
};
bool translationsLoaded = false; bool translationsLoaded = false;
for (const QString& path : paths) { for (const QString& path : paths) {
@ -72,10 +71,9 @@ QList<QPair<QString, QString>> Translator::availableLanguages()
#ifdef QT_DEBUG #ifdef QT_DEBUG
QString("%1/share/translations").arg(KEEPASSX_BINARY_DIR), QString("%1/share/translations").arg(KEEPASSX_BINARY_DIR),
#endif #endif
filePath()->dataPath("translations") filePath()->dataPath("translations")};
};
QList<QPair<QString, QString> > languages; QList<QPair<QString, QString>> languages;
languages.append(QPair<QString, QString>("system", "System default")); languages.append(QPair<QString, QString>("system", "System default"));
QRegularExpression regExp("^keepassx_([a-zA-Z_]+)\\.qm$", QRegularExpression::CaseInsensitiveOption); QRegularExpression regExp("^keepassx_([a-zA-Z_]+)\\.qm$", QRegularExpression::CaseInsensitiveOption);
@ -138,7 +136,8 @@ bool Translator::installQtTranslator(const QString& language, const QString& pat
QScopedPointer<QTranslator> qtTranslator(new QTranslator(qApp)); QScopedPointer<QTranslator> qtTranslator(new QTranslator(qApp));
if (qtTranslator->load(QString("qtbase_%1").arg(language), path)) { if (qtTranslator->load(QString("qtbase_%1").arg(language), path)) {
return QCoreApplication::installTranslator(qtTranslator.take()); return QCoreApplication::installTranslator(qtTranslator.take());
} else if (qtTranslator->load(QString("qtbase_%1").arg(language), QLibraryInfo::location(QLibraryInfo::TranslationsPath))) { } else if (qtTranslator->load(QString("qtbase_%1").arg(language),
QLibraryInfo::location(QLibraryInfo::TranslationsPath))) {
return QCoreApplication::installTranslator(qtTranslator.take()); return QCoreApplication::installTranslator(qtTranslator.take());
} }
return false; return false;

View File

@ -22,8 +22,8 @@
#include "crypto/Random.h" #include "crypto/Random.h"
const int Uuid::Length = 16; const int Uuid::Length = 16;
const QRegExp Uuid::HexRegExp = QRegExp(QString("^[0-9A-F]{%1}$").arg(QString::number(Uuid::Length * 2)), const QRegExp Uuid::HexRegExp =
Qt::CaseInsensitive); QRegExp(QString("^[0-9A-F]{%1}$").arg(QString::number(Uuid::Length * 2)), Qt::CaseInsensitive);
Uuid::Uuid() Uuid::Uuid()
: m_data(Length, 0) : m_data(Length, 0)

View File

@ -19,8 +19,8 @@
#define KEEPASSX_UUID_H #define KEEPASSX_UUID_H
#include <QByteArray> #include <QByteArray>
#include <QString>
#include <QRegExp> #include <QRegExp>
#include <QString>
class Uuid class Uuid
{ {

View File

@ -116,7 +116,8 @@ bool Crypto::checkAlgorithms()
bool Crypto::selfTest() bool Crypto::selfTest()
{ {
return testSha256() && testSha512() && testAes256Cbc() && testAes256Ecb() && testTwofish() && testSalsa20() && testChaCha20(); return testSha256() && testSha512() && testAes256Cbc() && testAes256Ecb() && testTwofish() && testSalsa20()
&& testChaCha20();
} }
void Crypto::raiseError(const QString& str) void Crypto::raiseError(const QString& str)
@ -127,8 +128,8 @@ void Crypto::raiseError(const QString& str)
bool Crypto::testSha256() bool Crypto::testSha256()
{ {
QByteArray sha256Test = CryptoHash::hash("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", QByteArray sha256Test =
CryptoHash::Sha256); CryptoHash::hash("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", CryptoHash::Sha256);
if (sha256Test != QByteArray::fromHex("248D6A61D20638B8E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1")) { if (sha256Test != QByteArray::fromHex("248D6A61D20638B8E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1")) {
raiseError("SHA-256 mismatch."); raiseError("SHA-256 mismatch.");
@ -140,10 +141,11 @@ bool Crypto::testSha256()
bool Crypto::testSha512() bool Crypto::testSha512()
{ {
QByteArray sha512Test = CryptoHash::hash("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", QByteArray sha512Test =
CryptoHash::Sha512); CryptoHash::hash("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", CryptoHash::Sha512);
if (sha512Test != QByteArray::fromHex("204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445")) { if (sha512Test != QByteArray::fromHex("204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b"
"07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445")) {
raiseError("SHA-512 mismatch."); raiseError("SHA-512 mismatch.");
return false; return false;
} }
@ -262,7 +264,6 @@ bool Crypto::testTwofish()
return false; return false;
} }
SymmetricCipher twofishDecrypt(SymmetricCipher::Twofish, SymmetricCipher::Cbc, SymmetricCipher::Decrypt); SymmetricCipher twofishDecrypt(SymmetricCipher::Twofish, SymmetricCipher::Cbc, SymmetricCipher::Decrypt);
if (!twofishDecrypt.init(key, iv)) { if (!twofishDecrypt.init(key, iv)) {
raiseError(twofishEncrypt.errorString()); raiseError(twofishEncrypt.errorString());
@ -289,8 +290,7 @@ bool Crypto::testSalsa20()
QByteArray salsa20Cipher = QByteArray::fromHex("B4C0AFA503BE7FC29A62058166D56F8F"); QByteArray salsa20Cipher = QByteArray::fromHex("B4C0AFA503BE7FC29A62058166D56F8F");
bool ok; bool ok;
SymmetricCipher salsa20Stream(SymmetricCipher::Salsa20, SymmetricCipher::Stream, SymmetricCipher salsa20Stream(SymmetricCipher::Salsa20, SymmetricCipher::Stream, SymmetricCipher::Encrypt);
SymmetricCipher::Encrypt);
if (!salsa20Stream.init(salsa20Key, salsa20iv)) { if (!salsa20Stream.init(salsa20Key, salsa20iv)) {
raiseError(salsa20Stream.errorString()); raiseError(salsa20Stream.errorString());
return false; return false;
@ -309,15 +309,17 @@ bool Crypto::testSalsa20()
return true; return true;
} }
bool Crypto::testChaCha20() { bool Crypto::testChaCha20()
{
QByteArray chacha20Key = QByteArray::fromHex("0000000000000000000000000000000000000000000000000000000000000000"); QByteArray chacha20Key = QByteArray::fromHex("0000000000000000000000000000000000000000000000000000000000000000");
QByteArray chacha20iv = QByteArray::fromHex("0000000000000000"); QByteArray chacha20iv = QByteArray::fromHex("0000000000000000");
QByteArray chacha20Plain = QByteArray::fromHex("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"); QByteArray chacha20Plain = QByteArray::fromHex("0000000000000000000000000000000000000000000000000000000000000000000"
QByteArray chacha20Cipher = QByteArray::fromHex("76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7da41597c5157488d7724e03fb8d84a376a43b8f41518a11cc387b669b2ee6586"); "0000000000000000000000000000000000000000000000000000000000000");
QByteArray chacha20Cipher = QByteArray::fromHex("76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7da"
"41597c5157488d7724e03fb8d84a376a43b8f41518a11cc387b669b2ee6586");
bool ok; bool ok;
SymmetricCipher chacha20Stream(SymmetricCipher::ChaCha20, SymmetricCipher::Stream, SymmetricCipher chacha20Stream(SymmetricCipher::ChaCha20, SymmetricCipher::Stream, SymmetricCipher::Encrypt);
SymmetricCipher::Encrypt);
if (!chacha20Stream.init(chacha20Key, chacha20iv)) { if (!chacha20Stream.init(chacha20Key, chacha20iv)) {
raiseError(chacha20Stream.errorString()); raiseError(chacha20Stream.errorString());
return false; return false;

View File

@ -89,7 +89,6 @@ Random::Random(RandomBackend* backend)
{ {
} }
void RandomBackendGcrypt::randomize(void* data, int len) void RandomBackendGcrypt::randomize(void* data, int len)
{ {
Q_ASSERT(Crypto::initalized()); Q_ASSERT(Crypto::initalized());

View File

@ -25,7 +25,9 @@ class RandomBackend
{ {
public: public:
virtual void randomize(void* data, int len) = 0; virtual void randomize(void* data, int len) = 0;
virtual ~RandomBackend() {} virtual ~RandomBackend()
{
}
}; };
class Random class Random
@ -56,7 +58,8 @@ private:
Q_DISABLE_COPY(Random) Q_DISABLE_COPY(Random)
}; };
inline Random* randomGen() { inline Random* randomGen()
{
return Random::instance(); return Random::instance();
} }

View File

@ -22,9 +22,9 @@
#include <QScopedPointer> #include <QScopedPointer>
#include <QString> #include <QString>
#include "core/Uuid.h"
#include "crypto/SymmetricCipherBackend.h" #include "crypto/SymmetricCipherBackend.h"
#include "format/KeePass2.h" #include "format/KeePass2.h"
#include "core/Uuid.h"
class SymmetricCipher class SymmetricCipher
{ {

View File

@ -23,7 +23,9 @@
class SymmetricCipherBackend class SymmetricCipherBackend
{ {
public: public:
virtual ~SymmetricCipherBackend() {} virtual ~SymmetricCipherBackend()
{
}
virtual bool init() = 0; virtual bool init() = 0;
virtual bool setKey(const QByteArray& key) = 0; virtual bool setKey(const QByteArray& key) = 0;
virtual bool setIv(const QByteArray& iv) = 0; virtual bool setIv(const QByteArray& iv) = 0;

View File

@ -20,7 +20,8 @@
#include "config-keepassx.h" #include "config-keepassx.h"
#include "crypto/Crypto.h" #include "crypto/Crypto.h"
SymmetricCipherGcrypt::SymmetricCipherGcrypt(SymmetricCipher::Algorithm algo, SymmetricCipher::Mode mode, SymmetricCipherGcrypt::SymmetricCipherGcrypt(SymmetricCipher::Algorithm algo,
SymmetricCipher::Mode mode,
SymmetricCipher::Direction direction) SymmetricCipher::Direction direction)
: m_ctx(nullptr) : m_ctx(nullptr)
, m_algo(gcryptAlgo(algo)) , m_algo(gcryptAlgo(algo))
@ -84,8 +85,8 @@ void SymmetricCipherGcrypt::setErrorString(gcry_error_t err)
const char* gcryptError = gcry_strerror(err); const char* gcryptError = gcry_strerror(err);
const char* gcryptErrorSource = gcry_strsource(err); const char* gcryptErrorSource = gcry_strsource(err);
m_errorString = QString("%1/%2").arg(QString::fromLocal8Bit(gcryptErrorSource), m_errorString =
QString::fromLocal8Bit(gcryptError)); QString("%1/%2").arg(QString::fromLocal8Bit(gcryptErrorSource), QString::fromLocal8Bit(gcryptError));
} }
bool SymmetricCipherGcrypt::init() bool SymmetricCipherGcrypt::init()
@ -94,7 +95,7 @@ bool SymmetricCipherGcrypt::init()
gcry_error_t error; gcry_error_t error;
if(m_ctx != nullptr) if (m_ctx != nullptr)
gcry_cipher_close(m_ctx); gcry_cipher_close(m_ctx);
error = gcry_cipher_open(&m_ctx, m_algo, m_mode, 0); error = gcry_cipher_open(&m_ctx, m_algo, m_mode, 0);
if (error != 0) { if (error != 0) {

View File

@ -23,10 +23,11 @@
#include "crypto/SymmetricCipher.h" #include "crypto/SymmetricCipher.h"
#include "crypto/SymmetricCipherBackend.h" #include "crypto/SymmetricCipherBackend.h"
class SymmetricCipherGcrypt: public SymmetricCipherBackend class SymmetricCipherGcrypt : public SymmetricCipherBackend
{ {
public: public:
SymmetricCipherGcrypt(SymmetricCipher::Algorithm algo, SymmetricCipher::Mode mode, SymmetricCipherGcrypt(SymmetricCipher::Algorithm algo,
SymmetricCipher::Mode mode,
SymmetricCipher::Direction direction); SymmetricCipher::Direction direction);
~SymmetricCipherGcrypt(); ~SymmetricCipherGcrypt();

View File

@ -31,4 +31,4 @@
#include <argon2.h> #include <argon2.h>
#endif //KEEPASSXC_CRYPTO_ARGON2_H #endif // KEEPASSXC_CRYPTO_ARGON2_H

View File

@ -19,8 +19,8 @@
#include <QtConcurrent> #include <QtConcurrent>
#include "format/KeePass2.h"
#include "crypto/CryptoHash.h" #include "crypto/CryptoHash.h"
#include "format/KeePass2.h"
AesKdf::AesKdf() AesKdf::AesKdf()
: Kdf::Kdf(KeePass2::KDF_AES_KDBX4) : Kdf::Kdf(KeePass2::KDF_AES_KDBX4)
@ -35,7 +35,7 @@ AesKdf::AesKdf(bool legacyKdbx3)
{ {
} }
bool AesKdf::processParameters(const QVariantMap &p) bool AesKdf::processParameters(const QVariantMap& p)
{ {
bool ok; bool ok;
int rounds = p.value(KeePass2::KDFPARAM_AES_ROUNDS).toInt(&ok); int rounds = p.value(KeePass2::KDFPARAM_AES_ROUNDS).toInt(&ok);
@ -84,8 +84,7 @@ bool AesKdf::transform(const QByteArray& raw, QByteArray& result) const
bool AesKdf::transformKeyRaw(const QByteArray& key, const QByteArray& seed, int rounds, QByteArray* result) bool AesKdf::transformKeyRaw(const QByteArray& key, const QByteArray& seed, int rounds, QByteArray* result)
{ {
QByteArray iv(16, 0); QByteArray iv(16, 0);
SymmetricCipher cipher(SymmetricCipher::Aes256, SymmetricCipher::Ecb, SymmetricCipher cipher(SymmetricCipher::Aes256, SymmetricCipher::Ecb, SymmetricCipher::Encrypt);
SymmetricCipher::Encrypt);
if (!cipher.init(seed, iv)) { if (!cipher.init(seed, iv)) {
qWarning("AesKdf::transformKeyRaw: error in SymmetricCipher::init: %s", cipher.errorString().toUtf8().data()); qWarning("AesKdf::transformKeyRaw: error in SymmetricCipher::init: %s", cipher.errorString().toUtf8().data());
return false; return false;

View File

@ -20,7 +20,7 @@
#include "Kdf.h" #include "Kdf.h"
class AesKdf: public Kdf class AesKdf : public Kdf
{ {
public: public:
AesKdf(); AesKdf();
@ -35,10 +35,8 @@ protected:
int benchmarkImpl(int msec) const override; int benchmarkImpl(int msec) const override;
private: private:
static bool transformKeyRaw(const QByteArray& key, static bool
const QByteArray& seed, transformKeyRaw(const QByteArray& key, const QByteArray& seed, int rounds, QByteArray* result) Q_REQUIRED_RESULT;
int rounds,
QByteArray* result) Q_REQUIRED_RESULT;
}; };
#endif // KEEPASSX_AESKDF_H #endif // KEEPASSX_AESKDF_H

View File

@ -86,7 +86,7 @@ bool Argon2Kdf::setParallelism(quint32 threads)
return false; return false;
} }
bool Argon2Kdf::processParameters(const QVariantMap &p) bool Argon2Kdf::processParameters(const QVariantMap& p)
{ {
QByteArray salt = p.value(KeePass2::KDFPARAM_ARGON2_SALT).toByteArray(); QByteArray salt = p.value(KeePass2::KDFPARAM_ARGON2_SALT).toByteArray();
if (!setSeed(salt)) { if (!setSeed(salt)) {
@ -161,13 +161,28 @@ bool Argon2Kdf::transform(const QByteArray& raw, QByteArray& result) const
return transformKeyRaw(raw, seed(), version(), rounds(), memory(), parallelism(), result); return transformKeyRaw(raw, seed(), version(), rounds(), memory(), parallelism(), result);
} }
bool Argon2Kdf::transformKeyRaw(const QByteArray& key, const QByteArray& seed, quint32 version, bool Argon2Kdf::transformKeyRaw(const QByteArray& key,
quint32 rounds, quint64 memory, quint32 parallelism, QByteArray& result) const QByteArray& seed,
quint32 version,
quint32 rounds,
quint64 memory,
quint32 parallelism,
QByteArray& result)
{ {
// Time Cost, Mem Cost, Threads/Lanes, Password, length, Salt, length, out, length // Time Cost, Mem Cost, Threads/Lanes, Password, length, Salt, length, out, length
int rc = argon2_hash(rounds, memory, parallelism, key.data(), key.size(), int rc = argon2_hash(rounds,
seed.data(), seed.size(), result.data(), result.size(), memory,
nullptr, 0, Argon2_d, version); parallelism,
key.data(),
key.size(),
seed.data(),
seed.size(),
result.data(),
result.size(),
nullptr,
0,
Argon2_d,
version);
if (rc != ARGON2_OK) { if (rc != ARGON2_OK) {
qWarning("Argon2 error: %s", argon2_error_message(rc)); qWarning("Argon2 error: %s", argon2_error_message(rc));
return false; return false;

View File

@ -20,7 +20,8 @@
#include "Kdf.h" #include "Kdf.h"
class Argon2Kdf : public Kdf { class Argon2Kdf : public Kdf
{
public: public:
Argon2Kdf(); Argon2Kdf();

View File

@ -55,7 +55,6 @@ protected:
private: private:
class BenchmarkThread; class BenchmarkThread;
const Uuid m_uuid; const Uuid m_uuid;
}; };
#endif // KEEPASSX_KDF_H #endif // KEEPASSX_KDF_H

View File

@ -22,9 +22,9 @@
#ifndef KEEPASSXC_KDF_P_H #ifndef KEEPASSXC_KDF_P_H
#define KEEPASSXC_KDF_P_H #define KEEPASSXC_KDF_P_H
class Kdf::BenchmarkThread: public QThread class Kdf::BenchmarkThread : public QThread
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit BenchmarkThread(int msec, const Kdf* kdf); explicit BenchmarkThread(int msec, const Kdf* kdf);

Some files were not shown because too many files have changed in this diff Show More