1 #include "invstorage.h"
5 #include "fsstorage_read.h"
6 #include "logging/logging.h"
7 #include "sqlstorage.h"
8 #include "utilities/utils.h"
10 void INvStorage::importSimple(
const boost::filesystem::path& base_path, store_data_t store_func, load_data_t load_func,
12 if (!(this->*load_func)(
nullptr) && !imported_data_path.empty()) {
13 boost::filesystem::path abs_path = imported_data_path.get(base_path);
14 if (!boost::filesystem::exists(abs_path)) {
15 LOG_ERROR <<
"Couldn't import data: " << abs_path <<
" doesn't exist.";
18 std::string content = Utils::readFile(abs_path.string());
19 (this->*store_func)(content);
23 void INvStorage::importUpdateSimple(
const boost::filesystem::path& base_path, store_data_t store_func,
24 load_data_t load_func,
const BasedPath& imported_data_path) {
25 std::string prev_content;
28 if (!(this->*load_func)(&prev_content)) {
30 }
else if (!imported_data_path.empty()) {
31 content = Utils::readFile(imported_data_path.get(base_path).string());
32 if (Crypto::sha256digest(content) != Crypto::sha256digest(prev_content)) {
37 if (update && !imported_data_path.empty()) {
38 boost::filesystem::path abs_path = imported_data_path.get(base_path);
39 if (!boost::filesystem::exists(abs_path)) {
40 LOG_ERROR <<
"Couldn't import data: " << abs_path <<
" doesn't exist.";
43 if (content.empty()) {
44 content = Utils::readFile(abs_path.string());
46 (this->*store_func)(content);
50 void INvStorage::importPrimaryKeys(
const boost::filesystem::path& base_path,
const BasedPath& import_pubkey_path,
52 if (loadPrimaryKeys(
nullptr,
nullptr) || import_pubkey_path.empty() || import_privkey_path.empty()) {
55 const boost::filesystem::path pubkey_abs_path = import_pubkey_path.get(base_path);
56 const boost::filesystem::path privkey_abs_path = import_privkey_path.get(base_path);
57 if (!boost::filesystem::exists(pubkey_abs_path)) {
58 LOG_ERROR <<
"Couldn't import data: " << pubkey_abs_path <<
" doesn't exist.";
61 if (!boost::filesystem::exists(privkey_abs_path)) {
62 LOG_ERROR <<
"Couldn't import data: " << privkey_abs_path <<
" doesn't exist.";
65 const std::string pub_content = Utils::readFile(pubkey_abs_path.string());
66 const std::string priv_content = Utils::readFile(privkey_abs_path.string());
67 storePrimaryKeys(pub_content, priv_content);
70 void INvStorage::importInstalledVersions(
const boost::filesystem::path& base_path) {
71 std::vector<Uptane::Target> installed_versions;
72 const boost::filesystem::path file_path =
BasedPath(
"installed_versions").get(base_path);
73 loadPrimaryInstallationLog(&installed_versions,
false);
74 if (!installed_versions.empty()) {
77 size_t current_index = SIZE_MAX;
78 fsReadInstalledVersions(file_path, &installed_versions, ¤t_index);
79 if (current_index < installed_versions.size()) {
81 savePrimaryInstalledVersion(installed_versions[current_index], InstalledVersionUpdateMode::kCurrent);
82 boost::filesystem::remove(file_path);
86 void INvStorage::importData(
const ImportConfig& import_config) {
87 importPrimaryKeys(import_config.base_path, import_config.uptane_public_key_path,
88 import_config.uptane_private_key_path);
90 importUpdateSimple(import_config.base_path, &INvStorage::storeTlsCa, &INvStorage::loadTlsCa,
91 import_config.tls_cacert_path);
92 importSimple(import_config.base_path, &INvStorage::storeTlsCert, &INvStorage::loadTlsCert,
93 import_config.tls_clientcert_path);
94 importSimple(import_config.base_path, &INvStorage::storeTlsPkey, &INvStorage::loadTlsPkey,
95 import_config.tls_pkey_path);
97 importInstalledVersions(import_config.base_path);
100 std::shared_ptr<INvStorage> INvStorage::newStorage(
const StorageConfig& config,
const bool readonly) {
101 switch (config.type) {
102 case StorageType::kSqlite: {
103 boost::filesystem::path db_path = config.sqldb_path.get(config.path);
104 if (!boost::filesystem::exists(db_path) && FSStorageRead::FSStoragePresent(config)) {
107 "Migration from FS is not possible because the SQL database is configured to be readonly");
110 LOG_INFO <<
"Starting FS to SQL storage migration";
111 if (access(config.path.c_str(), R_OK | W_OK | X_OK) != 0) {
112 throw StorageException(std::string(
"Cannot read prior filesystem configuration from ") +
113 config.path.string() +
" due to insufficient permissions.");
116 old_config.type = StorageType::kFileSystem;
117 old_config.path = config.path;
119 auto sql_storage = std::make_shared<SQLStorage>(config, readonly);
121 INvStorage::FSSToSQLS(fs_storage, *sql_storage);
124 if (!boost::filesystem::exists(db_path)) {
125 LOG_INFO <<
"Bootstrap empty SQL storage";
127 LOG_INFO <<
"Use existing SQL storage: " << db_path;
129 return std::make_shared<SQLStorage>(config, readonly);
131 case StorageType::kFileSystem:
133 throw std::runtime_error(
"FSStorage has been removed in recent versions of aktualizr, please use SQLStorage");
138 std::string public_key;
139 std::string private_key;
140 if (fs_storage.loadPrimaryKeys(&public_key, &private_key)) {
141 sql_storage.storePrimaryKeys(public_key, private_key);
145 if (fs_storage.loadTlsCa(&ca)) {
146 sql_storage.storeTlsCa(ca);
150 if (fs_storage.loadTlsCert(&cert)) {
151 sql_storage.storeTlsCert(cert);
155 if (fs_storage.loadTlsPkey(&pkey)) {
156 sql_storage.storeTlsPkey(pkey);
159 std::string device_id;
160 if (fs_storage.loadDeviceId(&device_id)) {
161 sql_storage.storeDeviceId(device_id);
165 if (fs_storage.loadEcuSerials(&serials)) {
166 sql_storage.storeEcuSerials(serials);
169 if (fs_storage.loadEcuRegistered()) {
170 sql_storage.storeEcuRegistered();
173 std::vector<MisconfiguredEcu> ecus;
174 if (fs_storage.loadMisconfiguredEcus(&ecus)) {
175 sql_storage.storeMisconfiguredEcus(ecus);
178 std::vector<Uptane::Target> installed_versions;
179 size_t current_index = SIZE_MAX;
181 fs_storage.loadInstalledVersions(&installed_versions, ¤t_index);
182 for (
auto it = installed_versions.cbegin(); it != installed_versions.cend(); it++, k++) {
183 auto mode = k == current_index ? InstalledVersionUpdateMode::kCurrent : InstalledVersionUpdateMode::kNone;
184 sql_storage.savePrimaryInstalledVersion(*it, mode);
188 for (
const auto& role : Uptane::Role::Roles()) {
189 if (role == Uptane::Role::Root()) {
194 for (
auto repo : {Uptane::RepositoryType::Director(), Uptane::RepositoryType::Image()}) {
195 if (fs_storage.loadNonRoot(&meta, repo, role)) {
196 sql_storage.storeNonRoot(meta, repo, role);
201 std::string latest_root;
202 for (
auto repo : {Uptane::RepositoryType::Director(), Uptane::RepositoryType::Image()}) {
203 if (fs_storage.loadLatestRoot(&latest_root, Uptane::RepositoryType::Director())) {
204 int latest_version = Uptane::extractVersionUntrusted(latest_root);
205 for (
int version = 0; version <= latest_version; ++version) {
215 fs_storage.cleanUpAll();
218 bool INvStorage::fsReadInstalledVersions(
const boost::filesystem::path& filename,
219 std::vector<Uptane::Target>* installed_versions,
size_t* current_version) {
220 std::string current_hash;
221 if (access(filename.c_str(), R_OK) != 0) {
224 const Json::Value installed_versions_json = Utils::parseJSONFile(filename.string());
225 std::vector<Uptane::Target> new_versions;
227 for (
auto it = installed_versions_json.begin(); it != installed_versions_json.end(); ++it, ++k) {
228 if (!(*it).isObject()) {
231 t_json[
"hashes"][
"sha256"] = it.key();
233 new_versions.push_back(t);
234 if (current_version !=
nullptr) {
235 *current_version = k;
238 if (current_version !=
nullptr && (*it)[
"is_current"].asBool()) {
239 *current_version = k;
242 new_versions.push_back(t);
245 *installed_versions = new_versions;