|
15 | 15 |
|
16 | 16 | #include "src/operators/verify_cc.h" |
17 | 17 |
|
18 | | -#include <pcre.h> |
19 | 18 | #include <iostream> |
20 | 19 | #include <cstring> |
21 | 20 | #include <vector> |
22 | 21 |
|
23 | 22 | #include "src/operators/operator.h" |
24 | 23 |
|
25 | | -#if PCRE_HAVE_JIT |
26 | | -#define pcre_study_opt PCRE_STUDY_JIT_COMPILE |
27 | | -#else |
28 | | -#define pcre_study_opt 0 |
29 | | -#endif |
30 | | - |
31 | | - |
32 | 24 | namespace modsecurity { |
33 | 25 | namespace operators { |
34 | 26 |
|
35 | | -VerifyCC::~VerifyCC() { |
36 | | - if (m_pc != NULL) { |
37 | | - pcre_free(m_pc); |
38 | | - m_pc = NULL; |
39 | | - } |
40 | | - if (m_pce != NULL) { |
41 | | -#if PCRE_HAVE_JIT |
42 | | - pcre_free_study(m_pce); |
43 | | -#else |
44 | | - pcre_free(m_pce); |
45 | | -#endif |
46 | | - m_pce = NULL; |
47 | | - } |
48 | | -} |
49 | | - |
50 | 27 | /** |
51 | 28 | * Luhn Mod-10 Method (ISO 2894/ANSI 4.13) |
52 | 29 | */ |
@@ -90,70 +67,36 @@ int VerifyCC::luhnVerify(const char *ccnumber, int len) { |
90 | 67 |
|
91 | 68 |
|
92 | 69 | bool VerifyCC::init(const std::string ¶m2, std::string *error) { |
93 | | - const char *errptr = NULL; |
94 | | - int erroffset = 0; |
95 | | - |
96 | | - m_pc = pcre_compile(m_param.c_str(), PCRE_DOTALL|PCRE_MULTILINE, |
97 | | - &errptr, &erroffset, NULL); |
98 | | - if (m_pc == NULL) { |
99 | | - error->assign(errptr); |
100 | | - return false; |
101 | | - } |
| 70 | + m_re.reset(new modsecurity::regex::Regex(m_param)); |
102 | 71 |
|
103 | | - m_pce = pcre_study(m_pc, pcre_study_opt, &errptr); |
104 | | - if (m_pce == NULL) { |
105 | | - if (errptr == NULL) { |
106 | | - /* |
107 | | - * Per pcre_study(3) m_pce == NULL && errptr == NULL means |
108 | | - * that no addional information is found, so no need to study |
109 | | - */ |
110 | | - return true; |
111 | | - } |
112 | | - error->assign(errptr); |
| 72 | + if (!m_re->ok()) { |
| 73 | + *error = "Failed to compile regular expression " + m_re->getPattern(); |
113 | 74 | return false; |
114 | 75 | } |
115 | | - |
116 | 76 | return true; |
117 | 77 | } |
118 | 78 |
|
119 | 79 |
|
120 | 80 | bool VerifyCC::evaluate(Transaction *t, Rule *rule, |
121 | 81 | const std::string& i, std::shared_ptr<RuleMessage> ruleMessage) { |
122 | | - int offset = 0; |
123 | | - bool is_cc = false; |
124 | | - int target_length = i.length(); |
125 | | - |
126 | | - for (offset = 0; offset < target_length; offset++) { |
127 | | - std::string match; |
128 | | - int ovector[33]; |
129 | | - memset(ovector, 0, sizeof(ovector)); |
130 | | - int ret = pcre_exec(m_pc, m_pce, i.c_str(), i.size(), offset, |
131 | | - 0, ovector, 33) > 0; |
132 | | - |
133 | | - /* If there was no match, then we are done. */ |
134 | | - if (ret == PCRE_ERROR_NOMATCH) { |
135 | | - break; |
136 | | - } |
137 | | - if (ret < 0) { |
138 | | - return false; |
139 | | - } |
140 | | - if (ret > 0) { |
141 | | - match = std::string(i, ovector[0], ovector[1] - ovector[0]); |
142 | | - is_cc = luhnVerify(match.c_str(), match.size()); |
143 | | - if (is_cc) { |
144 | | - if (t) { |
145 | | - if (rule && t && rule->m_containsCaptureAction) { |
146 | | - t->m_collections.m_tx_collection->storeOrUpdateFirst( |
147 | | - "0", std::string(match)); |
148 | | - ms_dbg_a(t, 7, "Added VerifyCC match TX.0: " + \ |
149 | | - std::string(match)); |
150 | | - } |
151 | | - ms_dbg_a(t, 9, "CC# match \"" + m_param + |
152 | | - "\" at " + i + ". [offset " + |
153 | | - std::to_string(offset) + "]"); |
| 82 | + |
| 83 | + // ModSecurity v2 chacked for overlapping matches here, |
| 84 | + // so do we here |
| 85 | + for (const auto &m : m_re->searchAll(i, /* overlapping */ true)) { |
| 86 | + const auto &s = m.group(0).string; |
| 87 | + bool is_cc = luhnVerify(s.data(), s.size()); |
| 88 | + if (is_cc) { |
| 89 | + if (t) { |
| 90 | + if (rule && t && rule->m_containsCaptureAction) { |
| 91 | + t->m_collections.m_tx_collection->storeOrUpdateFirst( |
| 92 | + "0", s); |
| 93 | + ms_dbg_a(t, 7, "Added VerifyCC match TX.0: " + s); |
154 | 94 | } |
155 | | - return true; |
| 95 | + ms_dbg_a(t, 9, "CC# match \"" + m_param + |
| 96 | + "\" at " + i + ". [offset " + |
| 97 | + std::to_string(m.group(0).offset) + "]"); |
156 | 98 | } |
| 99 | + return true; |
157 | 100 | } |
158 | 101 | } |
159 | 102 |
|
|
0 commit comments