Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/keepassxreboot/keepassxc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJanek Bevendorff <janek@jbev.net>2017-01-14 16:09:47 +0300
committerGitHub <noreply@github.com>2017-01-14 16:09:47 +0300
commit1ca5b72073a98f47d191f9dda321e690cda9c468 (patch)
treeecdf67e1dd86648ab63a5487881059cf97f90adc
parenta8d9e8ba7cb34ca5911bd1fe85a30f3733dedaa7 (diff)
parentd7c308c6881598d844ff85941d496160f01b50a7 (diff)
Merge pull request #143 from louib/feature/merge_databases_script
Feature : merge databases program
-rw-r--r--utils/CMakeLists.txt7
-rw-r--r--utils/kdbx-merge.cpp163
2 files changed, 170 insertions, 0 deletions
diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt
index d0cfb5a31..e3928051e 100644
--- a/utils/CMakeLists.txt
+++ b/utils/CMakeLists.txt
@@ -25,6 +25,13 @@ target_link_libraries(kdbx-extract
${GCRYPT_LIBRARIES}
${ZLIB_LIBRARIES})
+add_executable(kdbx-merge kdbx-merge.cpp)
+target_link_libraries(kdbx-merge
+ keepassx_core
+ Qt5::Core
+ ${GCRYPT_LIBRARIES}
+ ${ZLIB_LIBRARIES})
+
add_executable(entropy-meter entropy-meter.cpp)
target_link_libraries(entropy-meter zxcvbn)
diff --git a/utils/kdbx-merge.cpp b/utils/kdbx-merge.cpp
new file mode 100644
index 000000000..d67a87672
--- /dev/null
+++ b/utils/kdbx-merge.cpp
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+
+#include <QCommandLineParser>
+#include <QCoreApplication>
+#include <QFile>
+#include <QSaveFile>
+#include <QStringList>
+#include <QTextStream>
+
+#include "core/Database.h"
+#include "crypto/Crypto.h"
+#include "format/KeePass2Reader.h"
+#include "format/KeePass2Writer.h"
+#include "keys/CompositeKey.h"
+#include "keys/FileKey.h"
+#include "keys/PasswordKey.h"
+
+/*
+ * Read a key from a line of input.
+ * If the line references a valid file
+ * path, the key is loaded from file.
+ */
+CompositeKey readKeyFromLine(QString line)
+{
+
+ CompositeKey key;
+ if (QFile::exists(line)) {
+ FileKey fileKey;
+ fileKey.load(line);
+ key.addKey(fileKey);
+ }
+ else {
+ PasswordKey password;
+ password.setPassword(line);
+ key.addKey(password);
+ }
+ return key;
+
+}
+
+int main(int argc, char **argv)
+{
+
+ QCoreApplication app(argc, argv);
+
+ QCommandLineParser parser;
+ parser.setApplicationDescription(QCoreApplication::translate("main", "Merge 2 KeePassXC database files."));
+ parser.addPositionalArgument("database1", QCoreApplication::translate("main", "path of the database to merge into."));
+ parser.addPositionalArgument("database2", QCoreApplication::translate("main", "path of the database to merge from."));
+
+ QCommandLineOption samePasswordOption(QStringList() << "s" << "same-password",
+ QCoreApplication::translate("main", "use the same password for both database files."));
+
+ parser.addHelpOption();
+ parser.addOption(samePasswordOption);
+ parser.process(app);
+
+ const QStringList args = parser.positionalArguments();
+ if (args.size() != 2) {
+ parser.showHelp();
+ return 1;
+ }
+
+ if (!Crypto::init()) {
+ qFatal("Fatal error while testing the cryptographic functions:\n%s", qPrintable(Crypto::errorString()));
+ }
+
+ static QTextStream inputTextStream(stdin, QIODevice::ReadOnly);
+
+ QString line1 = inputTextStream.readLine();
+ CompositeKey key1 = readKeyFromLine(line1);
+
+ CompositeKey key2;
+ if (parser.isSet("same-password")) {
+ key2 = *key1.clone();
+ }
+ else {
+ QString line2 = inputTextStream.readLine();
+ key2 = readKeyFromLine(line2);
+ }
+
+
+ QString databaseFilename1 = args.at(0);
+ QFile dbFile1(databaseFilename1);
+ if (!dbFile1.exists()) {
+ qCritical("File %s does not exist.", qPrintable(databaseFilename1));
+ return 1;
+ }
+ if (!dbFile1.open(QIODevice::ReadOnly)) {
+ qCritical("Unable to open file %s.", qPrintable(databaseFilename1));
+ return 1;
+ }
+
+ KeePass2Reader reader1;
+ Database* db1 = reader1.readDatabase(&dbFile1, key1);
+
+ if (reader1.hasError()) {
+ qCritical("Error while parsing the database:\n%s\n", qPrintable(reader1.errorString()));
+ return 1;
+ }
+
+
+ QString databaseFilename2 = args.at(1);
+ QFile dbFile2(databaseFilename2);
+ if (!dbFile2.exists()) {
+ qCritical("File %s does not exist.", qPrintable(databaseFilename2));
+ return 1;
+ }
+ if (!dbFile2.open(QIODevice::ReadOnly)) {
+ qCritical("Unable to open file %s.", qPrintable(databaseFilename2));
+ return 1;
+ }
+
+ KeePass2Reader reader2;
+ Database* db2 = reader2.readDatabase(&dbFile2, key2);
+
+ if (reader2.hasError()) {
+ qCritical("Error while parsing the database:\n%s\n", qPrintable(reader2.errorString()));
+ return 1;
+ }
+
+ db1->merge(db2);
+
+ QSaveFile saveFile(databaseFilename1);
+ if (!saveFile.open(QIODevice::WriteOnly)) {
+ qCritical("Unable to open file %s for writing.", qPrintable(databaseFilename1));
+ return 1;
+ }
+
+ KeePass2Writer writer;
+ writer.writeDatabase(&saveFile, db1);
+
+ if (writer.hasError()) {
+ qCritical("Error while updating the database:\n%s\n", qPrintable(writer.errorString()));
+ return 1;
+ }
+
+ if (!saveFile.commit()) {
+ qCritical("Error while updating the database:\n%s\n", qPrintable(writer.errorString()));
+ return 0;
+ }
+
+ qDebug("Successfully merged the database files.\n");
+ return 1;
+
+}