| #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 |