From 25175dd80020a3c2836e3709fd1ce2e38fc3beee Mon Sep 17 00:00:00 2001 From: Felipe Zimmerle Date: Wed, 28 Jun 2017 00:44:42 -0300 Subject: [PATCH] Adds support to verify CPF operator --- src/operators/verify_cpf.cc | 131 ++++++++++++++++++++++++++++++++++-- src/operators/verify_cpf.h | 43 ++++++++++-- 2 files changed, 162 insertions(+), 12 deletions(-) diff --git a/src/operators/verify_cpf.cc b/src/operators/verify_cpf.cc index 4e7a0c5a..229cac88 100644 --- a/src/operators/verify_cpf.cc +++ b/src/operators/verify_cpf.cc @@ -22,13 +22,132 @@ namespace modsecurity { namespace operators { +int VerifyCPF::convert_to_int(const char c) +{ + int n; + if ((c>='0') && (c<='9')) + n = c - '0'; + else if ((c>='A') && (c<='F')) + n = c - 'A' + 10; + else if ((c>='a') && (c<='f')) + n = c - 'a' + 10; + else + n = 0; + return n; +} -bool VerifyCPF::evaluate(Transaction *transaction, const std::string &str) { - /** - * @todo Implement the operator VerifyCPF. - * Reference: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#verifyCPF - */ - return true; +bool VerifyCPF::verify(const char *cpfnumber, int len) { + int factor, part_1, part_2, var_len = len; + unsigned int sum = 0, i = 0, cpf_len = 11, c; + int cpf[11]; + char s_cpf[11]; + char bad_cpf[12][12] = { "00000000000", + "01234567890", + "11111111111", + "22222222222", + "33333333333", + "44444444444", + "55555555555", + "66666666666", + "77777777777", + "88888888888", + "99999999999"}; + + while ((*cpfnumber != '\0') && ( var_len > 0)) + { + if (*cpfnumber != '-' || *cpfnumber != '.') + { + if (i < cpf_len && isdigit(*cpfnumber)) + { + s_cpf[i] = *cpfnumber; + cpf[i] = convert_to_int(*cpfnumber); + i++; + } + } + cpfnumber++; + var_len--; + } + + + if (i != cpf_len) + { + return 0; + } + else + { + for (i = 0; i< cpf_len; i++) + { + if (strncmp(s_cpf,bad_cpf[i],cpf_len) == 0) + { + return 0; + } + } + } + + part_1 = convert_to_int(s_cpf[cpf_len-2]); + part_2 = convert_to_int(s_cpf[cpf_len-1]); + + c = cpf_len; + + for (i = 0; i < 9; i++) { + sum += (cpf[i] * --c); + } + + factor = (sum % cpf_len); + + if(factor < 2) { + cpf[9] = 0; + } else { + cpf[9] = cpf_len-factor; + } + + sum = 0; + c = cpf_len; + + for (i = 0;i < 10; i++) + sum += (cpf[i] * c--); + + factor = (sum % cpf_len); + + if (factor < 2) { + cpf[10] = 0; + } else { + cpf[10] = cpf_len-factor; + } + + if (part_1 == cpf[9] && part_2 == cpf[10]) + { + return true; + } + + return false; +} + + +bool VerifyCPF::evaluate(Transaction *transaction, Rule *rule, + const std::string& input, std::shared_ptr ruleMessage) { + std::list matches; + bool is_cpf = false; + int i; + + if (m_param.empty()) { + return false; + } + + for (i = 0; i < input.size() - 1 && is_cpf == false; i++) { + matches = m_re->searchAll(input.substr(i, input.size())); + + for (const auto & i : matches) { + is_cpf = verify(i.match.c_str(), i.match.size()); + logOffset(ruleMessage, i.m_offset, i.m_length); + if (is_cpf) { + goto out; + } + } + } + +out: + return is_cpf; } diff --git a/src/operators/verify_cpf.h b/src/operators/verify_cpf.h index 90cf8a45..ae425aab 100644 --- a/src/operators/verify_cpf.h +++ b/src/operators/verify_cpf.h @@ -19,25 +19,56 @@ #include #include "src/operators/operator.h" +#include "src/utils/regex.h" + namespace modsecurity { -namespace operators { +using Utils::SMatch; +using Utils::regex_search; +using Utils::Regex; +namespace operators { class VerifyCPF : public Operator { public: /** @ingroup ModSecurity_Operator */ VerifyCPF(std::string o, std::string p, bool n) - : Operator(o, p, n) { } + : Operator(o, p, n) { + m_re = new Regex(p); + } + VerifyCPF(std::string name, std::string param) + : Operator(name, param) { + m_re = new Regex(param); + } explicit VerifyCPF(std::string param) - : Operator("VerifyCPF", param) { } - bool evaluate(Transaction *transaction, const std::string &str) override; -}; + : Operator("VerifyCPF", param) { + m_re = new Regex(param); + } + ~VerifyCPF() { + delete m_re; + } + bool evaluate(Transaction *transaction, Rule *rule, + const std::string &input) override { + return evaluate(transaction, NULL, input, NULL); + } + bool evaluate(Transaction *transaction, + const std::string &input) override { + return evaluate(transaction, NULL, input); + } + bool evaluate(Transaction *transaction, Rule *rule, + const std::string& input, + std::shared_ptr ruleMessage) override; + + int convert_to_int(const char c); + bool verify(const char *ssnumber, int len); + + private: + Regex *m_re; +}; } // namespace operators } // namespace modsecurity - #endif // SRC_OPERATORS_VERIFY_CPF_H_