summaryrefslogtreecommitdiff
path: root/tools/ckm_db_tool/ckm_db_merge.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/ckm_db_tool/ckm_db_merge.cpp')
-rw-r--r--tools/ckm_db_tool/ckm_db_merge.cpp193
1 files changed, 193 insertions, 0 deletions
diff --git a/tools/ckm_db_tool/ckm_db_merge.cpp b/tools/ckm_db_tool/ckm_db_merge.cpp
new file mode 100644
index 00000000..17e308cf
--- /dev/null
+++ b/tools/ckm_db_tool/ckm_db_merge.cpp
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2000 - 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+/*
+ * @file ckm_db_merge.cpp
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ */
+
+#include <string>
+#include <vector>
+#include <iostream>
+#include <sstream>
+#include <exception>
+
+#include <getopt.h>
+#include <unistd.h>
+
+#include <db-wrapper.h>
+
+using namespace std;
+using namespace CKM;
+
+typedef function<bool(DB::Row &row)> RowFilter;
+typedef vector<RowFilter> RowFilterVector;
+
+bool printRow(const DB::Row &row) {
+ string iv(10, ' '), data(10, ' ');
+ for (std::size_t i=0; i < iv.size(); ++i) {
+ if (row.iv.size() > i) iv[i] = row.iv[i];
+ if (row.data.size() > i) data[i] = row.data[i];
+ }
+ cout << "Read row:";
+ cout << "\n Name: " << row.name;
+ cout << "\n Owner: " << row.ownerLabel;
+ cout << "\n Exportable: " << row.exportable;
+ cout << "\n Alg type: " << static_cast<int>(row.algorithmType);
+ cout << "\n Enc schema: " << row.encryptionScheme;
+ cout << "\n Data size: " << row.dataSize;
+ cout << "\n BackendId: " << static_cast<int>(row.backendId);
+ cout << "\n Data(first 10 chars): " << data;
+ cout << "\n IV(first 10 chars): " << iv;
+ cout << "\n";
+ return true;
+}
+
+void printUsage()
+{
+ cout << "Usage: ckm_db_merge [OPTION]\n";
+ cout << "Copy data from one key-manager database into other one.\n";
+ cout << "Options:\n";
+ cout << " -v, --verbose print additional data on screen\n";
+ cout << " -s, --source UID database UID from were data will be readed - default value 0\n";
+ cout << " -t, --target UID database UID to were data will be writen - default value 0\n";
+ cout << " -p, --spass PASSWORD password for source database - default empty string\n";
+ cout << " -r, --tpass PASSWORD password for target database - default emtpy string\n";
+ cout << " -o, --owner OWNER change the owner of information in database to OWNER\n";
+ cout << " -h, --help print this help on screen\n";
+ cout << "Example: Copy data from db-5001 to db-0 (system database) and change object owner to /System\n";
+ cout << " ckm_db_merge -s 5001 -t 0 -p !@#SDFCV -o \"/System\"\n";
+ cout << "Please note: This tool automatically updates databases to newest scheme!" << endl;
+}
+
+int mergeDatabase(
+ uid_t uid1,
+ const Password &pass1,
+ uid_t uid2,
+ const Password &pass2,
+ const RowFilterVector &filters)
+{
+ DbWrapper source(uid1, pass1);
+ DbWrapper target(uid2, pass2);
+
+ int ret;
+
+ if (CKM_API_SUCCESS != (ret = source.unlock())) { // this should migrate database to newest version
+ cerr << "Unlocking source database failed: " << ret << endl;
+ return 1;
+ }
+ if (CKM_API_SUCCESS != (ret = target.unlock())) { // this should migrate database to newest version
+ cerr << "Unlocking target database failed: " << ret << endl;
+ return 1;
+ }
+
+ DB::RowVector data = source.getRows();
+
+ // apply all filters to each row
+ for (auto &e : data) {
+ bool migrate = true;
+ for (auto &f : filters) {
+ migrate &= f(e);
+ }
+ if (migrate) {
+ try {
+ target.saveRow(e);
+ } catch (const CKM::DB::SqlConnection::Exception::Base &e) {
+ cerr << "Sql exception. Migration failed or object already exist in database: " << e.DumpToString() << endl;
+ }
+ }
+ }
+
+ source.lock();
+ target.lock();
+ return 0;
+}
+
+int main(int argc, char *argv[]) {
+ Password password1, password2;
+ uid_t uid1 = 0, uid2 = 0;
+ string owner;
+ RowFilterVector filters;
+ try {
+ while (1) {
+ int option_index = 0;
+
+ static struct option long_options[] = {
+ {"verbose", no_argument, 0, 'v'},
+ {"source", required_argument, 0, 's'},
+ {"target", required_argument, 0, 't'},
+ {"spass", required_argument, 0, 'p'},
+ {"tpass", required_argument, 0, 'r'},
+ {"owner", required_argument, 0, 'o'},
+ {"help", no_argument, 0, 'h'},
+ {0, 0, 0, 0 }
+ };
+ int c = getopt_long(argc, argv, "vs:t:p:r:o:h", long_options, &option_index);
+
+ if (-1 == c)
+ break;
+
+ switch (c) {
+ case 'v':
+ filters.push_back(printRow);
+ break;
+ case 's':
+ uid1 = stoi(optarg);
+ break;
+ case 't':
+ uid2 = stoi(optarg);
+ break;
+ case 'p':
+ password1 = optarg;
+ break;
+ case 'r':
+ password2 = optarg;
+ break;
+ case 'o':
+ owner = optarg; // I cannot pass optarg to lambda because it's pointer
+ filters.push_back([=](DB::Row &row) {row.ownerLabel = owner; return true;});
+ break;
+ case 'h':
+ printUsage();
+ return 0;
+ case '?':
+ case ':':
+ default:
+ printUsage();
+ return 1;
+ }
+ }
+
+ if (uid1 == uid2) {
+ cerr << "Source database and target database must be different!" << endl;
+ return 1;
+ }
+
+ return mergeDatabase(uid1, password1, uid2, password2, filters);
+ } catch (const CKM::DB::SqlConnection::Exception::InvalidColumn &e) {
+ cerr << "Invalid Column exception was catched. Probably migration failed. " << e.DumpToString() << endl;
+ } catch (const invalid_argument &e) {
+ cerr << "Argument could not be converted" << endl;
+ } catch (const out_of_range &e) {
+ cerr << "Out of range" << endl;
+ } catch (const exception &e) {
+ cerr << "Unexpected error: " << e.what() << endl;
+ } catch (...) {
+ cerr << "Unknown exception" << endl;
+ }
+
+ return 1;
+}