Merge branch 'develop' into feature/yubikey

This commit is contained in:
Janek Bevendorff 2017-03-01 23:37:52 +01:00
commit 7eb7dbe0be
No known key found for this signature in database
GPG Key ID: CFEC2F6850BFFA53
11 changed files with 69 additions and 40 deletions

View File

@ -3,22 +3,23 @@
[![Travis Build Status](https://travis-ci.org/keepassxreboot/keepassxc.svg?branch=develop)](https://travis-ci.org/keepassxreboot/keepassxc) [![Coverage Status](https://coveralls.io/repos/github/keepassxreboot/keepassxc/badge.svg)](https://coveralls.io/github/keepassxreboot/keepassxc) [![Travis Build Status](https://travis-ci.org/keepassxreboot/keepassxc.svg?branch=develop)](https://travis-ci.org/keepassxreboot/keepassxc) [![Coverage Status](https://coveralls.io/repos/github/keepassxreboot/keepassxc/badge.svg)](https://coveralls.io/github/keepassxreboot/keepassxc)
## About ## About
KeePassXC is a fork of [KeePassX](https://www.keepassx.org/) that [aims to incorporate stalled pull requests, features, and bug fixes that have never made it into the main KeePassX repository](https://github.com/keepassxreboot/keepassx/issues/43). KeePassXC is a community fork of [KeePassX](https://www.keepassx.org/) with the goal to extend and improve it with new features and bugfixes to provide a feature-rich, fully cross-platform and modern open-source password manager.
## Additional features compared to KeePassX ## Additional features compared to KeePassX
- Autotype on all three major platforms (Linux, Windows, OS X) - Auto-Type on all three major platforms (Linux, Windows, OS X)
- Stand-alone password generator - Stand-alone password generator
- Password strength meter - Password strength meter
- Use website's favicons as entry icons - Using website favicons as entry icons
- Merging of databases - Merging of databases
- Automatic reload when the database changed on disk - Automatic reload when the database changed on disk
- KeePassHTTP support for use with [PassIFox](https://addons.mozilla.org/en-us/firefox/addon/passifox/) in Mozilla Firefox and [chromeIPass](https://chrome.google.com/webstore/detail/chromeipass/ompiailgknfdndiefoaoiligalphfdae) in Google Chrome or Chromium. - KeePassHTTP support for use with [PassIFox](https://addons.mozilla.org/en-us/firefox/addon/passifox/) in Mozilla Firefox and [chromeIPass](https://chrome.google.com/webstore/detail/chromeipass/ompiailgknfdndiefoaoiligalphfdae) in Google Chrome or Chromium.
- Many bug fixes
For a full list of features and changes, read the [CHANGELOG](CHANGELOG) document. For a full list of features and changes, read the [CHANGELOG](CHANGELOG) document.
### Note about KeePassHTTP ### Note about KeePassHTTP
KeePassHTTP is not a highly secure protocol and has certain flaw which allow an attacker to decrypt your passwords when they manage to intercept communication between a KeePassHTTP server and PassIFox/chromeIPass over a network connection (see [here](https://github.com/pfn/keepasshttp/issues/258) and [here](https://github.com/keepassxreboot/keepassxc/issues/147)). KeePassXC therefore strictly limits communication between itself and the browser plugin to your local computer. As long as your computer is not compromised, your passwords are fairly safe that way, but still use it at your own risk! KeePassHTTP is not a highly secure protocol and has certain flaw which allow an attacker to decrypt your passwords when they manage to intercept communication between a KeePassHTTP server and PassIFox/chromeIPass over a network connection (see [here](https://github.com/pfn/keepasshttp/issues/258) and [here](https://github.com/keepassxreboot/keepassxc/issues/147)). KeePassXC therefore strictly limits communication between itself and the browser plugin to your local computer. As long as your computer is not compromised, your passwords are fairly safe that way, but use it at your own risk!
### Installation ### Installation
Pre-compiled binaries can be found on the [downloads page](https://keepassxc.org/download). Additionally, individual Linux distributions may ship their own versions, so please check out your distribution's package list to see if KeePassXC is available. Pre-compiled binaries can be found on the [downloads page](https://keepassxc.org/download). Additionally, individual Linux distributions may ship their own versions, so please check out your distribution's package list to see if KeePassXC is available.

View File

@ -166,7 +166,7 @@ void DatabaseTabWidget::openDatabase(const QString& fileName, const QString& pw,
msgBox.setIcon(QMessageBox::Question); msgBox.setIcon(QMessageBox::Question);
msgBox.addButton(QMessageBox::Yes); msgBox.addButton(QMessageBox::Yes);
msgBox.addButton(QMessageBox::No); msgBox.addButton(QMessageBox::No);
auto readOnlyButton = msgBox.addButton(tr("Open read-only"), QMessageBox::AcceptRole); auto readOnlyButton = msgBox.addButton(tr("Open read-only"), QMessageBox::NoRole);
msgBox.setDefaultButton(readOnlyButton); msgBox.setDefaultButton(readOnlyButton);
msgBox.setEscapeButton(QMessageBox::No); msgBox.setEscapeButton(QMessageBox::No);
auto result = msgBox.exec(); auto result = msgBox.exec();

View File

@ -273,50 +273,74 @@ void EditWidgetIcons::removeCustomIcon()
QModelIndex index = m_ui->customIconsView->currentIndex(); QModelIndex index = m_ui->customIconsView->currentIndex();
if (index.isValid()) { if (index.isValid()) {
Uuid iconUuid = m_customIconModel->uuidFromIndex(index); Uuid iconUuid = m_customIconModel->uuidFromIndex(index);
int iconUsedCount = 0;
const QList<Entry*> allEntries = m_database->rootGroup()->entriesRecursive(true); const QList<Entry*> allEntries = m_database->rootGroup()->entriesRecursive(true);
QList<Entry*> entriesWithSameIcon;
QList<Entry*> historyEntriesWithSameIcon; QList<Entry*> historyEntriesWithSameIcon;
for (Entry* entry : allEntries) { for (Entry* entry : allEntries) {
bool isHistoryEntry = !entry->group();
if (iconUuid == entry->iconUuid()) { if (iconUuid == entry->iconUuid()) {
if (isHistoryEntry) { // Check if this is a history entry (no assigned group)
if (!entry->group()) {
historyEntriesWithSameIcon << entry; historyEntriesWithSameIcon << entry;
} } else if (m_currentUuid != entry->uuid()) {
else if (m_currentUuid != entry->uuid()) { entriesWithSameIcon << entry;
iconUsedCount++;
} }
} }
} }
const QList<Group*> allGroups = m_database->rootGroup()->groupsRecursive(true); const QList<Group*> allGroups = m_database->rootGroup()->groupsRecursive(true);
for (const Group* group : allGroups) { QList<Group*> groupsWithSameIcon;
for (Group* group : allGroups) {
if (iconUuid == group->iconUuid() && m_currentUuid != group->uuid()) { if (iconUuid == group->iconUuid() && m_currentUuid != group->uuid()) {
iconUsedCount++; groupsWithSameIcon << group;
} }
} }
if (iconUsedCount == 0) { int iconUseCount = entriesWithSameIcon.size() + groupsWithSameIcon.size();
if (iconUseCount > 0) {
QMessageBox::StandardButton ans = MessageBox::question(this, tr("Confirm Delete"),
tr("This icon is used by %1 entries, and will be replaced "
"by the default icon. Are you sure you want to delete it?")
.arg(iconUseCount), QMessageBox::Yes | QMessageBox::No);
if (ans == QMessageBox::No) {
// Early out, nothing is changed
return;
} else {
// Revert matched entries to the default entry icon
for (Entry* entry : asConst(entriesWithSameIcon)) {
entry->setIcon(Entry::DefaultIconNumber);
}
// Revert matched groups to the default group icon
for (Group* group : asConst(groupsWithSameIcon)) {
group->setIcon(Group::DefaultIconNumber);
}
}
}
// Remove the icon from history entries
for (Entry* entry : asConst(historyEntriesWithSameIcon)) { for (Entry* entry : asConst(historyEntriesWithSameIcon)) {
entry->setUpdateTimeinfo(false); entry->setUpdateTimeinfo(false);
entry->setIcon(0); entry->setIcon(0);
entry->setUpdateTimeinfo(true); entry->setUpdateTimeinfo(true);
} }
// Remove the icon from the database
m_database->metadata()->removeCustomIcon(iconUuid); m_database->metadata()->removeCustomIcon(iconUuid);
m_customIconModel->setIcons(m_database->metadata()->customIconsScaledPixmaps(), m_customIconModel->setIcons(m_database->metadata()->customIconsScaledPixmaps(),
m_database->metadata()->customIconsOrder()); m_database->metadata()->customIconsOrder());
if (m_customIconModel->rowCount() > 0) {
m_ui->customIconsView->setCurrentIndex(m_customIconModel->index(0, 0)); // Reset the current icon view
}
else {
updateRadioButtonDefaultIcons(); updateRadioButtonDefaultIcons();
}
} if (m_database->resolveEntry(m_currentUuid) != nullptr) {
else { m_ui->defaultIconsView->setCurrentIndex(m_defaultIconModel->index(Entry::DefaultIconNumber));
Q_EMIT messageEditEntry( } else {
tr("Can't delete icon. Still used by %1 items.").arg(iconUsedCount), MessageWidget::Error); m_ui->defaultIconsView->setCurrentIndex(m_defaultIconModel->index(Group::DefaultIconNumber));
} }
} }
} }

View File

@ -302,6 +302,10 @@ MainWindow::MainWindow()
connect(m_ui->actionAbout, SIGNAL(triggered()), SLOT(showAboutDialog())); connect(m_ui->actionAbout, SIGNAL(triggered()), SLOT(showAboutDialog()));
#ifdef Q_OS_MAC
setUnifiedTitleAndToolBarOnMac(true);
#endif
connect(m_ui->tabWidget, SIGNAL(messageGlobal(QString,MessageWidget::MessageType)), this, SLOT(displayGlobalMessage(QString, MessageWidget::MessageType))); connect(m_ui->tabWidget, SIGNAL(messageGlobal(QString,MessageWidget::MessageType)), this, SLOT(displayGlobalMessage(QString, MessageWidget::MessageType)));
connect(m_ui->tabWidget, SIGNAL(messageDismissGlobal()), this, SLOT(hideGlobalMessage())); connect(m_ui->tabWidget, SIGNAL(messageDismissGlobal()), this, SLOT(hideGlobalMessage()));
connect(m_ui->tabWidget, SIGNAL(messageTab(QString,MessageWidget::MessageType)), this, SLOT(displayTabMessage(QString, MessageWidget::MessageType))); connect(m_ui->tabWidget, SIGNAL(messageTab(QString,MessageWidget::MessageType)), this, SLOT(displayTabMessage(QString, MessageWidget::MessageType)));

View File

@ -110,7 +110,7 @@ static QByteArray encrypt2(const QByteArray & data, SymmetricCipherGcrypt & ciph
//Encrypt //Encrypt
QByteArray buffer = data + QByteArray(paddingSize, paddingSize); QByteArray buffer = data + QByteArray(paddingSize, paddingSize);
cipher.reset(); cipher.reset();
cipher.processInPlace(buffer); Q_UNUSED(cipher.processInPlace(buffer));
return buffer; return buffer;
} }

View File

@ -91,7 +91,7 @@ typedef int (*http_cb) (http_parser*);
/* Status Codes */ /* Status Codes */
#define HTTP_STATUS_MAP(XX) \ #define HTTPPARSER_HTTP_STATUS_MAP(XX) \
XX(100, CONTINUE, Continue) \ XX(100, CONTINUE, Continue) \
XX(101, SWITCHING_PROTOCOLS, Switching Protocols) \ XX(101, SWITCHING_PROTOCOLS, Switching Protocols) \
XX(102, PROCESSING, Processing) \ XX(102, PROCESSING, Processing) \
@ -150,12 +150,12 @@ typedef int (*http_cb) (http_parser*);
XX(507, INSUFFICIENT_STORAGE, Insufficient Storage) \ XX(507, INSUFFICIENT_STORAGE, Insufficient Storage) \
XX(508, LOOP_DETECTED, Loop Detected) \ XX(508, LOOP_DETECTED, Loop Detected) \
XX(510, NOT_EXTENDED, Not Extended) \ XX(510, NOT_EXTENDED, Not Extended) \
XX(511, NETWORK_AUTHENTICATION_REQUIRED, Network Authentication Required) \ XX(511, NETWORK_AUTHENTICATION_REQUIRED, Network Authentication Required)
enum http_status enum http_status
{ {
#define XX(num, name, string) HTTP_STATUS_##name = num, #define XX(num, name, string) HTTP_STATUS_##name = num,
HTTP_STATUS_MAP(XX) HTTPPARSER_HTTP_STATUS_MAP(XX)
#undef XX #undef XX
}; };

View File

@ -41,7 +41,7 @@ public:
if ( !icollectRequired ) // not allowed to collect data if ( !icollectRequired ) // not allowed to collect data
return false; return false;
int newLength = icollectedData.length() + (int) length; int newLength = icollectedData.length() + static_cast<int>(length);
if ( icollectCapacity > 0 && newLength > icollectCapacity ) if ( icollectCapacity > 0 && newLength > icollectCapacity )
return false; // the capacity is full return false; // the capacity is full

View File

@ -112,7 +112,7 @@ protected:
void onReadyRead() { void onReadyRead() {
while ( isocket.bytesAvailable() > 0 ) { while ( isocket.bytesAvailable() > 0 ) {
char buffer[4097] = {0}; char buffer[4097] = {0};
size_t readLength = (size_t) isocket.readRaw(buffer, 4096); size_t readLength = static_cast<size_t>(isocket.readRaw(buffer, 4096));
parse(buffer, readLength); parse(buffer, readLength);
} }

View File

@ -42,7 +42,7 @@ public:
// if it's a QLocalServer // if it's a QLocalServer
virtual void incomingConnection(quintptr socketDescriptor) { virtual void incomingConnection(quintptr socketDescriptor) {
iserver->incomingConnection((qintptr) socketDescriptor); iserver->incomingConnection(static_cast<qintptr>(socketDescriptor));
} }
}; };

View File

@ -83,7 +83,7 @@ public:
void onReadyRead() { void onReadyRead() {
while ( isocket.bytesAvailable() > 0 ) { while ( isocket.bytesAvailable() > 0 ) {
char buffer[4097] = {0}; char buffer[4097] = {0};
size_t readLength = (size_t) isocket.readRaw(buffer, 4096); size_t readLength = static_cast<size_t>(isocket.readRaw(buffer, 4096));
parse(buffer, readLength); parse(buffer, readLength);
} }

View File

@ -8,7 +8,7 @@ namespace qhttp {
# error "to compile QHttp classes, Qt 5.0 or later is needed." # error "to compile QHttp classes, Qt 5.0 or later is needed."
#endif #endif
#define HTTP_STATUS_MAP(XX) \ #define QHTTPABSTRACTS_HTTP_STATUS_MAP(XX) \
XX(100, "Continue") \ XX(100, "Continue") \
XX(101, "Switching Protocols") \ XX(101, "Switching Protocols") \
/* RFC 2518) obsoleted by RFC 4918 */ \ /* RFC 2518) obsoleted by RFC 4918 */ \
@ -78,7 +78,7 @@ static struct {
int code; int code;
const char* message; const char* message;
} g_status_codes[] { } g_status_codes[] {
HTTP_STATUS_MAP(PATCH_STATUS_CODES) QHTTPABSTRACTS_HTTP_STATUS_MAP(PATCH_STATUS_CODES)
}; };
#undef PATCH_STATUS_CODES #undef PATCH_STATUS_CODES