diff --git a/headers/modsecurity/transaction.h b/headers/modsecurity/transaction.h index 3e70caa38e..bc506ad773 100644 --- a/headers/modsecurity/transaction.h +++ b/headers/modsecurity/transaction.h @@ -35,6 +35,7 @@ #include #include +#include #ifndef __cplusplus typedef struct ModSecurity_t ModSecurity; @@ -739,6 +740,13 @@ int msc_update_status_code(Transaction *transaction, int status); /** @ingroup ModSecurity_C_API */ int msc_set_request_hostname(Transaction *transaction, const unsigned char *hostname); +/** @ingroup ModSecurity_C_API */ +size_t msc_get_rules_messages_size(const Transaction *transaction); + +/** @ingroup ModSecurity_C_API */ +size_t msc_get_rules_messages_rule_ids(const Transaction *transaction, + int64_t *ids, size_t ids_len); + #ifdef __cplusplus } } // namespace modsecurity diff --git a/src/transaction.cc b/src/transaction.cc index 408f9b3d40..df32d58667 100644 --- a/src/transaction.cc +++ b/src/transaction.cc @@ -2325,5 +2325,60 @@ extern "C" int msc_set_request_hostname(Transaction *transaction, } +/** + * @name msc_get_rules_messages_size + * @brief Retrieve the number of RuleMessage records on a transaction. + * + * Returns the size of Transaction::m_rulesMessages: the number of + * RuleMessage records that were selected to be logged on the + * transaction. This is not necessarily the total number of rules that + * matched! + * + * @param transaction ModSecurity transaction. + * + * @returns The number of RuleMessage records on the transaction. + * + */ +extern "C" size_t msc_get_rules_messages_size(const Transaction *transaction) { + return transaction->m_rulesMessages.size(); +} + + +/** + * @name msc_get_rules_messages_rule_ids + * @brief Copy the rule ids from Transaction::m_rulesMessages into a buffer. + * + * Copies the rule id of each RuleMessage into the caller-provided buffer. + * Only rule messages that were selected to be logged are included. + * + * The caller is expected to size the buffer using + * msc_get_rules_messages_size. If @p ids_len is smaller than the number + * of available records, only the first @p ids_len ids are written and + * the remaining records are skipped. + * + * @param transaction ModSecurity transaction. + * @param ids Caller-provided buffer to receive the rule ids. + * May be NULL only if @p ids_len is 0. + * @param ids_len Capacity of @p ids, in number of int64_t slots. + * + * @returns The number of rule ids written into @p ids. + * + */ +extern "C" size_t msc_get_rules_messages_rule_ids(const Transaction *transaction, + int64_t *ids, size_t ids_len) { + if (ids == nullptr || ids_len == 0) { + return 0; + } + size_t written = 0; + for (const auto &msg : transaction->m_rulesMessages) { + if (written >= ids_len) { + break; + } + ids[written++] = msg.m_rule.m_ruleId; + } + return written; +} + + } // namespace modsecurity