1 #include "invstorage.h" 5 #include "fsstorage_read.h" 6 #include "logging/logging.h" 7 #include "sqlstorage.h" 8 #include "utilities/utils.h" 10 std::ostream& operator<<(std::ostream& os,
const StorageType stype) {
11 std::string stype_str;
13 case StorageType::kFileSystem:
14 stype_str =
"filesystem";
16 case StorageType::kSqlite:
20 stype_str =
"unknown";
23 os <<
'"' << stype_str <<
'"';
27 void StorageConfig::updateFromPropertyTree(
const boost::property_tree::ptree& pt) {
28 CopyFromConfig(type,
"type", pt);
29 CopyFromConfig(path,
"path", pt);
30 CopyFromConfig(sqldb_path,
"sqldb_path", pt);
31 CopyFromConfig(uptane_metadata_path,
"uptane_metadata_path", pt);
32 CopyFromConfig(uptane_private_key_path,
"uptane_private_key_path", pt);
33 CopyFromConfig(uptane_public_key_path,
"uptane_public_key_path", pt);
34 CopyFromConfig(tls_cacert_path,
"tls_cacert_path", pt);
35 CopyFromConfig(tls_pkey_path,
"tls_pkey_path", pt);
36 CopyFromConfig(tls_clientcert_path,
"tls_clientcert_path", pt);
39 void StorageConfig::writeToStream(std::ostream& out_stream)
const {
40 writeOption(out_stream, type,
"type");
41 writeOption(out_stream, path,
"path");
42 writeOption(out_stream, sqldb_path.get(
""),
"sqldb_path");
43 writeOption(out_stream, uptane_metadata_path.get(
""),
"uptane_metadata_path");
44 writeOption(out_stream, uptane_private_key_path.get(
""),
"uptane_private_key_path");
45 writeOption(out_stream, uptane_public_key_path.get(
""),
"uptane_public_key_path");
46 writeOption(out_stream, tls_cacert_path.get(
""),
"tls_cacert_path");
47 writeOption(out_stream, tls_pkey_path.get(
""),
"tls_pkey_path");
48 writeOption(out_stream, tls_clientcert_path.get(
""),
"tls_clientcert_path");
51 void ImportConfig::updateFromPropertyTree(
const boost::property_tree::ptree& pt) {
52 CopyFromConfig(base_path,
"base_path", pt);
53 CopyFromConfig(uptane_private_key_path,
"uptane_private_key_path", pt);
54 CopyFromConfig(uptane_public_key_path,
"uptane_public_key_path", pt);
55 CopyFromConfig(tls_cacert_path,
"tls_cacert_path", pt);
56 CopyFromConfig(tls_pkey_path,
"tls_pkey_path", pt);
57 CopyFromConfig(tls_clientcert_path,
"tls_clientcert_path", pt);
60 void ImportConfig::writeToStream(std::ostream& out_stream)
const {
61 writeOption(out_stream, base_path,
"base_path");
62 writeOption(out_stream, uptane_private_key_path.get(
""),
"uptane_private_key_path");
63 writeOption(out_stream, uptane_public_key_path.get(
""),
"uptane_public_key_path");
64 writeOption(out_stream, tls_cacert_path.get(
""),
"tls_cacert_path");
65 writeOption(out_stream, tls_pkey_path.get(
""),
"tls_pkey_path");
66 writeOption(out_stream, tls_clientcert_path.get(
""),
"tls_clientcert_path");
69 void INvStorage::importSimple(
const boost::filesystem::path& base_path, store_data_t store_func, load_data_t load_func,
71 if (!(this->*load_func)(
nullptr) && !imported_data_path.empty()) {
72 boost::filesystem::path abs_path = imported_data_path.get(base_path);
73 if (!boost::filesystem::exists(abs_path)) {
74 LOG_ERROR <<
"Couldn't import data: " << abs_path <<
" doesn't exist.";
77 std::string content = Utils::readFile(abs_path.string());
78 (this->*store_func)(content);
82 void INvStorage::importUpdateSimple(
const boost::filesystem::path& base_path, store_data_t store_func,
83 load_data_t load_func,
const BasedPath& imported_data_path) {
84 std::string prev_content;
87 if (!(this->*load_func)(&prev_content)) {
89 }
else if (!imported_data_path.empty()) {
90 content = Utils::readFile(imported_data_path.get(base_path).string());
91 if (Crypto::sha256digest(content) != Crypto::sha256digest(prev_content)) {
96 if (update && !imported_data_path.empty()) {
97 boost::filesystem::path abs_path = imported_data_path.get(base_path);
98 if (!boost::filesystem::exists(abs_path)) {
99 LOG_ERROR <<
"Couldn't import data: " << abs_path <<
" doesn't exist.";
102 if (content.empty()) {
103 content = Utils::readFile(abs_path.string());
105 (this->*store_func)(content);
109 void INvStorage::importPrimaryKeys(
const boost::filesystem::path& base_path,
const BasedPath& import_pubkey_path,
111 if (loadPrimaryKeys(
nullptr,
nullptr) || import_pubkey_path.empty() || import_privkey_path.empty()) {
114 boost::filesystem::path pubkey_abs_path = import_pubkey_path.get(base_path);
115 boost::filesystem::path privkey_abs_path = import_privkey_path.get(base_path);
116 if (!boost::filesystem::exists(pubkey_abs_path)) {
117 LOG_ERROR <<
"Couldn't import data: " << pubkey_abs_path <<
" doesn't exist.";
120 if (!boost::filesystem::exists(privkey_abs_path)) {
121 LOG_ERROR <<
"Couldn't import data: " << privkey_abs_path <<
" doesn't exist.";
124 std::string pub_content = Utils::readFile(pubkey_abs_path.string());
125 std::string priv_content = Utils::readFile(privkey_abs_path.string());
126 storePrimaryKeys(pub_content, priv_content);
129 void INvStorage::importData(
const ImportConfig& import_config) {
130 importPrimaryKeys(import_config.base_path, import_config.uptane_public_key_path,
131 import_config.uptane_private_key_path);
133 importUpdateSimple(import_config.base_path, &INvStorage::storeTlsCa, &INvStorage::loadTlsCa,
134 import_config.tls_cacert_path);
135 importSimple(import_config.base_path, &INvStorage::storeTlsCert, &INvStorage::loadTlsCert,
136 import_config.tls_clientcert_path);
137 importSimple(import_config.base_path, &INvStorage::storeTlsPkey, &INvStorage::loadTlsPkey,
138 import_config.tls_pkey_path);
141 std::shared_ptr<INvStorage> INvStorage::newStorage(
const StorageConfig& config,
bool readonly) {
142 switch (config.type) {
143 case StorageType::kSqlite: {
144 boost::filesystem::path db_path = config.sqldb_path.get(config.path);
145 if (!boost::filesystem::exists(db_path) && boost::filesystem::exists(config.path)) {
147 throw StorageException(
"Migration from FS is not possible, because of readonly database");
150 LOG_INFO <<
"Starting FS to SQL storage migration";
151 if (access(config.path.c_str(), R_OK | W_OK | X_OK) != 0) {
152 throw StorageException(std::string(
"Cannot read prior filesystem configuration from ") +
153 config.path.string() +
" due to insufficient permissions.");
156 old_config.type = StorageType::kFileSystem;
157 old_config.path = config.path;
159 auto sql_storage = std::make_shared<SQLStorage>(config, readonly);
161 INvStorage::FSSToSQLS(fs_storage, *sql_storage);
164 if (!boost::filesystem::exists(db_path)) {
165 LOG_INFO <<
"Bootstrap empty SQL storage";
167 LOG_INFO <<
"Use existing SQL storage: " << db_path;
169 return std::make_shared<SQLStorage>(config, readonly);
171 case StorageType::kFileSystem:
173 throw std::runtime_error(
"FSStorage has been removed in recent versions of aktualizr, please use SQLStorage");
178 std::string public_key;
179 std::string private_key;
180 if (fs_storage.loadPrimaryKeys(&public_key, &private_key)) {
181 sql_storage.storePrimaryKeys(public_key, private_key);
185 if (fs_storage.loadTlsCa(&ca)) {
186 sql_storage.storeTlsCa(ca);
190 if (fs_storage.loadTlsCert(&cert)) {
191 sql_storage.storeTlsCert(cert);
195 if (fs_storage.loadTlsPkey(&pkey)) {
196 sql_storage.storeTlsPkey(pkey);
199 std::string device_id;
200 if (fs_storage.loadDeviceId(&device_id)) {
201 sql_storage.storeDeviceId(device_id);
205 if (fs_storage.loadEcuSerials(&serials)) {
206 sql_storage.storeEcuSerials(serials);
209 if (fs_storage.loadEcuRegistered()) {
210 sql_storage.storeEcuRegistered();
213 std::vector<MisconfiguredEcu> ecus;
214 if (fs_storage.loadMisconfiguredEcus(&ecus)) {
215 sql_storage.storeMisconfiguredEcus(ecus);
219 if (fs_storage.loadInstallationResult(&res)) {
220 sql_storage.storeInstallationResult(res);
223 std::vector<Uptane::Target> installed_versions;
224 std::string current_hash = fs_storage.loadInstalledVersions(&installed_versions);
225 if (installed_versions.size() != 0u) {
226 sql_storage.storeInstalledVersions(installed_versions, current_hash);
230 for (
auto role : Uptane::Role::Roles()) {
231 if (role == Uptane::Role::Root()) {
236 for (
auto repo : {Uptane::RepositoryType::Director, Uptane::RepositoryType::Images}) {
237 if (fs_storage.loadNonRoot(&meta, repo, role)) {
238 sql_storage.storeNonRoot(meta, repo, role);
243 std::string latest_root;
244 for (
auto repo : {Uptane::RepositoryType::Director, Uptane::RepositoryType::Images}) {
245 if (fs_storage.loadLatestRoot(&latest_root, Uptane::RepositoryType::Director)) {
246 int latest_version = Uptane::extractVersionUntrusted(latest_root);
247 for (
int version = 0; version <= latest_version; ++version) {
257 fs_storage.cleanUpAll();
260 void INvStorage::saveInstalledVersion(
const Uptane::Target& target) {
261 std::vector<Uptane::Target> versions;
262 std::string new_current_hash;
263 loadInstalledVersions(&versions);
264 if (std::find(versions.begin(), versions.end(), target) == versions.end()) {
265 versions.push_back(target);
267 storeInstalledVersions(versions, target.sha256Hash());
Metadata version numbers.