Skip to content

Commit 3cdc65a

Browse files
revolterMKleusberg
authored andcommitted
Add automatic crypted databases open via dotenvs (#1404)
* Rename confusing variables * Fix some project warnings * Fix code style * Add constant for the default page size * Move KeyFormats enum to CipherSettings * Fix code style * Fix memory leak * Stop relying on CipherDialog for encryption settings management * Fix code style * Add .env format for QSettings * Add automatic crypted databases open via dotenvs This adds support for `.env` files next to the crypted databases that are to be opened that contains the needed cipher settings. The only required one is the plain-text password as a value for the key with the name of the database like this: myCryptedDatabase.sqlite = MyPassword This way, databases with a different extension are supported too: myCryptedDatabase.db = MyPassword You can also specify a custom page size adding a different line (anywhere in the file) like this: myCryptedDatabase.db_pageSize = 2048 If not specified, `1024` is used. You can also specify the format of the specified key using the associated integer id: anotherCryptedDatabase.sqlite = 0xCAFEBABE anotherCryptedDatabase.sqlite_keyFormat = 1 where `1` means a Raw key. If not specified, `0` is used, which means a simple text Passphrase. Dotenv files (`.env`) are already used on other platforms and by different tools to manage environment variables, and it's recommended to be ignored from version control systems, so they won't leak. * Add new files to CMakeLists * Move DotenvFormat include to the implementation * Fix build error * Remove superfluous method (related to ac51c23) * Remove superfluous checks * Fix memory leaks (introduced by 94bbb46) * Fix code style * Make dotenv related variable and comment clearer * Remove duplicated code * Remove unused forward declaration (introduced by e5a0293)
1 parent c861f1b commit 3cdc65a

File tree

13 files changed

+267
-76
lines changed

13 files changed

+267
-76
lines changed

CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ set(SQLB_MOC_HDR
138138
src/FindReplaceDialog.h
139139
src/ExtendedScintilla.h
140140
src/FileExtensionManager.h
141+
src/CipherSettings.h
142+
src/DotenvFormat.h
141143
)
142144

143145
set(SQLB_SRC
@@ -182,6 +184,8 @@ set(SQLB_SRC
182184
src/ExtendedScintilla.cpp
183185
src/FileExtensionManager.cpp
184186
src/Data.cpp
187+
src/CipherSettings.cpp
188+
src/DotenvFormat.cpp
185189
)
186190

187191
set(SQLB_FORMS

src/CipherDialog.cpp

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -49,34 +49,33 @@ CipherDialog::~CipherDialog()
4949
delete ui;
5050
}
5151

52-
CipherDialog::KeyFormats CipherDialog::keyFormat() const
52+
CipherSettings CipherDialog::getCipherSettings() const
5353
{
54-
return static_cast<CipherDialog::KeyFormats>(ui->comboKeyFormat->currentIndex());
55-
}
54+
CipherSettings::KeyFormats keyFormat = CipherSettings::getKeyFormat(ui->comboKeyFormat->currentIndex());
55+
QString password = ui->editPassword->text();
56+
int pageSize = ui->comboPageSize->itemData(ui->comboPageSize->currentIndex()).toInt();
5657

57-
QString CipherDialog::password() const
58-
{
59-
if(keyFormat() == KeyFormats::Passphrase)
60-
return QString("'%1'").arg(ui->editPassword->text().replace("'", "''"));
61-
else
62-
return QString("\"x'%1'\"").arg(ui->editPassword->text().mid(2)); // Remove the '0x' part at the beginning
63-
}
58+
CipherSettings cipherSettings;
6459

65-
int CipherDialog::pageSize() const
66-
{
67-
return ui->comboPageSize->itemData(ui->comboPageSize->currentIndex()).toInt();
60+
cipherSettings.setKeyFormat(keyFormat);
61+
cipherSettings.setPassword(password);
62+
cipherSettings.setPageSize(pageSize);
63+
64+
return cipherSettings;
6865
}
6966

7067
void CipherDialog::checkInputFields()
7168
{
7269
if(sender() == ui->comboKeyFormat)
7370
{
74-
if(keyFormat() == KeyFormats::Passphrase)
71+
CipherSettings::KeyFormats keyFormat = CipherSettings::getKeyFormat(ui->comboKeyFormat->currentIndex());
72+
73+
if(keyFormat == CipherSettings::KeyFormats::Passphrase)
7574
{
7675
ui->editPassword->setValidator(nullptr);
7776
ui->editPassword2->setValidator(nullptr);
7877
ui->editPassword->setPlaceholderText("");
79-
} else if(keyFormat() == KeyFormats::RawKey) {
78+
} else if(keyFormat == CipherSettings::KeyFormats::RawKey) {
8079
ui->editPassword->setValidator(rawKeyValidator);
8180
ui->editPassword2->setValidator(rawKeyValidator);
8281
ui->editPassword->setPlaceholderText("0x...");

src/CipherDialog.h

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
#include <QDialog>
55

6+
#include "CipherSettings.h"
7+
68
class QRegExpValidator;
79

810
namespace Ui {
@@ -14,21 +16,12 @@ class CipherDialog : public QDialog
1416
Q_OBJECT
1517

1618
public:
17-
enum KeyFormats
18-
{
19-
Passphrase,
20-
RawKey
21-
};
22-
2319
// Set the encrypt parameter to true when the dialog is used to encrypt a database;
2420
// set it to false if the dialog is used to ask the user for the key to decrypt a file.
2521
explicit CipherDialog(QWidget* parent, bool encrypt);
2622
~CipherDialog();
2723

28-
// Allow read access to the input fields
29-
KeyFormats keyFormat() const;
30-
QString password() const;
31-
int pageSize() const;
24+
CipherSettings getCipherSettings() const;
3225

3326
private:
3427
Ui::CipherDialog* ui;

src/CipherSettings.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#include "CipherSettings.h"
2+
3+
CipherSettings::KeyFormats CipherSettings::getKeyFormat() const
4+
{
5+
return keyFormat;
6+
}
7+
8+
void CipherSettings::setKeyFormat(const KeyFormats &value)
9+
{
10+
keyFormat = value;
11+
}
12+
13+
QString CipherSettings::getPassword() const
14+
{
15+
if(keyFormat == Passphrase)
16+
{
17+
QString tempPassword = password;
18+
19+
tempPassword.replace("'", "''");
20+
21+
return QString("'%1'").arg(tempPassword);
22+
} else {
23+
// Remove the '0x' part at the beginning
24+
return QString("\"x'%1'\"").arg(password.mid(2));
25+
}
26+
}
27+
28+
void CipherSettings::setPassword(const QString &value)
29+
{
30+
password = value;
31+
}
32+
33+
int CipherSettings::getPageSize() const
34+
{
35+
if (pageSize == 0)
36+
return defaultPageSize;
37+
38+
return pageSize;
39+
}
40+
41+
void CipherSettings::setPageSize(int value)
42+
{
43+
pageSize = value;
44+
}
45+
46+
CipherSettings::KeyFormats CipherSettings::getKeyFormat(int rawKeyFormat)
47+
{
48+
return static_cast<CipherSettings::KeyFormats>(rawKeyFormat);
49+
}

src/CipherSettings.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#ifndef CIPHERSETTINGS_H
2+
#define CIPHERSETTINGS_H
3+
4+
#include <QString>
5+
6+
class CipherSettings
7+
{
8+
public:
9+
enum KeyFormats
10+
{
11+
Passphrase,
12+
RawKey
13+
};
14+
15+
static const int defaultPageSize = 1024;
16+
17+
KeyFormats getKeyFormat() const;
18+
void setKeyFormat(const KeyFormats &value);
19+
20+
QString getPassword() const;
21+
void setPassword(const QString &value);
22+
23+
int getPageSize() const;
24+
void setPageSize(int value);
25+
26+
static KeyFormats getKeyFormat(int rawKeyFormat);
27+
28+
private:
29+
KeyFormats keyFormat;
30+
QString password;
31+
int pageSize;
32+
};
33+
34+
#endif // CIPHERSETTINGS_H

src/DotenvFormat.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#include "DotenvFormat.h"
2+
3+
#include <QRegularExpression>
4+
#include <QTextStream>
5+
6+
bool DotenvFormat::readEnvFile(QIODevice &device, QSettings::SettingsMap &map)
7+
{
8+
QTextStream in(&device);
9+
10+
QString line;
11+
12+
QRegularExpression keyValueRegex("^\\s*([\\w\\.\\-]+)\\s*=\\s*(.*)\\s*$");
13+
14+
while (in.readLineInto(&line)) {
15+
QRegularExpressionMatch match = keyValueRegex.match(line);
16+
17+
if (match.capturedLength() < 3) {
18+
continue;
19+
}
20+
21+
QString key = match.captured(1);
22+
QString value = match.captured(2);
23+
24+
map.insert(key, value);
25+
}
26+
27+
return true;
28+
}

src/DotenvFormat.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#ifndef DOTENVFORMAT_H
2+
#define DOTENVFORMAT_H
3+
4+
#include <QIODevice>
5+
#include <QSettings>
6+
7+
class DotenvFormat
8+
{
9+
public:
10+
static bool readEnvFile(QIODevice &device, QSettings::SettingsMap &map);
11+
};
12+
13+
#endif // DOTENVFORMAT_H

src/MainWindow.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2530,8 +2530,8 @@ void MainWindow::updateFilter(int column, const QString& value)
25302530
void MainWindow::editEncryption()
25312531
{
25322532
#ifdef ENABLE_SQLCIPHER
2533-
CipherDialog dialog(this, true);
2534-
if(dialog.exec())
2533+
CipherDialog cipherDialog(this, true);
2534+
if(cipherDialog.exec())
25352535
{
25362536
// Show progress dialog even though we can't provide any detailed progress information but this
25372537
// process might take some time.
@@ -2553,14 +2553,16 @@ void MainWindow::editEncryption()
25532553
file.close();
25542554
}
25552555

2556+
CipherSettings cipherSettings = cipherDialog.getCipherSettings();
2557+
25562558
// Attach a new database using the new settings
25572559
qApp->processEvents();
25582560
if(ok)
2559-
ok = db.executeSQL(QString("ATTACH DATABASE '%1' AS sqlitebrowser_edit_encryption KEY %2;").arg(db.currentFile() + ".enctemp").arg(dialog.password()),
2561+
ok = db.executeSQL(QString("ATTACH DATABASE '%1' AS sqlitebrowser_edit_encryption KEY %2;").arg(db.currentFile() + ".enctemp").arg(cipherSettings.getPassword()),
25602562
false, false);
25612563
qApp->processEvents();
25622564
if(ok)
2563-
ok = db.executeSQL(QString("PRAGMA sqlitebrowser_edit_encryption.cipher_page_size = %1").arg(dialog.pageSize()), false, false);
2565+
ok = db.executeSQL(QString("PRAGMA sqlitebrowser_edit_encryption.cipher_page_size = %1").arg(cipherSettings.getPageSize()), false, false);
25642566

25652567
// Export the current database to the new one
25662568
qApp->processEvents();

src/Settings.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
#define SETTINGS_H
33

44
#include <QApplication>
5-
#include <QVariant>
65
#include <QHash>
6+
#include <QVariant>
77

88
class Settings
99
{

0 commit comments

Comments
 (0)