// Copyright (c) 2012 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.

#ifndef CRASH_REPORTER_CRASH_COLLECTOR_H_
#define CRASH_REPORTER_CRASH_COLLECTOR_H_

#include <sys/stat.h>
#include <sys/types.h>

#include <memory>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

#include <base/files/file_path.h>
#include <base/macros.h>
#include <base/optional.h>
#include <base/time/clock.h>
#include <base/time/time.h>
#include <brillo/dbus/file_descriptor.h>
#include <gtest/gtest_prod.h>  // for FRIEND_TEST
#include <session_manager/dbus-proxies.h>
#include <debugd/dbus-proxies.h>
#include <metrics/metrics_library.h>

constexpr mode_t kSystemCrashFilesMode = 0660;

// User crash collector.
class CrashCollector {
 public:
  typedef bool (*IsFeedbackAllowedFunction)();

  enum CrashDirectorySelectionMethod {
    // Force reports to be stored in the user crash directory, even if we are
    // not running as the "chronos" user.
    kAlwaysUseUserCrashDirectory,
    // Use the normal crash directory selection process: Store in the user crash
    // directory if running as the "chronos" user, otherwise store in the system
    // crash directory.
    kUseNormalCrashDirectorySelectionMethod
  };

  enum CrashSendingMode {
    // Use the normal crash sending mode: Write crash files out to disk, and
    // assume crash_sender will be along later to send them out.
    kNormalCrashSendMode,
    // Use a special mode suitable when we are in a login-crash-loop. where
    // Chrome keeps crashing right after login, and we're about to log the user
    // out because we can't get into a good logged-in state. Write the crash
    // files into special in-memory locations, since the normal user crash
    // directory is in the cryptohome which will be locked out momentarily, and
    // send those in-memory files over to debugd for immediate upload, since
    // they are in volatile storage and the user may turn off their machine in
    // frustration shortly.
    kCrashLoopSendingMode
  };

  enum ErrorType {
    kErrorNone,
    kErrorSystemIssue,
    kErrorReadCoreData,
    kErrorUnusableProcFiles,
    kErrorInvalidCoreFile,
    kErrorUnsupported32BitCoreFile,
    kErrorCore2MinidumpConversion,
  };

  explicit CrashCollector(const std::string& collector_name,
                          const std::string& tag = "");

  explicit CrashCollector(
      const std::string& collector_name,
      CrashDirectorySelectionMethod crash_directory_selection_method,
      CrashSendingMode crash_sending_mode,
      const std::string& tag = "");

  virtual ~CrashCollector();

  void set_lsb_release_for_test(const base::FilePath& lsb_release) {
    lsb_release_ = lsb_release;
  }

  // For testing, set the directory always returned by
  // GetCreatedCrashDirectoryByEuid.
  void set_crash_directory_for_test(const base::FilePath& forced_directory) {
    forced_crash_directory_ = forced_directory;
  }

  // For testing, set the directory where cached files are stored instead of
  // kCrashReporterStatePath.
  void set_reporter_state_directory_for_test(
      const base::FilePath& forced_directory) {
    crash_reporter_state_path_ = forced_directory;
  }

  void set_metrics_library_for_test(
      std::unique_ptr<MetricsLibraryInterface> metrics_lib) {
    metrics_lib_ = std::move(metrics_lib);
  }

  // For testing, set the log config file path instead of kDefaultLogConfig.
  void set_log_config_path(const std::string& path) {
    log_config_path_ = base::FilePath(path);
  }

  // For testing, set the clock to use to get the report timestamp.
  void set_test_clock(std::unique_ptr<base::Clock> test_clock) {
    test_clock_ = std::move(test_clock);
  }

  // For testing, use to set the kernel version rather than relying on uname.
  void set_test_kernel_info(const std::string& kernel_name,
                            const std::string& kernel_version) {
    test_kernel_name_ = kernel_name;
    test_kernel_version_ = kernel_version;
  }

  // For testing, return the in-memory files generated when in
  // kCrashLoopSendingMode. Since in_memory_files_ is a move-only type, this
  // clears the in_memory_files_ member variable.
  std::vector<std::tuple<std::string, brillo::dbus_utils::FileDescriptor>>
  get_in_memory_files_for_test() {
    return std::move(in_memory_files_);
  }

  // Initialize the crash collector for detection of crashes, given a
  // metrics collection enabled oracle.
  void Initialize(IsFeedbackAllowedFunction is_metrics_allowed, bool early);

  // Return the number of bytes successfully written by all calls to
  // WriteNewFile() and WriteNewCompressedFile() so far. For
  // WriteNewCompressedFile(), the count is of bytes on disk, after compression.
  off_t get_bytes_written() const { return bytes_written_; }

  // Initialize the system crash paths.
  static bool InitializeSystemCrashDirectories(bool early);

  // Initialize metrics path. Returns true if flag directory is created.
  static bool InitializeSystemMetricsDirectories();

  // Add non-standard meta data to the crash metadata file.  Call
  // before calling FinishCrash.  Key must not contain "=" or "\n" characters.
  // Value must not contain "\n" characters.
  void AddCrashMetaData(const std::string& key, const std::string& value);

 protected:
  friend class CrashCollectorTest;
  FRIEND_TEST(ArcContextTest, GetAndroidVersion);
  FRIEND_TEST(ChromeCollectorTest, HandleCrash);
  FRIEND_TEST(CrashCollectorTest, CrashLoopModeCreatesInMemoryCompressedFiles);
  FRIEND_TEST(CrashCollectorTest,
              DISABLED_CrashLoopModeCreatesInMemoryCompressedFiles);
  FRIEND_TEST(CrashCollectorTest, CrashLoopModeCreatesInMemoryFiles);
  FRIEND_TEST(CrashCollectorTest, DISABLED_CrashLoopModeCreatesInMemoryFiles);
  FRIEND_TEST(CrashCollectorTest, CrashLoopModeCreatesMultipleInMemoryFiles);
  FRIEND_TEST(CrashCollectorTest,
              DISABLED_CrashLoopModeCreatesMultipleInMemoryFiles);
  FRIEND_TEST(CrashCollectorTest,
              CrashLoopModeWillNotCreateDuplicateCompressedFileNames);
  FRIEND_TEST(CrashCollectorTest,
              DISABLED_CrashLoopModeWillNotCreateDuplicateCompressedFileNames);
  FRIEND_TEST(CrashCollectorTest, CrashLoopModeWillNotCreateDuplicateFileNames);
  FRIEND_TEST(CrashCollectorTest,
              DISABLED_CrashLoopModeWillNotCreateDuplicateFileNames);
  FRIEND_TEST(CrashCollectorTest, CheckHasCapacityCorrectBasename);
  FRIEND_TEST(CrashCollectorTest, CheckHasCapacityStrangeNames);
  FRIEND_TEST(CrashCollectorTest, CheckHasCapacityUsual);
  FRIEND_TEST(CrashCollectorTest, CreateDirectoryWithSettingsMode);
  FRIEND_TEST(CrashCollectorTest, CreateDirectoryWithSettingsNonDir);
  FRIEND_TEST(CrashCollectorTest, CreateDirectoryWithSettingsSubdir);
  FRIEND_TEST(CrashCollectorTest, CreateDirectoryWithSettingsSymlinks);
  FRIEND_TEST(CrashCollectorTest,
              CreateDirectoryWithSettings_FixPermissionsShallow);
  FRIEND_TEST(CrashCollectorTest,
              CreateDirectoryWithSettings_FixPermissionsRecursive);
  FRIEND_TEST(CrashCollectorTest,
              RunAsRoot_CreateDirectoryWithSettings_FixOwners);
  FRIEND_TEST(CrashCollectorTest,
              CreateDirectoryWithSettings_FixSubdirPermissions);
  FRIEND_TEST(CrashCollectorTest, FormatDumpBasename);
  FRIEND_TEST(CrashCollectorTest, GetCrashDirectoryInfo);
  FRIEND_TEST(CrashCollectorTest, GetCrashPath);
  FRIEND_TEST(CrashCollectorTest, GetLogContents);
  FRIEND_TEST(CrashCollectorTest, GetMultipleLogContents);
  FRIEND_TEST(CrashCollectorTest, GetProcessTree);
  FRIEND_TEST(CrashCollectorTest, GetUptime);
  FRIEND_TEST(CrashCollectorTest, Initialize);
  FRIEND_TEST(CrashCollectorTest, MetaData);
  FRIEND_TEST(CrashCollectorTest, MetaDataDoesntCreateSymlink);
  FRIEND_TEST(CrashCollectorTest, MetaDataDoesntOverwriteSymlink);
  FRIEND_TEST(CrashCollectorTest, CollectionLogsToUMA);
  FRIEND_TEST(CrashCollectorTest, ParseProcessTicksFromStat);
  FRIEND_TEST(CrashCollectorTest, Sanitize);
  FRIEND_TEST(CrashCollectorTest, StripMacAddressesBasic);
  FRIEND_TEST(CrashCollectorTest, StripMacAddressesBulk);
  FRIEND_TEST(CrashCollectorTest, StripSensitiveDataSample);
  FRIEND_TEST(CrashCollectorTest, StripEmailAddresses);
  FRIEND_TEST(CrashCollectorTest, StripSerialNumbers);
  FRIEND_TEST(CrashCollectorTest, RemoveNewFileFailsOnNonExistantFiles);
  FRIEND_TEST(CrashCollectorTest,
              RemoveNewFileFailsOnNonExistantFilesInCrashLoopMode);
  FRIEND_TEST(CrashCollectorTest, RemoveNewFileRemovesCompressedFiles);
  FRIEND_TEST(CrashCollectorTest,
              RemoveNewFileRemovesCompressedFilesInCrashLoopMode);
  FRIEND_TEST(CrashCollectorTest,
              DISABLED_RemoveNewFileRemovesCompressedFilesInCrashLoopMode);
  FRIEND_TEST(CrashCollectorTest,
              RemoveNewFileRemovesCorrectFileInCrashLoopMode);
  FRIEND_TEST(CrashCollectorTest,
              DISABLED_RemoveNewFileRemovesCorrectFileInCrashLoopMode);
  FRIEND_TEST(CrashCollectorTest, RemoveNewFileRemovesNormalFiles);
  FRIEND_TEST(CrashCollectorTest,
              RemoveNewFileRemovesNormalFilesInCrashLoopMode);
  FRIEND_TEST(CrashCollectorTest,
              DISABLED_RemoveNewFileRemovesNormalFilesInCrashLoopMode);
  FRIEND_TEST(CrashCollectorTest, TruncatedLog);
  FRIEND_TEST(CrashCollectorTest, WriteNewFile);
  FRIEND_TEST(CrashCollectorTest, WriteNewCompressedFile);
  FRIEND_TEST(CrashCollectorTest, WriteNewCompressedFileFailsIfFileExists);

  // Default value if OS version/description cannot be determined.
  static const char* const kUnknownValue;

  // Set maximum enqueued crashes in a crash directory.
  static const int kMaxCrashDirectorySize;

  // UID for root account.
  static const uid_t kRootUid;

  // Set up D-Bus.
  virtual void SetUpDBus();

  // Writes |data| of |size| to |filename|, which must be a new file.
  // If the file already exists or writing fails, return a negative value.
  // Otherwise returns the number of bytes written.
  int WriteNewFile(const base::FilePath& filename, const char* data, int size);

  // Writes |data| of |size| to |filename|, which must be a new file ending in
  // ".gz". File will be a gzip-compressed file. Returns true on success,
  // false on failure.
  bool WriteNewCompressedFile(const base::FilePath& filename,
                              const char* data,
                              size_t size);

  // Deletes a file created by WriteNewFile() or WriteNewCompressedFile(). Also
  // decrements get_bytes_written() by the file size. Needed because
  // base::DeleteFile() doesn't work on files created when in
  // kCrashLoopSendingMode.
  bool RemoveNewFile(const base::FilePath& filename);

  // Return a filename that has only [a-z0-1_] characters by mapping
  // all others into '_'.
  std::string Sanitize(const std::string& name);

  // Strip any data that the user might not want sent up to the crash server.
  // |contents| is modified in-place.
  void StripSensitiveData(std::string* contents);
  void StripMacAddresses(std::string* contents);
  void StripEmailAddresses(std::string* contents);
  void StripSerialNumbers(std::string* contents);

  bool GetUserCrashDirectories(std::vector<base::FilePath>* directories,
                               bool use_non_chronos_cryptohome);
  base::FilePath GetUserCrashDirectory(bool use_non_chronos_cryptohome);
  base::Optional<base::FilePath> GetCrashDirectoryInfo(
      uid_t process_euid,
      uid_t default_user_id,
      bool use_non_chronos_cryptohome,
      mode_t* mode,
      uid_t* directory_owner,
      gid_t* directory_group);

  // Determines the crash directory for given euid, and creates the directory if
  // necessary with appropriate permissions.  If |out_of_capacity| is not
  // nullptr, it is set to indicate if the call failed due to not having
  // capacity in the crash directory. Returns true whether or not directory
  // needed to be created, false on any failure.  If the crash directory is at
  // capacity, returns false.  If |use_non_chronos_cryptohome| is set, use the
  // new crash directory under /run/daemon-store/crash/<user-hash>.
  bool GetCreatedCrashDirectoryByEuid(uid_t euid,
                                      base::FilePath* crash_file_path,
                                      bool* out_of_capacity,
                                      bool use_non_chronos_cryptohome = false);

  // Create a directory using the specified mode/user/group, and make sure it
  // is actually a directory with the specified permissions.
  // If |files_mode| is set, the call will recursively change permissions on
  // |dir| such that:
  //   * any directories under it in the file heirarchy have mode |mode|
  //   * any files under it in the heirarchy have mode |files_mode|
  //   * all files AND directories under it are owned by owner:group
  static bool CreateDirectoryWithSettings(const base::FilePath& dir,
                                          mode_t mode,
                                          uid_t owner,
                                          gid_t group,
                                          int* dir_fd,
                                          mode_t files_mode = 0);

  // Format crash name based on components.
  std::string FormatDumpBasename(const std::string& exec_name,
                                 time_t timestamp,
                                 pid_t pid);

  // Create a file path to a file in |crash_directory| with the given
  // |basename| and |extension|.
  base::FilePath GetCrashPath(const base::FilePath& crash_directory,
                              const std::string& basename,
                              const std::string& extension);

  // Returns the path /proc/<pid>.
  static base::FilePath GetProcessPath(pid_t pid);

  static bool GetUptime(base::TimeDelta* uptime);
  static bool GetUptimeAtProcessStart(pid_t pid, base::TimeDelta* uptime);

  virtual bool GetExecutableBaseNameFromPid(pid_t pid, std::string* base_name);

  // Check given crash directory still has remaining capacity for another
  // crash.
  bool CheckHasCapacity(const base::FilePath& crash_directory);
  bool CheckHasCapacity(const base::FilePath& crash_directory,
                        const std::string& display_path);

  // Write a log applicable to |exec_name| to |output_file| based on the
  // log configuration file at |config_path|. If |output_file| ends in .gz, it
  // will be compressed in gzip format, otherwise it will be plaintext.
  bool GetLogContents(const base::FilePath& config_path,
                      const std::string& exec_name,
                      const base::FilePath& output_file);

  // Write logs applicable to |exec_names| to |output_file| based on the
  // log configuration file at |config_path|. If |output_file| ends in .gz, it
  // will be compressed in gzip format, otherwise it will be plaintext.
  // This function returns false only if all of the log commands fail to run.
  bool GetMultipleLogContents(const base::FilePath& config_path,
                              const std::vector<std::string>& exec_names,
                              const base::FilePath& output_file);

  // Write details about the process tree of |pid| to |output_file|.
  bool GetProcessTree(pid_t pid, const base::FilePath& output_file);

  // Add a file to be uploaded to the crash reporter server. The file must
  // persist until the crash report is sent; ideally it should live in the same
  // place as the .meta file, so it can be cleaned up automatically.
  void AddCrashMetaUploadFile(const std::string& key, const std::string& path);

  // Add non-standard meta data to the crash metadata file.
  // Data added though this call will be uploaded to the crash reporter server,
  // appearing as a form field. Virtual for testing.
  virtual void AddCrashMetaUploadData(const std::string& key,
                                      const std::string& value);

  // Like AddCrashMetaUploadData, but loads the value from the file at |path|.
  // The file is not uploaded as an attachment, unlike AddCrashMetaUploadFile.
  void AddCrashMetaUploadText(const std::string& key, const std::string& path);

  // Gets the corresponding value for |key| from the lsb-release file.
  std::string GetLsbReleaseValue(const std::string& key) const;

  // Returns the OS version written to the metadata file.
  virtual std::string GetOsVersion() const;

  // Returns the OS milestone written to the metadata file.
  virtual std::string GetOsMilestone() const;

  // Returns the OS description written to the metadata file.
  virtual std::string GetOsDescription() const;

  // Returns the kernel name from uname (e.g. "Linux").
  std::string GetKernelName() const;

  // Returns the uname string formatted as
  // 3.8.11 #1 SMP Wed Aug 22 02:18:30 PDT 2018
  std::string GetKernelVersion() const;

  // Called after all files have been written and we want to send out this
  // crash. Write a file of metadata about crash and, if in crash-loop mode,
  // sends the UploadSingleCrash message to debugd. Not called if we failed to
  // make a good crash report.
  virtual void FinishCrash(const base::FilePath& meta_path,
                           const std::string& exec_name,
                           const std::string& payload_name);

  // Returns true if chrome crashes should be handled.
  bool ShouldHandleChromeCrashes();

  IsFeedbackAllowedFunction is_feedback_allowed_function_;
  std::string extra_metadata_;
  base::FilePath forced_crash_directory_;
  base::FilePath lsb_release_;
  base::FilePath system_crash_path_;
  base::FilePath crash_reporter_state_path_;
  base::FilePath log_config_path_;
  size_t max_log_size_;
  std::unique_ptr<base::Clock> test_clock_;
  std::string test_kernel_name_;
  std::string test_kernel_version_;

  scoped_refptr<dbus::Bus> bus_;

  // D-Bus proxy for session manager interface.
  std::unique_ptr<org::chromium::SessionManagerInterfaceProxyInterface>
      session_manager_proxy_;

  // D-Bus proxy for debugd interface.
  std::unique_ptr<org::chromium::debugdProxyInterface> debugd_proxy_;

  // If kCrashLoopSendingMode, reports are stored in memory and sent over DBus
  // to debugd when finished. Otherwise, we store the crash reports on disk and
  // rely on crash_sender to later pick it up and send it.
  const CrashSendingMode crash_sending_mode_;

  // Hash a string to a number.  We define our own hash function to not
  // be dependent on a C++ library that might change.
  static unsigned HashString(base::StringPiece input);

  void EnqueueCollectionErrorLog(ErrorType error_type,
                                 const std::string& exec,
                                 const std::string& basename);

  // Logs a |message| detailing a crash, along with the |reason| for which the
  // collector handled or ignored it.
  void LogCrash(const std::string& message, const std::string& reason) const;

 private:
  static bool ParseProcessTicksFromStat(base::StringPiece stat,
                                        uint64_t* ticks);

  // Should reports always be stored in the user crash directory, or can they be
  // stored in the system directory if we are not running as "chronos"?
  const CrashDirectorySelectionMethod crash_directory_selection_method_;

  // True when FinishCrash has been called. Once true, no new files should be
  // created.
  bool is_finished_;

  // If crash_loop_mode_ is true, all files are collected in here instead of
  // being written to disk. The first element of the tuple is the base filename,
  // the second is a memfd_create file descriptor with the file contents.
  std::vector<std::tuple<std::string, brillo::dbus_utils::FileDescriptor>>
      in_memory_files_;

  // Number of bytes successfully written by all calls to WriteNewFile() and
  // WriteNewCompressedFile() so far. For WriteNewCompressedFile(), the count is
  // of bytes on disk, after compression.
  off_t bytes_written_;

  // Creates a new file and returns a file descriptor to it. Helper for
  // WriteNewFile() and WriteNewCompressedFile().
  base::ScopedFD GetNewFileHandle(const base::FilePath& filename);

  // Returns true if there is already a file in in_memory_files_ with
  // filename.BaseName().
  bool InMemoryFileExists(const base::FilePath& filename) const;

  // Returns an error type signature for a given |error_type| value,
  // which is reported to the crash server along with the
  // crash_reporter-user-collection signature.
  std::string GetErrorTypeSignature(ErrorType error_type) const;

  // Prepended to log messages to differentiate between collectors.
  const std::string tag_;

  std::unique_ptr<MetricsLibraryInterface> metrics_lib_;

  DISALLOW_COPY_AND_ASSIGN(CrashCollector);
};

#endif  // CRASH_REPORTER_CRASH_COLLECTOR_H_
