Adds support to the @verifyCC operator

This commit is contained in:
Felipe Zimmerle 2015-08-12 13:14:16 -03:00
parent 1b0a918330
commit 21400ba454
3 changed files with 77 additions and 15 deletions

View File

@ -15,27 +15,83 @@
#include "operators/verify_cc.h"
#include <pcrecpp.h>
#include <iostream>
#include "operators/operator.h"
namespace ModSecurity {
namespace operators {
bool VerifyCC::evaluate(Assay *assay) {
/**
* @todo Implement the operator VerifyCC.
* Reference: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#verifyCC
/**
* Luhn Mod-10 Method (ISO 2894/ANSI 4.13)
*/
int VerifyCC::luhnVerify(const char *ccnumber, int len) {
int sum[2] = { 0, 0 };
int odd = 0;
int digits = 0;
int i;
/* Weighted lookup table which is just a precalculated (i = index):
* i*2 + (( (i*2) > 9 ) ? -9 : 0)
*/
return true;
/* weight lookup table */
static const int wtable[10] = {0, 2, 4, 6, 8, 1, 3, 5, 7, 9};
/* Add up only digits (weighted digits via lookup table)
* for both odd and even CC numbers to avoid 2 passes.
*/
for (i = 0; i < len; i++) {
if (ccnumber[i] >= (0 + 48) && ccnumber[i] <= (9 + 48)) {
sum[0] += (!odd ? wtable[ccnumber[i] - '0'] : (ccnumber[i] - '0'));
sum[1] += (odd ? wtable[ccnumber[i] - '0'] : (ccnumber[i] - '0'));
odd = 1 - odd; /* alternate weights */
digits++;
}
}
/* No digits extracted */
if (digits == 0) {
return 0;
}
/* Do a mod 10 on the sum */
sum[odd] %= 10;
/* If the result is a zero the card is valid. */
return sum[odd] ? 0 : 1;
}
VerifyCC::VerifyCC(std::string op, std::string param, bool negation)
: Operator() {
this->op = op;
this->param = param;
bool VerifyCC::evaluate(Assay *assay, const std::string &i) {
int offset = 0;
bool is_cc = false;
int target_length = i.length();
const char *target = i.c_str();
for (offset = 0; offset < target_length; offset++) {
std::string shiftedString(i, offset, i.length() - offset);
std::string match;
pcrecpp::StringPiece input(shiftedString);
while (m_re.FindAndConsume(&input, &match)) {
is_cc = luhnVerify(match.c_str(), match.size());
if (is_cc) {
if (assay) {
assay->debug(9, "CC# match \"" + param +
"\" at " + i + ". [offset " +
std::to_string(offset) + "]");
}
return true;
}
}
}
return false;
}
} // namespace operators
} // namespace ModSecurity

View File

@ -16,25 +16,31 @@
#ifndef SRC_OPERATORS_VERIFY_CC_H_
#define SRC_OPERATORS_VERIFY_CC_H_
#include <pcrecpp.h>
#include <string>
#include "operators/operator.h"
#ifdef __cplusplus
namespace ModSecurity {
namespace operators {
class VerifyCC : public Operator {
public:
/** @ingroup ModSecurity_Operator */
VerifyCC(std::string o, std::string p, bool i);
bool evaluate(Assay *assay);
VerifyCC(std::string op, std::string param, bool negation)
: Operator(op, param, negation),
m_re(param, pcrecpp::RE_Options()) { }
int luhnVerify(const char *ccnumber, int len);
bool evaluate(Assay *assay, const std::string &input) override;
private:
pcrecpp::RE m_re;
};
} // namespace operators
} // namespace ModSecurity
#endif
#endif // SRC_OPERATORS_VERIFY_CC_H_

@ -1 +1 @@
Subproject commit 55534e6966ebf037db68025eb2b3a14f056cd278
Subproject commit 967a8a43d1e91b65a05655c0d0a5754bdfa0759a