| // Copyright 2018 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CHROME_BROWSER_SAFE_BROWSING_DOWNLOAD_PROTECTION_FILE_ANALYZER_H_ |
| #define CHROME_BROWSER_SAFE_BROWSING_DOWNLOAD_PROTECTION_FILE_ANALYZER_H_ |
| |
| #include "base/files/file_path.h" |
| #include "base/functional/callback.h" |
| #include "base/memory/scoped_refptr.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/time/time.h" |
| #include "base/types/optional_ref.h" |
| #include "build/build_config.h" |
| #include "chrome/common/safe_browsing/archive_analyzer_results.h" |
| #include "chrome/common/safe_browsing/binary_feature_extractor.h" |
| #include "components/safe_browsing/core/common/proto/csd.pb.h" |
| #include "third_party/protobuf/src/google/protobuf/repeated_field.h" |
| |
| #if !BUILDFLAG(IS_ANDROID) |
| #include "chrome/services/file_util/public/cpp/sandboxed_rar_analyzer.h" |
| #include "chrome/services/file_util/public/cpp/sandboxed_seven_zip_analyzer.h" |
| #include "chrome/services/file_util/public/cpp/sandboxed_zip_analyzer.h" |
| #endif |
| |
| #if BUILDFLAG(IS_MAC) |
| #include "chrome/common/safe_browsing/disk_image_type_sniffer_mac.h" |
| #include "chrome/services/file_util/public/cpp/sandboxed_dmg_analyzer_mac.h" |
| #endif |
| |
| namespace safe_browsing { |
| |
| // This class does the file content analysis for a user download, extracting the |
| // features that will be sent to the SB backend. This class lives on the UI |
| // thread, which is where the result callback will be invoked. |
| class FileAnalyzer { |
| public: |
| enum class ArchiveValid { UNSET, VALID, INVALID }; |
| |
| // This struct holds the possible features extracted from a file. |
| struct Results { |
| Results(); |
| Results(const Results& other); |
| ~Results(); |
| |
| // What type of inspection was performed to yield the results here. |
| DownloadFileType::InspectionType inspection_performed = |
| DownloadFileType::NONE; |
| |
| // When analyzing a ZIP or RAR, the type becomes clarified by content |
| // inspection (does it contain binaries/archives?). So we return a type. |
| ClientDownloadRequest::DownloadType type; |
| |
| // For archive files, whether the archive contains an executable. Has |
| // unspecified contents for non-archive files. |
| bool archived_executable = false; |
| |
| // For archive files, whether the archive contains an archive. Has |
| // unspecified contents for non-archive files. |
| bool archived_archive = false; |
| |
| // For archive files, the features extracted from each contained |
| // archive/binary. |
| google::protobuf::RepeatedPtrField<ClientDownloadRequest::ArchivedBinary> |
| archived_binaries; |
| |
| // For executables, information about the signature of the executable. |
| ClientDownloadRequest::SignatureInfo signature_info; |
| |
| // For executables, information about the file headers. |
| ClientDownloadRequest::ImageHeaders image_headers; |
| |
| #if BUILDFLAG(IS_MAC) |
| // For DMG files, the signature of the DMG. |
| std::vector<uint8_t> disk_image_signature; |
| |
| // For DMG files, any detached code signatures in the DMG. |
| google::protobuf::RepeatedPtrField< |
| ClientDownloadRequest::DetachedCodeSignature> |
| detached_code_signatures; |
| #endif |
| |
| // For archives, the features and metadata extracted from the file. |
| ClientDownloadRequest::ArchiveSummary archive_summary; |
| |
| // Information about the encryption on this file. |
| EncryptionInfo encryption_info; |
| }; |
| |
| explicit FileAnalyzer( |
| scoped_refptr<BinaryFeatureExtractor> binary_feature_extractor); |
| ~FileAnalyzer(); |
| void Start(const base::FilePath& target_file_name, |
| const base::FilePath& tmp_path, |
| base::optional_ref<const std::string> password, |
| base::OnceCallback<void(Results)> callback); |
| |
| private: |
| void StartExtractFileFeatures(); |
| void OnFileAnalysisFinished(FileAnalyzer::Results results); |
| |
| #if !BUILDFLAG(IS_ANDROID) |
| void StartExtractZipFeatures(); |
| void OnZipAnalysisFinished(const ArchiveAnalyzerResults& archive_results); |
| |
| void StartExtractRarFeatures(); |
| void OnRarAnalysisFinished(const ArchiveAnalyzerResults& archive_results); |
| #endif |
| |
| #if BUILDFLAG(IS_MAC) |
| void StartExtractDmgFeatures(); |
| void ExtractFileOrDmgFeatures(bool download_file_has_koly_signature); |
| void OnDmgAnalysisFinished( |
| const safe_browsing::ArchiveAnalyzerResults& archive_results); |
| #endif |
| |
| #if !BUILDFLAG(IS_ANDROID) |
| void StartExtractSevenZipFeatures(); |
| void OnSevenZipAnalysisFinished( |
| const ArchiveAnalyzerResults& archive_results); |
| #endif |
| |
| void LogAnalysisDurationWithAndWithoutSuffix(const std::string& suffix); |
| |
| // The ultimate destination/filename for the download. This is used to |
| // determine the filetype from the filename extension/suffix, and should be a |
| // human-readable filename (i.e. not a content-URI, on Android). |
| base::FilePath target_file_name_; |
| |
| // The current path to the file contents. |
| base::FilePath tmp_path_; |
| |
| std::optional<std::string> password_; |
| scoped_refptr<BinaryFeatureExtractor> binary_feature_extractor_; |
| base::OnceCallback<void(Results)> callback_; |
| base::Time start_time_; |
| Results results_; |
| |
| #if !BUILDFLAG(IS_ANDROID) |
| std::unique_ptr<SandboxedZipAnalyzer, base::OnTaskRunnerDeleter> |
| zip_analyzer_{nullptr, base::OnTaskRunnerDeleter(nullptr)}; |
| |
| std::unique_ptr<SandboxedRarAnalyzer, base::OnTaskRunnerDeleter> |
| rar_analyzer_{nullptr, base::OnTaskRunnerDeleter(nullptr)}; |
| #endif |
| |
| #if BUILDFLAG(IS_MAC) |
| std::unique_ptr<SandboxedDMGAnalyzer, base::OnTaskRunnerDeleter> |
| dmg_analyzer_{nullptr, base::OnTaskRunnerDeleter(nullptr)}; |
| #endif |
| |
| #if !BUILDFLAG(IS_ANDROID) |
| std::unique_ptr<SandboxedSevenZipAnalyzer, base::OnTaskRunnerDeleter> |
| seven_zip_analyzer_{nullptr, base::OnTaskRunnerDeleter(nullptr)}; |
| #endif |
| |
| base::WeakPtrFactory<FileAnalyzer> weakptr_factory_{this}; |
| }; |
| |
| } // namespace safe_browsing |
| |
| #endif // CHROME_BROWSER_SAFE_BROWSING_DOWNLOAD_PROTECTION_FILE_ANALYZER_H_ |