mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2024-12-27 00:09:53 -05:00
Merge branch 'develop' into feature/yubikey
This commit is contained in:
commit
7eb7dbe0be
@ -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)
|
||||
|
||||
## 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
|
||||
- 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
|
||||
- Password strength meter
|
||||
- Use website's favicons as entry icons
|
||||
- Using website favicons as entry icons
|
||||
- Merging of databases
|
||||
- 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.
|
||||
- Many bug fixes
|
||||
|
||||
For a full list of features and changes, read the [CHANGELOG](CHANGELOG) document.
|
||||
|
||||
### 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
|
||||
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.
|
||||
|
@ -166,7 +166,7 @@ void DatabaseTabWidget::openDatabase(const QString& fileName, const QString& pw,
|
||||
msgBox.setIcon(QMessageBox::Question);
|
||||
msgBox.addButton(QMessageBox::Yes);
|
||||
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.setEscapeButton(QMessageBox::No);
|
||||
auto result = msgBox.exec();
|
||||
|
@ -273,50 +273,74 @@ void EditWidgetIcons::removeCustomIcon()
|
||||
QModelIndex index = m_ui->customIconsView->currentIndex();
|
||||
if (index.isValid()) {
|
||||
Uuid iconUuid = m_customIconModel->uuidFromIndex(index);
|
||||
int iconUsedCount = 0;
|
||||
|
||||
const QList<Entry*> allEntries = m_database->rootGroup()->entriesRecursive(true);
|
||||
QList<Entry*> entriesWithSameIcon;
|
||||
QList<Entry*> historyEntriesWithSameIcon;
|
||||
|
||||
for (Entry* entry : allEntries) {
|
||||
bool isHistoryEntry = !entry->group();
|
||||
if (iconUuid == entry->iconUuid()) {
|
||||
if (isHistoryEntry) {
|
||||
// Check if this is a history entry (no assigned group)
|
||||
if (!entry->group()) {
|
||||
historyEntriesWithSameIcon << entry;
|
||||
}
|
||||
else if (m_currentUuid != entry->uuid()) {
|
||||
iconUsedCount++;
|
||||
} else if (m_currentUuid != entry->uuid()) {
|
||||
entriesWithSameIcon << entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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()) {
|
||||
iconUsedCount++;
|
||||
groupsWithSameIcon << group;
|
||||
}
|
||||
}
|
||||
|
||||
if (iconUsedCount == 0) {
|
||||
for (Entry* entry : asConst(historyEntriesWithSameIcon)) {
|
||||
entry->setUpdateTimeinfo(false);
|
||||
entry->setIcon(0);
|
||||
entry->setUpdateTimeinfo(true);
|
||||
}
|
||||
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);
|
||||
|
||||
m_database->metadata()->removeCustomIcon(iconUuid);
|
||||
m_customIconModel->setIcons(m_database->metadata()->customIconsScaledPixmaps(),
|
||||
m_database->metadata()->customIconsOrder());
|
||||
if (m_customIconModel->rowCount() > 0) {
|
||||
m_ui->customIconsView->setCurrentIndex(m_customIconModel->index(0, 0));
|
||||
}
|
||||
else {
|
||||
updateRadioButtonDefaultIcons();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
Q_EMIT messageEditEntry(
|
||||
tr("Can't delete icon. Still used by %1 items.").arg(iconUsedCount), MessageWidget::Error);
|
||||
|
||||
|
||||
// Remove the icon from history entries
|
||||
for (Entry* entry : asConst(historyEntriesWithSameIcon)) {
|
||||
entry->setUpdateTimeinfo(false);
|
||||
entry->setIcon(0);
|
||||
entry->setUpdateTimeinfo(true);
|
||||
}
|
||||
|
||||
// Remove the icon from the database
|
||||
m_database->metadata()->removeCustomIcon(iconUuid);
|
||||
m_customIconModel->setIcons(m_database->metadata()->customIconsScaledPixmaps(),
|
||||
m_database->metadata()->customIconsOrder());
|
||||
|
||||
// Reset the current icon view
|
||||
updateRadioButtonDefaultIcons();
|
||||
|
||||
if (m_database->resolveEntry(m_currentUuid) != nullptr) {
|
||||
m_ui->defaultIconsView->setCurrentIndex(m_defaultIconModel->index(Entry::DefaultIconNumber));
|
||||
} else {
|
||||
m_ui->defaultIconsView->setCurrentIndex(m_defaultIconModel->index(Group::DefaultIconNumber));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -301,6 +301,10 @@ MainWindow::MainWindow()
|
||||
connect(m_ui->welcomeWidget, SIGNAL(importKeePass1Database()), SLOT(switchToKeePass1Database()));
|
||||
|
||||
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(messageDismissGlobal()), this, SLOT(hideGlobalMessage()));
|
||||
|
@ -110,7 +110,7 @@ static QByteArray encrypt2(const QByteArray & data, SymmetricCipherGcrypt & ciph
|
||||
//Encrypt
|
||||
QByteArray buffer = data + QByteArray(paddingSize, paddingSize);
|
||||
cipher.reset();
|
||||
cipher.processInPlace(buffer);
|
||||
Q_UNUSED(cipher.processInPlace(buffer));
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
@ -91,7 +91,7 @@ typedef int (*http_cb) (http_parser*);
|
||||
|
||||
|
||||
/* Status Codes */
|
||||
#define HTTP_STATUS_MAP(XX) \
|
||||
#define HTTPPARSER_HTTP_STATUS_MAP(XX) \
|
||||
XX(100, CONTINUE, Continue) \
|
||||
XX(101, SWITCHING_PROTOCOLS, Switching Protocols) \
|
||||
XX(102, PROCESSING, Processing) \
|
||||
@ -150,12 +150,12 @@ typedef int (*http_cb) (http_parser*);
|
||||
XX(507, INSUFFICIENT_STORAGE, Insufficient Storage) \
|
||||
XX(508, LOOP_DETECTED, Loop Detected) \
|
||||
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
|
||||
{
|
||||
#define XX(num, name, string) HTTP_STATUS_##name = num,
|
||||
HTTP_STATUS_MAP(XX)
|
||||
HTTPPARSER_HTTP_STATUS_MAP(XX)
|
||||
#undef XX
|
||||
};
|
||||
|
||||
|
@ -41,7 +41,7 @@ public:
|
||||
if ( !icollectRequired ) // not allowed to collect data
|
||||
return false;
|
||||
|
||||
int newLength = icollectedData.length() + (int) length;
|
||||
int newLength = icollectedData.length() + static_cast<int>(length);
|
||||
|
||||
if ( icollectCapacity > 0 && newLength > icollectCapacity )
|
||||
return false; // the capacity is full
|
||||
|
@ -112,7 +112,7 @@ protected:
|
||||
void onReadyRead() {
|
||||
while ( isocket.bytesAvailable() > 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);
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ public:
|
||||
|
||||
// if it's a QLocalServer
|
||||
virtual void incomingConnection(quintptr socketDescriptor) {
|
||||
iserver->incomingConnection((qintptr) socketDescriptor);
|
||||
iserver->incomingConnection(static_cast<qintptr>(socketDescriptor));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -83,7 +83,7 @@ public:
|
||||
void onReadyRead() {
|
||||
while ( isocket.bytesAvailable() > 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);
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ namespace qhttp {
|
||||
# error "to compile QHttp classes, Qt 5.0 or later is needed."
|
||||
#endif
|
||||
|
||||
#define HTTP_STATUS_MAP(XX) \
|
||||
#define QHTTPABSTRACTS_HTTP_STATUS_MAP(XX) \
|
||||
XX(100, "Continue") \
|
||||
XX(101, "Switching Protocols") \
|
||||
/* RFC 2518) obsoleted by RFC 4918 */ \
|
||||
@ -78,7 +78,7 @@ static struct {
|
||||
int code;
|
||||
const char* message;
|
||||
} g_status_codes[] {
|
||||
HTTP_STATUS_MAP(PATCH_STATUS_CODES)
|
||||
QHTTPABSTRACTS_HTTP_STATUS_MAP(PATCH_STATUS_CODES)
|
||||
};
|
||||
#undef PATCH_STATUS_CODES
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user