/* Copyright (C) 2021-2025 Cisco Systems, Inc. and/or its affiliates. All rights reserved. */

#ifndef __CLAMAV_RUST_H
#define __CLAMAV_RUST_H

/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */

#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include "clamav.h"
#include "matcher-ac.h"
#include "htmlnorm.h"
typedef struct cli_matcher cli_matcher; typedef struct cli_ctx_tag cli_ctx;

typedef enum IndicatorType {
  /**
   * For hash-based indicators.
   */
  IndicatorType_Strong,
  /**
   * For potentially unwanted applications/programs that are not malicious but may be used maliciously.
   */
  IndicatorType_PotentiallyUnwanted,
  /**
   * Weak indicators that together with other indicators can be used to form a stronger indicator.
   * This type of indicator should NEVER alert the user on its own.
   */
  IndicatorType_Weak,
} IndicatorType;

/**
 * A generic container for any error that implements `Into<std::error::Error>`
 */
typedef struct FFIError FFIError;

bool script2cdiff(const char *script, const char *builder, const char *server);

/**
 * C interface for cdiff_apply() (below).
 * This function is for use in sigtool.c and libfreshclam_internal.c
 *
 * # Safety
 *
 * No parameters may be NULL.
 */
bool cdiff_apply(const char *cdiff_file_path_str,
                 const void *verifier_ptr,
                 uint16_t mode,
                 struct FFIError **err);

/**
 * C interface for verify_signed_file() which verifies a file's external digital signature.
 * Handles all the unsafe ffi stuff.
 *
 * # Safety
 *
 * No parameters may be NULL.
 */
bool codesign_sign_file(const char *target_file_path_str,
                        const char *signature_file_path_str,
                        const char *signing_key_path_str,
                        const char *const *cert_paths_str,
                        uintptr_t cert_paths_len,
                        bool append,
                        struct FFIError **err);

/**
 * C interface for verify_signed_file() which verifies a file's external digital signature.
 * Handles all the unsafe ffi stuff.
 *
 * The signer_name output parameter is a pointer to a pointer to a C string.
 * The caller is responsible for freeing the CString. See `ffi_cstring_free`.
 *
 * # Safety
 *
 * No parameters may be NULL.
 */
bool codesign_verify_file(const char *signed_file_path_str,
                          const char *signature_file_path_str,
                          const void *verifier_ptr,
                          char **signer_name,
                          struct FFIError **err);

/**
 * C interface for creating a new Verifier.
 * Handles all the unsafe ffi stuff.
 * The verifier output parameter is a pointer to a pointer to a Verifier.
 *
 * # Safety
 *
 * No parameters may be NULL.
 */
bool codesign_verifier_new(const char *certs_directory_str, void **verifier, struct FFIError **err);

/**
 * C interface for freeing a Verifier.
 * Handles all the unsafe ffi stuff.
 *
 * # Safety
 *
 * No parameters may be NULL.
 */
void codesign_verifier_free(void *verifier);

/**
 * C interface to handle HTML style blocks.
 *
 * This function looks through the style block for images found in HTML style blocks.
 * It will extract each image and scan it.
 *
 * # Safety
 *
 * `file_bytes` must not be NULL
 */
cl_error_t html_style_block_handler(cli_ctx *ctx, const char *file_bytes);

/**
 * C interface for checking a CVD. This includes parsing the header, and (optionally) verifying the digital signature.
 * Handles all the unsafe ffi stuff.
 *
 * # Safety
 *
 * No parameters may be NULL
 */
bool cvd_check(const char *cvd_file_path_str,
               const char *certs_directory_str,
               bool skip_sign_verify,
               bool disable_legacy_dsig,
               char **signer_name,
               struct FFIError **err);

/**
 * C interface for unpacking a CVD. This includes parsing the header, verifying the digital signature, and unpacking the archive.
 * Handles all the unsafe ffi stuff.
 *
 * # Safety
 *
 * No parameters may be NULL
 * The CVD pointer must be valid
 * The destination path must be a valid path
 */
bool cvd_unpack(void *cvd,
                const char *destination_path_str,
                struct FFIError **err);

/**
 * C interface for opening a CVD file. This includes parsing the header.
 * Handles all the unsafe ffi stuff.
 * Returns a pointer to the CVD struct.
 *
 * # Safety
 *
 * No parameters may be NULL
 * The returned pointer must be freed with `cli_cvd_free`
 */
void *cvd_open(const char *cvd_file_path_str, struct FFIError **err);

/**
 * C interface for verifying a CVD. This includes verifying the digital signature.
 * Handles all the unsafe ffi stuff.
 *
 * If `certs_directory_str` is NULL, then only the MD5-based RSA digital signature will be verified.
 *
 * # Safety
 *
 * No parameters may be NULL except for `certs_directory_str`.
 * The CVD pointer must be valid
 */
bool cvd_verify(const void *cvd,
                const void *verifier_ptr,
                bool disable_legacy_dsig,
                char **signer_name,
                struct FFIError **err);

/**
 * C interface for freeing a CVD struct.
 * Handles all the unsafe ffi stuff.
 * Frees the CVD struct.
 *
 * # Safety
 *
 * The CVD pointer must be valid
 * The CVD pointer must not be used after calling this function
 */
void cvd_free(void *cvd);

/**
 * C interface for getting the creation time of a CVD.
 * Handles all the unsafe ffi stuff.
 * Returns the creation time as a u64.
 *
 * # Safety
 *
 * No parameters may be NULL
 * The CVD pointer must be valid
 */
uint64_t cvd_get_time_creation(const void *cvd);

/**
 * C interface for getting the version of a CVD.
 * Handles all the unsafe ffi stuff.
 * Returns the version as a u32.
 *
 * # Safety
 *
 * No parameters may be NULL
 * The CVD pointer must be valid
 */
uint32_t cvd_get_version(const void *cvd);

/**
 * C interface for getting the name of a CVD.
 * Handles all the unsafe ffi stuff.
 * Returns the version as a C string (aka char *).
 *
 * # Safety
 *
 * No parameters may be NULL
 * The CVD pointer must be valid
 * The caller is responsible for freeing the C string. See `ffi_cstring_free`.
 */
char *cvd_get_name(const void *cvd);

/**
 * C interface for getting the number of signatures in a CVD.
 * Handles all the unsafe ffi stuff.
 * Returns the number of signatures as a u32.
 *
 * # Safety
 *
 * No parameters may be NULL
 * The CVD pointer must be valid
 */
uint32_t cvd_get_num_sigs(const void *cvd);

/**
 * C interface for getting the minimum feature level of a CVD.
 * Handles all the unsafe ffi stuff.
 * Returns the minimum feature level as a u32.
 *
 * # Safety
 *
 * No parameters may be NULL
 * The CVD pointer must be valid
 */
uint32_t cvd_get_min_flevel(const void *cvd);

/**
 * C interface for getting the CVD builder.
 * Handles all the unsafe ffi stuff.
 * Returns the builder as a CString.
 * The caller is responsible for freeing the CString. See `ffi_cstring_free`.
 *
 * # Safety
 *
 * No parameters may be NULL
 * The CVD pointer must be valid
 */
char *cvd_get_builder(const void *cvd);

/**
 * C interface for getting the file handle of a CVD.
 * Handles all the unsafe ffi stuff.
 * Returns the file handle an integer.
 * The caller must not close the file handle.
 * The file handle is not guaranteed to be valid after the CVD struct is freed.
 *
 * # Safety
 *
 * No parameters may be NULL
 * The CVD pointer must be valid
 */
int32_t cvd_get_file_descriptor(const void *cvd);

/**
 * C interface for getting the file handle of a CVD.
 * Handles all the unsafe ffi stuff.
 * Returns the file handle an integer.
 * The caller must not close the file handle.
 * The file handle is not guaranteed to be valid after the CVD struct is freed.
 *
 * # Safety
 *
 * No parameters may be NULL
 * The CVD pointer must be valid
 */
void *cvd_get_file_handle(const void *cvd);

/**
 * Initialize a match vector
 */
evidence_t evidence_new(void);

/**
 * C interface for Evidence::from_child().
 * Handles all the unsafe ffi stuff.
 *
 * Create a new Evidence instance for a parent layer, given Evidence from a child layer.
 *
 * # Safety
 * /// No parameters may be NULL
 */
bool evidence_new_from_child(evidence_t child,
                             evidence_t *evidence_out,
                             bool from_normalized,
                             struct FFIError **err);

/**
 * C interface for Evidence::add_child_evidence().
 * Handles all the unsafe ffi stuff.
 *
 * Add evidence from a child layer to this evidence instance.
 *
 * # Safety
 *
 * No parameters may be NULL
 */
bool evidence_add_child_evidence(evidence_t evidence,
                                 evidence_t child,
                                 bool from_normalized,
                                 struct FFIError **err);

/**
 * Free the evidence
 */
void evidence_free(evidence_t evidence);

/**
 * C interface for Evidence::render_verdict().
 * Handles all the unsafe ffi stuff.
 *
 * Render a verdict based on the evidence, depending on the severity of the
 * indicators found and the scan configuration.
 *
 * The individual alerting-indicators would have already been printed at this point.
 *
 * # Safety
 *
 * No parameters may be NULL
 */
bool evidence_render_verdict(evidence_t evidence);

/**
 * C interface to get a string name for one of the alerts.
 * Will first check for one from the strong indicators, then pua.
 *
 * # Safety
 *
 * Returns a string that is either static, or allocated when reading the database.
 * So the lifetime of the string is good at least until you reload or unload the databases.
 *
 * No parameters may be NULL
 */
const char *evidence_get_last_alert(evidence_t evidence);

/**
 * C interface to get a string name for an indicator by indicator_type and index.
 * You would use evidence_num_indicators_type() first to check how many indicators
 * there are for any given type, and then use this function to get the name of each indicator.
 *
 * # Safety
 *
 * Returns a string that is either static, or allocated when reading the database.
 * So the lifetime of the string is good at least until you reload or unload the databases.
 * The out_depth and out_object_id parameters are optional, and will be size_t pointers for depth and object_id.
 *
 * No parameters may be NULL
 */
const char *evidence_get_indicator(evidence_t evidence,
                                   enum IndicatorType indicator_type,
                                   uintptr_t index,
                                   uintptr_t *out_depth,
                                   uintptr_t *out_object_id);

/**
 * C interface to check number of alerting indicators in evidence.
 *
 * # Safety
 *
 * No parameters may be NULL
 */
uintptr_t evidence_num_alerts(evidence_t evidence);

/**
 * C interface to check number of indicators in evidence.
 * Handles all the unsafe ffi stuff.
 *
 * # Safety
 *
 * No parameters may be NULL
 */
uintptr_t evidence_num_indicators_type(evidence_t evidence, enum IndicatorType indicator_type);

/**
 * C interface for Evidence::add_indicator().
 * Handles all the unsafe ffi stuff.
 *
 * Add an indicator to the evidence.
 *
 * # Safety
 *
 * `hexsig` and `err` must not be NULL
 */
bool evidence_add_indicator(evidence_t evidence,
                            const char *name,
                            enum IndicatorType indicator_type,
                            uintptr_t object_id,
                            struct FFIError **err);

/**
 * C interface for Evidence::remove_indicator().
 * Handles all the unsafe ffi stuff.
 *
 * Remove an indicator from the evidence.
 *
 * # Safety
 *
 * `hexsig` and `err` must not be NULL
 */
bool evidence_remove_indicator(evidence_t evidence,
                               const char *name,
                               enum IndicatorType indicator_type,
                               struct FFIError **err);

/**
 * Compute (and cache) a formatted error string from the provided [`FFIError`] pointer.
 *
 * # Safety
 *
 * `err` must not be NULL
 */
const char *ffierror_fmt(struct FFIError *err);

/**
 * Free a [`FFIError`] structure
 *
 * # Safety
 *
 * `err` must not be NULL
 */
void ffierror_free(struct FFIError *err);

/**
 * C interface to free a CString.
 * Handles all the unsafe ffi stuff.
 * Frees the CString.
 *
 * # Safety
 *
 * The CString pointer must be valid
 * The CString pointer must not be used after calling this function
 */
void ffi_cstring_free(char *cstring);

/**
 * Initialize the hashmap
 */
fuzzyhashmap_t fuzzy_hashmap_new(void);

/**
 * Free the hashmap
 */
void fuzzy_hash_free_hashmap(fuzzyhashmap_t fuzzy_hashmap);

/**
 * C interface for FuzzyHashMap::check().
 * Handles all the unsafe ffi stuff.
 *
 * # Safety
 *
 * No parameters may be NULL
 */
bool fuzzy_hash_check(fuzzyhashmap_t fuzzy_hashmap,
                      cli_ac_data *mdata,
                      image_fuzzy_hash_t image_fuzzy_hash);

/**
 * C interface for FuzzyHashMap::load_subsignature().
 * Handles all the unsafe ffi stuff.
 *
 * # Safety
 *
 * `hexsig` and `err` must not be NULL
 */
bool fuzzy_hash_load_subsignature(fuzzyhashmap_t fuzzy_hashmap,
                                  const char *hexsig,
                                  uint32_t lsig_id,
                                  uint32_t subsig_id,
                                  struct FFIError **err);

/**
 * C interface for fuzzy_hash_calculate_image().
 * Handles all the unsafe ffi stuff.
 *
 * # Safety
 *
 * `file_bytes` and `hash_out` must not be NULL
 */
bool fuzzy_hash_calculate_image(const uint8_t *file_bytes,
                                uintptr_t file_size,
                                uint8_t *hash_out,
                                uintptr_t hash_out_len,
                                struct FFIError **err);

bool clrs_log_init(void);

/**
 * API exported for C code to log to standard error using Rust.
 * This would be an alternative to fputs, and reliably prints
 * non-ASCII UTF8 characters on Windows, where fputs does not.
 *
 * # Safety
 *
 * This function dereferences the c_buff raw pointer. Pointer must be valid.
 */
void clrs_eprint(const char *c_buf);

/**
 * Scan a OneNote file for attachments
 *
 * # Safety
 *
 * Must be a valid ctx pointer.
 */
cl_error_t scan_onenote(cli_ctx *ctx);

/**
 * Scan the contents of a LHA or LZH archive
 *
 * # Safety
 *
 * Must be a valid ctx pointer.
 */
cl_error_t scan_lha_lzh(cli_ctx *ctx);

/**
 * Scan an Alz file for attachments
 *
 * # Safety
 *
 * Must be a valid ctx pointer.
 */
cl_error_t cli_scanalz(cli_ctx *ctx);

extern cl_error_t cli_checktimelimit(cli_ctx *ctx);

/**
 * C interface to delete files using a glob pattern.
 *
 * # Safety
 *
 * No parameters may be NULL.
 */
bool glob_rm(const char *glob_str, struct FFIError **err);

/**
 * C interface to create a directory
 *
 * # Safety
 *
 * No parameters may be NULL.
 */
bool mkdir_w32(const char *path, struct FFIError **err);

#endif /* __CLAMAV_RUST_H */
