// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "crash-reporter/selinux_violation_collector.h"

#include <map>

#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/rand_util.h>
#include <base/strings/stringprintf.h>

#include "crash-reporter/util.h"

namespace {
constexpr char kExecName[] = "selinux-violation";
constexpr char kSignatureKey[] = "sig";
constexpr char kViolationReportPath[] =
    "/run/anomaly-collector/selinux-violation";
}  // namespace

using base::FilePath;
using base::StringPrintf;

SELinuxViolationCollector::SELinuxViolationCollector()
    : violation_report_path_(kViolationReportPath) {}

SELinuxViolationCollector::~SELinuxViolationCollector() {}

bool SELinuxViolationCollector::LoadSELinuxViolation(
    std::string* content,
    std::string* signature,
    std::map<std::string, std::string>* extra_metadata) {
  std::string violation_report;
  if (!base::ReadFileToString(violation_report_path_, &violation_report)) {
    PLOG(ERROR) << "Could not open " << violation_report_path_.value();
    return false;
  }

  // Report format
  // First line:  signature
  // Second line: parsed metadata key\x01value\x02key\x01value\x02
  // Third+ line: content

  std::string::size_type signature_end_position = violation_report.find('\n');
  *signature = violation_report.substr(0, signature_end_position);

  violation_report = violation_report.substr(signature_end_position + 1);
  std::string::size_type metadata_end_position = violation_report.find('\n');
  *content = violation_report.substr(metadata_end_position + 1);

  std::string metadata_string =
      violation_report.substr(0, metadata_end_position);
  while (!metadata_string.empty()) {
    std::string::size_type key_end_position = metadata_string.find('\x01');
    std::string::size_type value_end_position = metadata_string.find('\x02');
    std::string key = metadata_string.substr(0, key_end_position);
    std::string value = metadata_string.substr(
        key_end_position + 1, value_end_position - key_end_position - 1);
    extra_metadata->emplace(key, value);
    metadata_string = metadata_string.substr(value_end_position + 1);
  }

  return !signature->empty();
}

bool SELinuxViolationCollector::Collect() {
  std::string reason = "normal collection";
  bool feedback = true;
  if (util::IsDeveloperImage() || developer_image_for_testing_) {
    feedback = true;
    reason = "always collect from developer builds";
  } else if (!is_feedback_allowed_function_()) {
    reason = "no user consent";
    feedback = false;
  } else if (ShouldDropThisReport()) {
    reason = "dropped sample";
    feedback = false;
  }
  LOG(INFO) << "Processing selinux violation: " << reason;

  if (!feedback)
    return true;

  std::string violation_signature;
  std::string content;
  std::map<std::string, std::string> extra_metadata;
  if (!LoadSELinuxViolation(&content, &violation_signature, &extra_metadata))
    return true;

  FilePath crash_directory;
  if (!GetCreatedCrashDirectoryByEuid(kRootUid, &crash_directory, nullptr))
    return true;

  std::string dump_basename = FormatDumpBasename(kExecName, time(nullptr), 0);
  FilePath meta_path = GetCrashPath(crash_directory, dump_basename, "meta");
  FilePath log_path = GetCrashPath(crash_directory, dump_basename, "log");

  if (WriteNewFile(log_path, content.data(), content.length()) !=
      static_cast<int>(content.length())) {
    PLOG(WARNING) << "Failed to write audit message to " << log_path.value();
    return true;
  }

  AddCrashMetaData(kSignatureKey, violation_signature);

  for (const auto& metadata : extra_metadata)
    AddCrashMetaData(metadata.first, metadata.second);

  WriteCrashMetaData(meta_path, kExecName, log_path.value());

  return true;
}

bool SELinuxViolationCollector::ShouldDropThisReport() {
  int random = fake_random_for_statistic_sampling_;
  if (fake_random_for_statistic_sampling_ <= 0)
    random = base::RandInt(1, 1000);
  return random != 1;
}
