blob: 298261e0073590b577ccf2c5fe1637d99545846d [file] [log] [blame] [edit]
#include "tlbmc/configs/blocklist_parser.h"
#include <cstddef>
#include <filesystem>
#include <fstream>
#include <optional>
#include <string>
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/numbers.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "nlohmann/json.hpp"
#include "json_utils.h"
namespace milotic_tlbmc {
using ::milotic::authz::GetValueAsArray;
using ::milotic::authz::GetValueAsUintFromStringOrInteger;
absl::StatusOr<BusBlocklist> GetBusBlocklist(
absl::string_view blocklist_path) {
milotic_tlbmc::BusBlocklist bus_block_list;
auto blocklist_file = std::filesystem::directory_entry(blocklist_path);
if (!std::filesystem::exists(blocklist_path) ||
!blocklist_file.is_regular_file()) {
LOG(INFO) << "No blocklist found! Continuing...";
return bus_block_list;
}
LOG(INFO) << "Blocklist found!";
std::string json_file_path = blocklist_file.path().string();
std::ifstream blocklist_json(json_file_path);
if (!blocklist_json.is_open()) {
return absl::InvalidArgumentError(
absl::StrCat("Failed to open blocklist file: ", json_file_path));
}
nlohmann::json parsed_config =
nlohmann::json::parse(blocklist_json, nullptr, /*allow_exceptions=*/false,
/*ignore_comments=*/true);
if (parsed_config.is_discarded()) {
return absl::InvalidArgumentError(absl::StrCat(
"Failed to parse blocklist file: ", json_file_path, " is illformed."));
}
const nlohmann::json::array_t* buses =
GetValueAsArray(parsed_config, "buses");
if (buses == nullptr) {
LOG(INFO) << "No buses found in the blocklist file.";
return bus_block_list;
}
for (const auto& bus : *buses) {
if (bus.is_number_unsigned()) {
// Single integer bus, we skip all addresses for this bus.
bus_block_list[bus.get<size_t>()] = std::nullopt;
continue;
}
if (!bus.is_object()) {
LOG(INFO) << "Invalid bus entry in the blocklist: " << bus.dump();
continue;
}
std::optional<size_t> bus_value =
GetValueAsUintFromStringOrInteger(bus, "bus");
const nlohmann::json::array_t* addresses =
GetValueAsArray(bus, "addresses");
if (!bus_value.has_value() || addresses == nullptr) {
LOG(INFO) << "Invalid bus entry in the blocklist: " << bus.dump();
continue;
}
auto& bus_block_list_ref = bus_block_list[*bus_value];
for (const auto& address : *addresses) {
int address_value;
if (address.is_string() &&
absl::SimpleHexAtoi(address.get<std::string>(), &address_value)) {
if (!bus_block_list_ref.has_value()) {
bus_block_list_ref = absl::flat_hash_set<size_t>();
}
bus_block_list_ref->insert(address_value);
}
}
}
return bus_block_list;
}
} // namespace milotic_tlbmc