2 * Copyright (c) 2000 - 2020 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
17 * @file ckm_db_merge.cpp
18 * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
31 #include "db-wrapper.h"
37 typedef function<bool(DB::Row &row)> RowFilter;
38 typedef vector<RowFilter> RowFilterVector;
40 bool printRow(const DB::Row &row) {
41 string iv(10, ' '), data(10, ' ');
42 for (std::size_t i=0; i < iv.size(); ++i) {
43 if (row.iv.size() > i) iv[i] = row.iv[i];
44 if (row.data.size() > i) data[i] = row.data[i];
47 cout << "\n Name: " << row.name;
48 cout << "\n Owner: " << row.owner;
49 cout << "\n Exportable: " << row.exportable;
50 cout << "\n Alg type: " << static_cast<int>(row.algorithmType);
51 cout << "\n Enc schema: " << row.encryptionScheme;
52 cout << "\n Data size: " << row.dataSize;
53 cout << "\n BackendId: " << static_cast<int>(row.backendId);
54 cout << "\n Data(first 10 chars): " << data;
55 cout << "\n IV(first 10 chars): " << iv;
62 cout << "Usage: ckm_db_merge [OPTION]\n";
63 cout << "Copy data from one key-manager database into other one.\n";
65 cout << " -v, --verbose print additional data on screen\n";
66 cout << " -s, --source UID database UID from were data will be readed - default value 0\n";
67 cout << " -t, --target UID database UID to were data will be writen - default value 0\n";
68 cout << " -p, --spass PASSWORD password for source database - default empty string\n";
69 cout << " -r, --tpass PASSWORD password for target database - default emtpy string\n";
70 cout << " -o, --owner OWNER change the owner of information in database to OWNER\n";
71 cout << " -h, --help print this help on screen\n";
72 cout << "Example: Copy data from db-5001 to db-0 (system database) and change object owner to /System\n";
73 cout << " ckm_db_merge -s 5001 -t 0 -p !@#SDFCV -o \"/System\"\n";
74 cout << "Please note: This tool automatically updates databases to newest scheme!" << endl;
79 const Password &pass1,
81 const Password &pass2,
82 const RowFilterVector &filters)
84 DbWrapper source(uid1, pass1);
85 DbWrapper target(uid2, pass2);
89 if (CKM_API_SUCCESS != (ret = source.unlock())) { // this should migrate database to newest version
90 UI::error() << "unlocking source database failed: " << APICodeToString(ret) << endl;
93 if (CKM_API_SUCCESS != (ret = target.unlock())) { // this should migrate database to newest version
94 UI::error() << "unlocking target database failed: " << APICodeToString(ret) << endl;
98 DB::RowVector data = source.getRows();
100 // apply all filters to each row
101 for (auto &e : data) {
103 for (auto &f : filters) {
109 } catch (const CKM::DB::SqlConnection::Exception::Base &exc) {
111 << "sql exception, migration failed or object already exists in the database: "
112 << exc.DumpToString() << endl;
122 int main(int argc, char *argv[]) {
123 Password password1, password2;
124 uid_t uid1 = 0, uid2 = 0;
126 RowFilterVector filters;
129 int option_index = 0;
131 static struct option long_options[] = {
132 {"verbose", no_argument, 0, 'v'},
133 {"source", required_argument, 0, 's'},
134 {"target", required_argument, 0, 't'},
135 {"spass", required_argument, 0, 'p'},
136 {"tpass", required_argument, 0, 'r'},
137 {"owner", required_argument, 0, 'o'},
138 {"help", no_argument, 0, 'h'},
141 int c = getopt_long(argc, argv, "vs:t:p:r:o:h", long_options, &option_index);
148 filters.push_back(printRow);
163 owner = optarg; // I cannot pass optarg to lambda because it's pointer
164 filters.push_back([=](DB::Row &row) {row.owner = owner; return true;});
178 UI::error() << "source and target databases must be different" << endl;
182 return mergeDatabase(uid1, password1, uid2, password2, filters);
183 } catch (const CKM::DB::SqlConnection::Exception::InvalidColumn &e) {
184 UI::error() << "invalid column exception, probably a failed migration: " << e.DumpToString()
186 } catch (const invalid_argument &e) {
187 UI::error() << "argument could not be converted: " << e.what() << endl;
188 } catch (const out_of_range &e) {
189 UI::error() << "argument out of range: " << e.what() << endl;
190 } catch (const exception &e) {
191 UI::error() << "unexpected exception: " << e.what() << endl;
193 UI::error() << "unknown exception" << endl;