From a22ed6f9d36db139d4521ee8bb03e30fae33e1a7 Mon Sep 17 00:00:00 2001 From: Martin Kleusberg Date: Sun, 2 Nov 2014 19:06:06 +0100 Subject: [PATCH] cipher: Add option for changing the encryption used for the current file Add a new menu option to the main window (only visible when built with the sqlcipher option enabled) which opens a dialog asking for new encryption settings. These are then applied to a new database to which all contents of the current one are exported. The old database is then replaced by the new one. This adds support for encrypting plaintext databases, decrypting encrypted databases and changing the password or other settings of encrypted databases. If this turns out to work well enough we have functional SQLCipher encryption support with only details missing. --- src/CipherDialog.cpp | 6 ++-- src/CipherDialog.ui | 2 +- src/MainWindow.cpp | 66 +++++++++++++++++++++++++++++++++++++++++++ src/MainWindow.h | 1 + src/MainWindow.ui | 31 ++++++++++++++++++-- src/icons/icons.qrc | 1 + src/icons/key.png | Bin 0 -> 612 bytes 7 files changed, 102 insertions(+), 5 deletions(-) create mode 100644 src/icons/key.png diff --git a/src/CipherDialog.cpp b/src/CipherDialog.cpp index 68471f3e..f00d8604 100644 --- a/src/CipherDialog.cpp +++ b/src/CipherDialog.cpp @@ -13,9 +13,11 @@ CipherDialog::CipherDialog(QWidget* parent, bool encrypt) : if(encrypt) { ui->labelDialogDescription->setText(tr("Please set a key to encrypt the database.\nNote that if you change any of the other, optional, settings you'll need " - "to re-enter them as well every time you open the database file.")); + "to re-enter them as well every time you open the database file.\nLeave the password fields empty to disable the " + "encryption.\nThe encrpytion process might take some time and you should have a backup copy of you database! Unsaved " + "changes are applied before modifying the encryption.")); } else { - ui->labelDialogDescription->setText(tr("Please enter the key used to encrypt the database.\nIf any of the other setting were altered for this database file " + ui->labelDialogDescription->setText(tr("Please enter the key used to encrypt the database.\nIf any of the other settings were altered for this database file " "you need to provide this information as well.")); ui->editPassword2->setVisible(false); ui->labelPassword2->setVisible(false); diff --git a/src/CipherDialog.ui b/src/CipherDialog.ui index ad364307..5ba5ee74 100644 --- a/src/CipherDialog.ui +++ b/src/CipherDialog.ui @@ -6,7 +6,7 @@ 0 0 - 475 + 712 147 diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 74e90dab..d806d0c8 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -16,6 +16,7 @@ #include "DbStructureModel.h" #include "gen_version.h" #include "sqlite.h" +#include "CipherDialog.h" #include #include @@ -174,6 +175,11 @@ void MainWindow::init() QUrl url("https://raw.github.com/sqlitebrowser/sqlitebrowser/master/currentrelease"); m_NetworkManager->get(QNetworkRequest(url)); #endif + +#ifndef ENABLE_SQLCIPHER + // Only show encrpytion menu action when SQLCipher support is enabled + ui->actionEncryption->setVisible(false); +#endif } void MainWindow::clearCompleterModelsFields() @@ -845,6 +851,7 @@ void MainWindow::dbState( bool dirty ) ui->fileSaveAction->setEnabled(dirty); ui->fileRevertAction->setEnabled(dirty); ui->fileAttachAction->setEnabled(!dirty); + //ui->actionEncryption->setEnabled(!dirty); } void MainWindow::fileSave() @@ -1096,6 +1103,7 @@ void MainWindow::activateFields(bool enable) ui->actionSqlOpenTab->setEnabled(enable); ui->actionSqlSaveFile->setEnabled(enable); ui->actionSaveProject->setEnabled(enable); + ui->actionEncryption->setEnabled(enable); } void MainWindow::browseTableHeaderClicked(int logicalindex) @@ -1998,3 +2006,61 @@ void MainWindow::updateFilter(int column, const QString& value) m_browseTableModel->updateFilter(column ,value); setRecordsetLabel(); } + +void MainWindow::editEncryption() +{ +#ifdef ENABLE_SQLCIPHER + CipherDialog dialog(this, true); + if(dialog.exec()) + { + // Show progress dialog even though we can't provide any detailed progress information but this + // process might take some time. + QProgressDialog progress(this); + progress.setCancelButton(0); + progress.setWindowModality(Qt::ApplicationModal); + progress.show(); + qApp->processEvents(); + + // Apply all unsaved changes + bool ok = db.saveAll(); + qApp->processEvents(); + + // Create the new file first or it won't work + if(ok) + { + QFile file(db.curDBFilename + ".enctemp"); + file.open(QFile::WriteOnly); + file.close(); + } + + // Attach a new database using the new settings + qApp->processEvents(); + if(ok) + ok = db.executeSQL(QString("ATTACH DATABASE '%1' AS sqlitebrowser_edit_encryption KEY '%2';").arg(db.curDBFilename + ".enctemp").arg(dialog.password()), + false, false); + qApp->processEvents(); + if(ok) + ok = db.executeSQL(QString("PRAGMA sqlitebrowser_edit_encryption.cipher_page_size = %1").arg(dialog.pageSize()), false, false); + + // Export the current database to the new one + qApp->processEvents(); + if(ok) + ok = db.executeSQL("SELECT sqlcipher_export('sqlitebrowser_edit_encryption');", false, false); + + // Check for errors + qApp->processEvents(); + if(ok) + { + // No errors: Then close the current database, switch names, open the new one and if that succeeded delete the old one + + fileClose(); + QFile::rename(db.curDBFilename, db.curDBFilename + ".enctempold"); + QFile::rename(db.curDBFilename + ".enctemp", db.curDBFilename); + if(fileOpen(db.curDBFilename)) + QFile::remove(db.curDBFilename + ".enctempold"); + } else { + QMessageBox::warning(this, qApp->applicationName(), db.lastErrorMessage); + } + } +#endif +} diff --git a/src/MainWindow.h b/src/MainWindow.h index 9440f985..840f7fbc 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -179,6 +179,7 @@ private slots: void saveProject(); void fileAttach(); void updateFilter(int column, const QString& value); + void editEncryption(); }; #endif diff --git a/src/MainWindow.ui b/src/MainWindow.ui index b04b0f0c..8ffdddfe 100644 --- a/src/MainWindow.ui +++ b/src/MainWindow.ui @@ -278,8 +278,8 @@ 0 0 - 575 - 458 + 294 + 444 @@ -793,6 +793,7 @@ + @@ -1523,6 +1524,15 @@ &Attach Database + + + + :/icons/encryption:/icons/encryption + + + Set Encryption + + @@ -2314,6 +2324,22 @@ + + actionEncryption + triggered() + MainWindow + editEncryption() + + + -1 + -1 + + + 499 + 314 + + + fileOpen() @@ -2363,5 +2389,6 @@ loadProject() saveProject() fileAttach() + editEncryption() diff --git a/src/icons/icons.qrc b/src/icons/icons.qrc index f8061f83..9caca73f 100644 --- a/src/icons/icons.qrc +++ b/src/icons/icons.qrc @@ -40,5 +40,6 @@ package.png package_go.png page_key.png + key.png diff --git a/src/icons/key.png b/src/icons/key.png new file mode 100644 index 0000000000000000000000000000000000000000..4ec1a928140311ff30a0a9120e958096c77f446e GIT binary patch literal 612 zcmV-q0-ODbP)nmX^MrbE*gmZ6|p*GkKoxa?X?hD9M+@sRvFH{EqYA??u6x z2pu{uGnrwz*>rh zfvUA@7b#acN?M*mBG3rQV?e^+0R5m3YXWyRZL5Bt@3vAw{9JaEW$}=f4bXO52yBH{ z;G~ZN|GLn>k~{On3Swd-Sy(gFkOdyw-RP%&exwl01RJRp))TI*SsngruhZksQ*NT%!X?K0000