mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2025-02-25 17:01:17 -05:00
Fix permissions changing on database save
* Saving a database in unsafe mode retains the existing permissions on the kdbx file * New databases (save as, save backup, new database) and new key files are saved with 0600 permissions (user read/write), fixes #2575
This commit is contained in:
parent
1ad0184473
commit
fbebf30b98
@ -253,10 +253,14 @@ bool Database::saveAs(const QString& filePath, QString* error, bool atomic, bool
|
|||||||
|
|
||||||
QFileInfo fileInfo(filePath);
|
QFileInfo fileInfo(filePath);
|
||||||
auto realFilePath = fileInfo.exists() ? fileInfo.canonicalFilePath() : fileInfo.absoluteFilePath();
|
auto realFilePath = fileInfo.exists() ? fileInfo.canonicalFilePath() : fileInfo.absoluteFilePath();
|
||||||
|
bool isNewFile = !QFile::exists(realFilePath);
|
||||||
bool ok = AsyncTask::runAndWaitForFuture([&] { return performSave(realFilePath, error, atomic, backup); });
|
bool ok = AsyncTask::runAndWaitForFuture([&] { return performSave(realFilePath, error, atomic, backup); });
|
||||||
if (ok) {
|
if (ok) {
|
||||||
markAsClean();
|
markAsClean();
|
||||||
setFilePath(filePath);
|
setFilePath(filePath);
|
||||||
|
if (isNewFile) {
|
||||||
|
QFile::setPermissions(realFilePath, QFile::ReadUser | QFile::WriteUser);
|
||||||
|
}
|
||||||
m_fileWatcher->start(realFilePath, 30, 1);
|
m_fileWatcher->start(realFilePath, 30, 1);
|
||||||
} else {
|
} else {
|
||||||
// Saving failed, don't rewatch file since it does not represent our database
|
// Saving failed, don't rewatch file since it does not represent our database
|
||||||
@ -304,6 +308,7 @@ bool Database::performSave(const QString& filePath, QString* error, bool atomic,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Delete the original db and move the temp file in place
|
// Delete the original db and move the temp file in place
|
||||||
|
auto perms = QFile::permissions(filePath);
|
||||||
QFile::remove(filePath);
|
QFile::remove(filePath);
|
||||||
|
|
||||||
// Note: call into the QFile rename instead of QTemporaryFile
|
// Note: call into the QFile rename instead of QTemporaryFile
|
||||||
@ -312,6 +317,7 @@ bool Database::performSave(const QString& filePath, QString* error, bool atomic,
|
|||||||
if (tempFile.QFile::rename(filePath)) {
|
if (tempFile.QFile::rename(filePath)) {
|
||||||
// successfully saved the database
|
// successfully saved the database
|
||||||
tempFile.setAutoRemove(false);
|
tempFile.setAutoRemove(false);
|
||||||
|
QFile::setPermissions(filePath, perms);
|
||||||
return true;
|
return true;
|
||||||
} else if (!backup || !restoreDatabase(filePath)) {
|
} else if (!backup || !restoreDatabase(filePath)) {
|
||||||
// Failed to copy new database in place, and
|
// Failed to copy new database in place, and
|
||||||
@ -454,9 +460,12 @@ bool Database::backupDatabase(const QString& filePath)
|
|||||||
|
|
||||||
auto match = re.match(filePath);
|
auto match = re.match(filePath);
|
||||||
auto backupFilePath = filePath;
|
auto backupFilePath = filePath;
|
||||||
|
auto perms = QFile::permissions(filePath);
|
||||||
backupFilePath = backupFilePath.replace(re, "") + ".old" + match.captured(1);
|
backupFilePath = backupFilePath.replace(re, "") + ".old" + match.captured(1);
|
||||||
QFile::remove(backupFilePath);
|
QFile::remove(backupFilePath);
|
||||||
return QFile::copy(filePath, backupFilePath);
|
bool res = QFile::copy(filePath, backupFilePath);
|
||||||
|
QFile::setPermissions(backupFilePath, perms);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -472,11 +481,13 @@ bool Database::restoreDatabase(const QString& filePath)
|
|||||||
static auto re = QRegularExpression("^(.*?)(\\.[^.]+)?$");
|
static auto re = QRegularExpression("^(.*?)(\\.[^.]+)?$");
|
||||||
|
|
||||||
auto match = re.match(filePath);
|
auto match = re.match(filePath);
|
||||||
|
auto perms = QFile::permissions(filePath);
|
||||||
auto backupFilePath = match.captured(1) + ".old" + match.captured(2);
|
auto backupFilePath = match.captured(1) + ".old" + match.captured(2);
|
||||||
// Only try to restore if the backup file actually exists
|
// Only try to restore if the backup file actually exists
|
||||||
if (QFile::exists(backupFilePath)) {
|
if (QFile::exists(backupFilePath)) {
|
||||||
QFile::remove(filePath);
|
QFile::remove(filePath);
|
||||||
return QFile::copy(backupFilePath, filePath);
|
return QFile::copy(backupFilePath, filePath);
|
||||||
|
QFile::setPermissions(filePath, perms);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -200,6 +200,7 @@ bool FileKey::create(const QString& fileName, QString* errorMsg, int size)
|
|||||||
}
|
}
|
||||||
create(&file, size);
|
create(&file, size);
|
||||||
file.close();
|
file.close();
|
||||||
|
file.setPermissions(QFile::ReadUser);
|
||||||
|
|
||||||
if (file.error()) {
|
if (file.error()) {
|
||||||
if (errorMsg) {
|
if (errorMsg) {
|
||||||
|
@ -680,7 +680,7 @@ void TestGuiFdoSecrets::testCollectionCreate()
|
|||||||
|
|
||||||
QCOMPARE(spyCollectionCreated.count(), 1);
|
QCOMPARE(spyCollectionCreated.count(), 1);
|
||||||
{
|
{
|
||||||
auto args = spyCollectionCreated.takeFirst();
|
args = spyCollectionCreated.takeFirst();
|
||||||
QCOMPARE(args.size(), 1);
|
QCOMPARE(args.size(), 1);
|
||||||
QCOMPARE(args.at(0).value<Collection*>(), coll);
|
QCOMPARE(args.at(0).value<Collection*>(), coll);
|
||||||
}
|
}
|
||||||
@ -754,7 +754,7 @@ void TestGuiFdoSecrets::testCollectionDelete()
|
|||||||
|
|
||||||
QCOMPARE(spyCollectionDeleted.count(), 1);
|
QCOMPARE(spyCollectionDeleted.count(), 1);
|
||||||
{
|
{
|
||||||
auto args = spyCollectionDeleted.takeFirst();
|
args = spyCollectionDeleted.takeFirst();
|
||||||
QCOMPARE(args.size(), 1);
|
QCOMPARE(args.size(), 1);
|
||||||
QCOMPARE(args.at(0).value<Collection*>(), rawColl);
|
QCOMPARE(args.at(0).value<Collection*>(), rawColl);
|
||||||
}
|
}
|
||||||
@ -977,7 +977,7 @@ void TestGuiFdoSecrets::testItemDelete()
|
|||||||
|
|
||||||
QCOMPARE(spyItemDeleted.count(), 1);
|
QCOMPARE(spyItemDeleted.count(), 1);
|
||||||
{
|
{
|
||||||
auto args = spyItemDeleted.takeFirst();
|
args = spyItemDeleted.takeFirst();
|
||||||
QCOMPARE(args.size(), 1);
|
QCOMPARE(args.size(), 1);
|
||||||
QCOMPARE(args.at(0).value<Item*>(), rawItem);
|
QCOMPARE(args.at(0).value<Item*>(), rawItem);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user