Aktualizr
C++ SOTA Client
All Classes Namespaces Files Functions Variables Enumerations Enumerator Pages
virtualsecondary.cc
1 #include <boost/algorithm/hex.hpp>
2 #include <boost/filesystem.hpp>
3 #include <fstream>
4 
5 #include "crypto/crypto.h"
6 #include "utilities/fault_injection.h"
7 #include "utilities/utils.h"
8 #include "virtualsecondary.h"
9 
10 namespace Primary {
11 
12 const char* const VirtualSecondaryConfig::Type = "virtual";
13 
14 VirtualSecondaryConfig::VirtualSecondaryConfig(const Json::Value& json_config) : ManagedSecondaryConfig(Type) {
15  partial_verifying = json_config["partial_verifying"].asBool();
16  ecu_serial = json_config["ecu_serial"].asString();
17  ecu_hardware_id = json_config["ecu_hardware_id"].asString();
18  full_client_dir = json_config["full_client_dir"].asString();
19  ecu_private_key = json_config["ecu_private_key"].asString();
20  ecu_public_key = json_config["ecu_public_key"].asString();
21  firmware_path = json_config["firmware_path"].asString();
22  target_name_path = json_config["target_name_path"].asString();
23  metadata_path = json_config["metadata_path"].asString();
24 }
25 
26 std::vector<VirtualSecondaryConfig> VirtualSecondaryConfig::create_from_file(
27  const boost::filesystem::path& file_full_path) {
28  Json::Value json_config;
29  std::ifstream json_file(file_full_path.string());
30  Json::parseFromStream(Json::CharReaderBuilder(), json_file, &json_config, nullptr);
31  json_file.close();
32 
33  std::vector<VirtualSecondaryConfig> sec_configs;
34  sec_configs.reserve(json_config[Type].size());
35 
36  for (const auto& item : json_config[Type]) {
37  sec_configs.emplace_back(VirtualSecondaryConfig(item));
38  }
39  return sec_configs;
40 }
41 
42 void VirtualSecondaryConfig::dump(const boost::filesystem::path& file_full_path) const {
43  Json::Value json_config;
44 
45  json_config["partial_verifying"] = partial_verifying;
46  json_config["ecu_serial"] = ecu_serial;
47  json_config["ecu_hardware_id"] = ecu_hardware_id;
48  json_config["full_client_dir"] = full_client_dir.string();
49  json_config["ecu_private_key"] = ecu_private_key;
50  json_config["ecu_public_key"] = ecu_public_key;
51  json_config["firmware_path"] = firmware_path.string();
52  json_config["target_name_path"] = target_name_path.string();
53  json_config["metadata_path"] = metadata_path.string();
54 
55  Json::Value root;
56  root[Type].append(json_config);
57 
58  Json::StreamWriterBuilder json_bwriter;
59  json_bwriter["indentation"] = "\t";
60  std::unique_ptr<Json::StreamWriter> const json_writer(json_bwriter.newStreamWriter());
61 
62  boost::filesystem::create_directories(file_full_path.parent_path());
63  std::ofstream json_file(file_full_path.string());
64  json_writer->write(root, &json_file);
65  json_file.close();
66 }
67 
68 VirtualSecondary::VirtualSecondary(Primary::VirtualSecondaryConfig sconfig_in)
69  : ManagedSecondary(std::move(sconfig_in)) {}
70 
71 bool VirtualSecondary::storeFirmware(const std::string& target_name, const std::string& content) {
72  if (fiu_fail((std::string("secondary_install_") + getSerial().ToString()).c_str()) != 0) {
73  // consider changing this approach of the fault injection, since the current approach impacts the non-test code flow
74  // here as well as it doesn't test the installation failure on secondary from an end-to-end perspective as it
75  // injects an error on the middle of the control flow that would have happened if an installation error had happened
76  // in case of the virtual or the ip-secondary or any other secondary, e.g. add a mock secondary that returns an
77  // error to sendFirmware/install request we might consider passing the installation description message from
78  // Secondary, not just bool and/or data::ResultCode::Numeric
79  return false;
80  }
81 
82  // TODO: it does not make much sense to read, pass via a function parameter to Virtual secondary
83  // and store the file that has been already downloaded by Primary
84  // Primary should apply ECU (primary, virtual, secondary) specific verification, download and installation logic in
85  // the first place
86  Utils::writeFile(sconfig.target_name_path, target_name);
87  Utils::writeFile(sconfig.firmware_path, content);
88  sync();
89  return true;
90 }
91 
92 bool VirtualSecondary::getFirmwareInfo(Uptane::InstalledImageInfo& firmware_info) const {
93  std::string content;
94 
95  if (!boost::filesystem::exists(sconfig.target_name_path) || !boost::filesystem::exists(sconfig.firmware_path)) {
96  firmware_info.name = std::string("noimage");
97  content = "";
98  } else {
99  firmware_info.name = Utils::readFile(sconfig.target_name_path.string());
100  content = Utils::readFile(sconfig.firmware_path.string());
101  }
102  firmware_info.hash = Uptane::ManifestIssuer::generateVersionHashStr(content);
103  firmware_info.len = content.size();
104 
105  return true;
106 }
107 
108 } // namespace Primary
Uptane::InstalledImageInfo
Definition: tuf.h:132
Primary::VirtualSecondaryConfig
Definition: virtualsecondary.h:11