Skip to content

Commit

Permalink
Merge branch 'release/2.5.1' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
phoerious committed Nov 6, 2019
2 parents 74381dc + 1722397 commit eed935c
Show file tree
Hide file tree
Showing 23 changed files with 108 additions and 47 deletions.
8 changes: 8 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,14 @@ if(UNIX)
int main() { prctl(PR_SET_DUMPABLE, 0); return 0; }"
HAVE_PR_SET_DUMPABLE)

check_cxx_source_compiles("#include <malloc.h>
int main() { return 0; }"
HAVE_MALLOC_H)

check_cxx_source_compiles("#include <malloc.h>
int main() { malloc_usable_size(NULL, 0); return 0; }"
HAVE_MALLOC_USABLE_SIZE)

check_cxx_source_compiles("#include <sys/resource.h>
int main() {
struct rlimit limit;
Expand Down
4 changes: 4 additions & 0 deletions share/docs/man/keepassxc-cli.1
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,10 @@ an error if no TOTP is configured for the entry.
Shows the named attributes. This option can be specified more than once,
with each attribute shown one-per-line in the given order. If no attributes are
specified and \fI-t\fP is not specified, a summary of the default attributes is given.
Protected attributes will be displayed in clear text if specified explicitly by this option.

.IP "-s, --show-protected"
Shows the protected attributes in clear text.

.IP "-t, --totp"
Also shows the current TOTP, reporting an error if no TOTP is configured for
Expand Down
4 changes: 4 additions & 0 deletions share/translations/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,9 @@ endif()
set(QM_FILES ${QM_FILES} ${QTBASE_TRANSLATIONS})

install(FILES ${QM_FILES} DESTINATION ${DATA_INSTALL_DIR}/translations)

# Add keepassx_en.qm as a fallback for uncommon english locales
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/keepassx_en_US.qm DESTINATION ${DATA_INSTALL_DIR}/translations RENAME keepassx_en.qm)

add_custom_target(translations DEPENDS ${QM_FILES})
add_dependencies(${PROGNAME} translations)
2 changes: 1 addition & 1 deletion src/cli/Clip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Clip::Clip()
int Clip::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<QCommandLineParser> parser)
{
const QStringList args = parser->positionalArguments();
QString entryPath = args.at(1);
const QString& entryPath = args.at(1);
QString timeout;
if (args.size() == 3) {
timeout = args.at(2);
Expand Down
4 changes: 2 additions & 2 deletions src/cli/Import.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ int Import::execute(const QStringList& arguments)
TextStream errorTextStream(Utils::STDERR, QIODevice::WriteOnly);

const QStringList args = parser->positionalArguments();
const QString xmlExportPath = args.at(0);
const QString dbPath = args.at(1);
const QString& xmlExportPath = args.at(0);
const QString& dbPath = args.at(1);

if (QFileInfo::exists(dbPath)) {
errorTextStream << QObject::tr("File %1 already exists.").arg(dbPath) << endl;
Expand Down
2 changes: 1 addition & 1 deletion src/cli/List.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ int List::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
return EXIT_SUCCESS;
}

QString groupPath = args.at(1);
const QString& groupPath = args.at(1);
Group* group = database->rootGroup()->findGroupByPath(groupPath);
if (!group) {
errorTextStream << QObject::tr("Cannot find group %1.").arg(groupPath) << endl;
Expand Down
2 changes: 1 addition & 1 deletion src/cli/Locate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ int Locate::executeWithDatabase(QSharedPointer<Database> database, QSharedPointe
{

const QStringList args = parser->positionalArguments();
QString searchTerm = args.at(1);
const QString& searchTerm = args.at(1);
TextStream outputTextStream(Utils::STDOUT, QIODevice::WriteOnly);
TextStream errorTextStream(Utils::STDERR, QIODevice::WriteOnly);

Expand Down
21 changes: 16 additions & 5 deletions src/cli/Show.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ const QCommandLineOption Show::TotpOption = QCommandLineOption(QStringList() <<
<< "totp",
QObject::tr("Show the entry's current TOTP."));

const QCommandLineOption Show::ProtectedAttributesOption =
QCommandLineOption(QStringList() << "s"
<< "show-protected",
QObject::tr("Show the protected attributes in clear text."));

const QCommandLineOption Show::AttributesOption = QCommandLineOption(
QStringList() << "a"
<< "attributes",
Expand All @@ -46,6 +51,7 @@ Show::Show()
description = QObject::tr("Show an entry's information.");
options.append(Show::TotpOption);
options.append(Show::AttributesOption);
options.append(Show::ProtectedAttributesOption);
positionalArguments.append({QString("entry"), QObject::tr("Name of the entry to show."), QString("")});
}

Expand All @@ -57,6 +63,7 @@ int Show::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
const QStringList args = parser->positionalArguments();
const QString& entryPath = args.at(1);
bool showTotp = parser->isSet(Show::TotpOption);
bool showProtectedAttributes = parser->isSet(Show::ProtectedAttributesOption);
QStringList attributes = parser->values(Show::AttributesOption);

Entry* entry = database->rootGroup()->findEntryByPath(entryPath);
Expand All @@ -78,16 +85,20 @@ int Show::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<

// Iterate over the attributes and output them line-by-line.
bool sawUnknownAttribute = false;
for (const QString& attribute : asConst(attributes)) {
if (!entry->attributes()->contains(attribute)) {
for (const QString& attributeName : asConst(attributes)) {
if (!entry->attributes()->contains(attributeName)) {
sawUnknownAttribute = true;
errorTextStream << QObject::tr("ERROR: unknown attribute %1.").arg(attribute) << endl;
errorTextStream << QObject::tr("ERROR: unknown attribute %1.").arg(attributeName) << endl;
continue;
}
if (showAttributeNames) {
outputTextStream << attribute << ": ";
outputTextStream << attributeName << ": ";
}
if (entry->attributes()->isProtected(attributeName) && showAttributeNames && !showProtectedAttributes) {
outputTextStream << "PROTECTED" << endl;
} else {
outputTextStream << entry->resolveMultiplePlaceholders(entry->attributes()->value(attributeName)) << endl;
}
outputTextStream << entry->resolveMultiplePlaceholders(entry->attributes()->value(attribute)) << endl;
}

if (showTotp) {
Expand Down
1 change: 1 addition & 0 deletions src/cli/Show.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class Show : public DatabaseCommand

static const QCommandLineOption TotpOption;
static const QCommandLineOption AttributesOption;
static const QCommandLineOption ProtectedAttributesOption;
};

#endif // KEEPASSXC_SHOW_H
6 changes: 4 additions & 2 deletions src/core/Alloc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@
#include <malloc/malloc.h>
#elif defined(Q_OS_FREEBSD)
#include <malloc_np.h>
#else
#elif defined(HAVE_MALLOC_H)
#include <malloc.h>
#else
#include <stdlib.h>
#endif

#if defined(NDEBUG) && !defined(__cpp_sized_deallocation)
Expand Down Expand Up @@ -64,7 +66,7 @@ void operator delete(void* ptr) noexcept
::operator delete(ptr, _msize(ptr));
#elif defined(Q_OS_MACOS)
::operator delete(ptr, malloc_size(ptr));
#elif defined(Q_OS_UNIX)
#elif defined(HAVE_MALLOC_USABLE_SIZE)
::operator delete(ptr, malloc_usable_size(ptr));
#else
// whatever OS this is, give up and simply free stuff
Expand Down
4 changes: 2 additions & 2 deletions src/core/Database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ bool Database::open(const QString& filePath, QSharedPointer<const CompositeKey>

m_initialized = true;
emit databaseOpened();
m_fileWatcher->start(canonicalFilePath());
m_fileWatcher->start(canonicalFilePath(), 30, 1);
setEmitModified(true);

return true;
Expand Down Expand Up @@ -234,7 +234,7 @@ bool Database::saveAs(const QString& filePath, QString* error, bool atomic, bool
bool ok = performSave(canonicalFilePath, error, atomic, backup);
if (ok) {
setFilePath(filePath);
m_fileWatcher->start(canonicalFilePath);
m_fileWatcher->start(canonicalFilePath, 30, 1);
} else {
// Saving failed, don't rewatch file since it does not represent our database
markAsModified();
Expand Down
17 changes: 13 additions & 4 deletions src/core/FileWatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ FileWatcher::FileWatcher(QObject* parent)
m_fileIgnoreDelayTimer.setSingleShot(true);
}

void FileWatcher::start(const QString& filePath, int checksumInterval)
void FileWatcher::start(const QString& filePath, int checksumIntervalSeconds, int checksumSizeKibibytes)
{
stop();

Expand All @@ -63,8 +63,14 @@ void FileWatcher::start(const QString& filePath, int checksumInterval)

m_fileWatcher.addPath(filePath);
m_filePath = filePath;

// Handle file checksum
m_fileChecksumSizeBytes = checksumSizeKibibytes * 1024;
m_fileChecksum = calculateChecksum();
m_fileChecksumTimer.start(checksumInterval);
if (checksumIntervalSeconds > 0) {
m_fileChecksumTimer.start(checksumIntervalSeconds * 1000);
}

m_ignoreFileChange = false;
}

Expand Down Expand Up @@ -131,9 +137,12 @@ QByteArray FileWatcher::calculateChecksum()
QFile file(m_filePath);
if (file.open(QFile::ReadOnly)) {
QCryptographicHash hash(QCryptographicHash::Sha256);
if (hash.addData(&file)) {
return hash.result();
if (m_fileChecksumSizeBytes > 0) {
hash.addData(file.read(m_fileChecksumSizeBytes));
} else {
hash.addData(&file);
}
return hash.result();
}
return {};
}
Expand Down
3 changes: 2 additions & 1 deletion src/core/FileWatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class FileWatcher : public QObject
public:
explicit FileWatcher(QObject* parent = nullptr);

void start(const QString& path, int checksumInterval = 1000);
void start(const QString& path, int checksumIntervalSeconds = 0, int checksumSizeKibibytes = -1);
void stop();

bool hasSameFileChecksum();
Expand All @@ -56,6 +56,7 @@ private slots:
QTimer m_fileChangeDelayTimer;
QTimer m_fileIgnoreDelayTimer;
QTimer m_fileChecksumTimer;
int m_fileChecksumSizeBytes;
bool m_ignoreFileChange;
};

Expand Down
2 changes: 1 addition & 1 deletion src/core/IconDownloader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ void IconDownloader::setUrl(const QString& entryUrl)
// searching for a match with the returned address(es).
bool hostIsIp = false;
QList<QHostAddress> hostAddressess = QHostInfo::fromName(fullyQualifiedDomain).addresses();
for (auto addr : hostAddressess) {
for (const auto& addr : hostAddressess) {
if (addr.toString() == fullyQualifiedDomain) {
hostIsIp = true;
}
Expand Down
2 changes: 2 additions & 0 deletions src/format/OpVaultReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,8 @@ OpVaultReader::decodeB64CompositeKeys(const QString& b64, const QByteArray& encK
result->errorStr = tr("Unable to decode masterKey: %1").arg(keyKey01.errorString());
return result;
}
delete result;

const QByteArray keyKey = keyKey01.getClearText();

return decodeCompositeKeys(keyKey);
Expand Down
7 changes: 7 additions & 0 deletions src/keys/drivers/YubiKeyStub.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,10 @@ YubiKey::ChallengeResult YubiKey::challenge(int slot, bool mayBlock, const QByte

return ERROR;
}

bool YubiKey::checkSlotIsBlocking(int slot, QString& errorMessage)
{
Q_UNUSED(slot);
Q_UNUSED(errorMessage);
return false;
}
4 changes: 4 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ int main(int argc, char** argv)
#endif
#endif

#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
QGuiApplication::setDesktopFileName("org.keepassxc.KeePassXC.desktop");
#endif

Application app(argc, argv);
Application::setApplicationName("keepassxc");
Application::setApplicationVersion(KEEPASSXC_VERSION);
Expand Down
16 changes: 1 addition & 15 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -87,17 +87,7 @@ macro(add_unit_test)
endif()
endmacro(add_unit_test)

set(TEST_LIBRARIES
keepassx_core
${keepassxcbrowser_LIB}
${autotype_LIB}
Qt5::Core
Qt5::Concurrent
Qt5::Widgets
Qt5::Test
${GCRYPT_LIBRARIES}
${GPGERROR_LIBRARIES}
${ZLIB_LIBRARIES})
set(TEST_LIBRARIES keepassx_core Qt5::Test)

set(testsupport_SOURCES
modeltest.cpp
Expand All @@ -108,10 +98,6 @@ set(testsupport_SOURCES
add_library(testsupport STATIC ${testsupport_SOURCES})
target_link_libraries(testsupport Qt5::Core Qt5::Concurrent Qt5::Widgets Qt5::Test)

if(YUBIKEY_FOUND)
set(TEST_LIBRARIES ${TEST_LIBRARIES} ${YUBIKEY_LIBRARIES})
endif()

add_unit_test(NAME testgroup SOURCES TestGroup.cpp
LIBS testsupport ${TEST_LIBRARIES})

Expand Down
25 changes: 22 additions & 3 deletions tests/TestCli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
#include "core/Bootstrap.h"
#include "core/Config.h"
#include "core/Global.h"
#include "core/PasswordGenerator.h"
#include "core/Tools.h"
#include "crypto/Crypto.h"
#include "keys/drivers/YubiKey.h"
#include "format/Kdbx3Reader.h"
#include "format/Kdbx3Writer.h"
#include "format/Kdbx4Reader.h"
Expand Down Expand Up @@ -1682,28 +1682,47 @@ void TestCli::testShow()
QCOMPARE(m_stdoutFile->readAll(),
QByteArray("Title: Sample Entry\n"
"UserName: User Name\n"
"Password: Password\n"
"Password: PROTECTED\n"
"URL: http://www.somesite.com/\n"
"Notes: Notes\n"));

qint64 pos = m_stdoutFile->pos();
Utils::Test::setNextPassword("a");
showCmd.execute({"show", m_dbFile->fileName(), "-q", "/Sample Entry"});
showCmd.execute({"show", "-s", m_dbFile->fileName(), "/Sample Entry"});
m_stdoutFile->seek(pos);
m_stdoutFile->readLine(); // skip password prompt
QCOMPARE(m_stdoutFile->readAll(),
QByteArray("Title: Sample Entry\n"
"UserName: User Name\n"
"Password: Password\n"
"URL: http://www.somesite.com/\n"
"Notes: Notes\n"));

pos = m_stdoutFile->pos();
Utils::Test::setNextPassword("a");
showCmd.execute({"show", m_dbFile->fileName(), "-q", "/Sample Entry"});
m_stdoutFile->seek(pos);
QCOMPARE(m_stdoutFile->readAll(),
QByteArray("Title: Sample Entry\n"
"UserName: User Name\n"
"Password: PROTECTED\n"
"URL: http://www.somesite.com/\n"
"Notes: Notes\n"));

pos = m_stdoutFile->pos();
Utils::Test::setNextPassword("a");
showCmd.execute({"show", "-a", "Title", m_dbFile->fileName(), "/Sample Entry"});
m_stdoutFile->seek(pos);
m_stdoutFile->readLine(); // skip password prompt
QCOMPARE(m_stdoutFile->readAll(), QByteArray("Sample Entry\n"));

pos = m_stdoutFile->pos();
Utils::Test::setNextPassword("a");
showCmd.execute({"show", "-a", "Password", m_dbFile->fileName(), "/Sample Entry"});
m_stdoutFile->seek(pos);
m_stdoutFile->readLine(); // skip password prompt
QCOMPARE(m_stdoutFile->readAll(), QByteArray("Password\n"));

pos = m_stdoutFile->pos();
Utils::Test::setNextPassword("a");
showCmd.execute({"show", "-a", "Title", "-a", "URL", m_dbFile->fileName(), "/Sample Entry"});
Expand Down
Loading

0 comments on commit eed935c

Please sign in to comment.