mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-15 23:55:03 +03:00
Refactoring: Place m_variables inside Collections
This commit is contained in:
parent
787be98122
commit
b6ae0585cd
@ -41,6 +41,7 @@ typedef struct Rules_t Rules;
|
|||||||
#include "modsecurity/intervention.h"
|
#include "modsecurity/intervention.h"
|
||||||
#include "modsecurity/transaction/variable.h"
|
#include "modsecurity/transaction/variable.h"
|
||||||
#include "modsecurity/transaction/variables.h"
|
#include "modsecurity/transaction/variables.h"
|
||||||
|
#include "modsecurity/transaction/collections.h"
|
||||||
|
|
||||||
#define LOGFY_ADD(a, b) \
|
#define LOGFY_ADD(a, b) \
|
||||||
yajl_gen_string(g, reinterpret_cast<const unsigned char*>(a), strlen(a)); \
|
yajl_gen_string(g, reinterpret_cast<const unsigned char*>(a), strlen(a)); \
|
||||||
@ -68,6 +69,7 @@ namespace ModSecurity {
|
|||||||
class ModSecurity;
|
class ModSecurity;
|
||||||
class Assay;
|
class Assay;
|
||||||
class Rules;
|
class Rules;
|
||||||
|
class Collections;
|
||||||
namespace actions {
|
namespace actions {
|
||||||
class Action;
|
class Action;
|
||||||
}
|
}
|
||||||
@ -140,15 +142,10 @@ class Assay {
|
|||||||
|
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
|
||||||
void setCollection(const std::string& collectionName,
|
|
||||||
const std::string& variableName,
|
|
||||||
const std::string& targetValue);
|
|
||||||
|
|
||||||
const char *getResponseBody();
|
const char *getResponseBody();
|
||||||
int getResponseBodyLenth();
|
int getResponseBodyLenth();
|
||||||
|
|
||||||
transaction::Variables m_variables;
|
transaction::Collections m_collections;
|
||||||
std::unordered_map<std::string, transaction::Variables *> collections;
|
|
||||||
#ifndef NO_LOGS
|
#ifndef NO_LOGS
|
||||||
void debug(int, std::string);
|
void debug(int, std::string);
|
||||||
#endif
|
#endif
|
||||||
|
83
headers/modsecurity/transaction/collections.h
Normal file
83
headers/modsecurity/transaction/collections.h
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* ModSecurity, http://www.modsecurity.org/
|
||||||
|
* Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||||
|
*
|
||||||
|
* You may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* If any of the files related to licensing are missing or if you have any
|
||||||
|
* other questions related to licensing please contact Trustwave Holdings, Inc.
|
||||||
|
* directly using the email address security@modsecurity.org.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#include <ctime>
|
||||||
|
#include <iostream>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <fstream>
|
||||||
|
#include <vector>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <set>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <string>
|
||||||
|
#include <list>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "modsecurity/transaction/variables.h"
|
||||||
|
#include "modsecurity/transaction/variable.h"
|
||||||
|
|
||||||
|
#ifndef HEADERS_MODSECURITY_TRANSACTION_COLLECTIONS_H_
|
||||||
|
#define HEADERS_MODSECURITY_TRANSACTION_COLLECTIONS_H_
|
||||||
|
|
||||||
|
#ifndef __cplusplus
|
||||||
|
typedef struct Variable_t Variable;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
namespace ModSecurity {
|
||||||
|
namespace transaction {
|
||||||
|
|
||||||
|
class Collections :
|
||||||
|
public std::unordered_map<std::string, transaction::Variables *> {
|
||||||
|
public:
|
||||||
|
Collections();
|
||||||
|
~Collections();
|
||||||
|
|
||||||
|
void store(std::string key, std::string value);
|
||||||
|
void storeOrUpdateFirst(const std::string& collectionName,
|
||||||
|
const std::string& variableName,
|
||||||
|
const std::string& targetValue);
|
||||||
|
bool storeOrUpdateFirst(const std::string &key, const std::string &value);
|
||||||
|
bool updateFirst(const std::string &key, const std::string &value);
|
||||||
|
void del(const std::string& key);
|
||||||
|
std::string* resolveFirst(const std::string& var);
|
||||||
|
std::string* resolveFirst(const std::string& collectionName,
|
||||||
|
const std::string& var);
|
||||||
|
|
||||||
|
void resolve(const std::string& var,
|
||||||
|
std::list<transaction::Variable *> *l);
|
||||||
|
std::list<transaction::Variable *> *resolve(const std::string& var);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a special collection to host the transaction variables.
|
||||||
|
*
|
||||||
|
* It exists independent of initialization and it is only valid during a transaction.
|
||||||
|
*
|
||||||
|
* Notice that it is not the TX collection.
|
||||||
|
*/
|
||||||
|
transaction::Variables m_transient;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace transaction
|
||||||
|
} // namespace ModSecurity
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif // HEADERS_MODSECURITY_TRANSACTION_COLLECTIONS_H_
|
||||||
|
|
||||||
|
|
@ -38,8 +38,6 @@ namespace transaction {
|
|||||||
class Variables :
|
class Variables :
|
||||||
public std::unordered_multimap<std::string, std::string> {
|
public std::unordered_multimap<std::string, std::string> {
|
||||||
public:
|
public:
|
||||||
std::unordered_map<std::string, transaction::Variables *> *m_collections;
|
|
||||||
|
|
||||||
Variables();
|
Variables();
|
||||||
void store(std::string key, std::string value);
|
void store(std::string key, std::string value);
|
||||||
|
|
||||||
@ -50,27 +48,14 @@ class Variables :
|
|||||||
|
|
||||||
void del(const std::string& key);
|
void del(const std::string& key);
|
||||||
|
|
||||||
std::list<Variable *>
|
|
||||||
resolveInt(const std::string& key,
|
|
||||||
std::list<Variable *> *l);
|
|
||||||
|
|
||||||
std::list<Variable *>
|
|
||||||
resolveInt(const std::string& key);
|
|
||||||
|
|
||||||
|
|
||||||
std::string* resolveFirst(const std::string& var);
|
std::string* resolveFirst(const std::string& var);
|
||||||
|
|
||||||
|
|
||||||
std::string* resolveFirst(const std::string& collectionName,
|
std::string* resolveFirst(const std::string& collectionName,
|
||||||
const std::string& var);
|
const std::string& var);
|
||||||
|
|
||||||
void setCollections(std::unordered_map<std::string,
|
std::list<transaction::Variable *> resolve(const std::string& key);
|
||||||
transaction::Variables *> *c);
|
|
||||||
|
|
||||||
std::list<transaction::Variable *> *
|
std::list<Variable *> resolve(const std::string& var,
|
||||||
resolve(const std::string& var);
|
|
||||||
|
|
||||||
void resolve(const std::string& var,
|
|
||||||
std::list<transaction::Variable *> *l);
|
std::list<transaction::Variable *> *l);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -172,6 +172,7 @@ libmodsecurity_la_SOURCES = \
|
|||||||
modsecurity.cc \
|
modsecurity.cc \
|
||||||
rules.cc \
|
rules.cc \
|
||||||
utils.cc \
|
utils.cc \
|
||||||
|
collections.cc \
|
||||||
variables.cc \
|
variables.cc \
|
||||||
debug_log.cc \
|
debug_log.cc \
|
||||||
debug_log_writer.cc \
|
debug_log_writer.cc \
|
||||||
|
@ -61,7 +61,8 @@ bool Capture::evaluate(Rule *rule, Assay *assay) {
|
|||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (match->empty() == false) {
|
while (match->empty() == false) {
|
||||||
assay->setCollection("TX", std::to_string(i), match->back());
|
assay->m_collections.storeOrUpdateFirst("TX",
|
||||||
|
std::to_string(i), match->back());
|
||||||
match->pop_back();
|
match->pop_back();
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@ bool SetVar::evaluate(Rule *rule, Assay *assay) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
std::string *resolvedValue =
|
std::string *resolvedValue =
|
||||||
assay->m_variables.resolveFirst(collectionName,
|
assay->m_collections.resolveFirst(collectionName,
|
||||||
variableNameExpanded);
|
variableNameExpanded);
|
||||||
if (resolvedValue == NULL) {
|
if (resolvedValue == NULL) {
|
||||||
value = 0;
|
value = 0;
|
||||||
@ -146,7 +146,8 @@ bool SetVar::evaluate(Rule *rule, Assay *assay) {
|
|||||||
assay->debug(8, "Saving variable: " + collectionName + ":" + \
|
assay->debug(8, "Saving variable: " + collectionName + ":" + \
|
||||||
variableNameExpanded + " with value: " + targetValue);
|
variableNameExpanded + " with value: " + targetValue);
|
||||||
#endif
|
#endif
|
||||||
assay->setCollection(collectionName, variableNameExpanded, targetValue);
|
assay->m_collections.storeOrUpdateFirst(collectionName,
|
||||||
|
variableNameExpanded, targetValue);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
175
src/assay.cc
175
src/assay.cc
@ -111,23 +111,21 @@ Assay::Assay(ModSecurity *ms, Rules *rules, void *logCbData)
|
|||||||
std::to_string(generate_assay_unique_id());
|
std::to_string(generate_assay_unique_id());
|
||||||
m_rules->incrementReferenceCount();
|
m_rules->incrementReferenceCount();
|
||||||
|
|
||||||
m_variables.store("ARGS_COMBINED_SIZE", std::string("0"));
|
m_collections.store("ARGS_COMBINED_SIZE", std::string("0"));
|
||||||
m_ARGScombinedSizeStr = m_variables.resolveFirst("ARGS_COMBINED_SIZE");
|
m_ARGScombinedSizeStr = m_collections.resolveFirst("ARGS_COMBINED_SIZE");
|
||||||
m_variables.store("ARGS_NAMES", std::string(""));
|
m_collections.store("ARGS_NAMES", std::string(""));
|
||||||
this->m_namesArgs = m_variables.resolveFirst("ARGS_NAMES");
|
this->m_namesArgs = m_collections.resolveFirst("ARGS_NAMES");
|
||||||
m_variables.store("ARGS_POST_NAMES", std::string(""));
|
m_collections.store("ARGS_POST_NAMES", std::string(""));
|
||||||
this->m_namesArgsPost = m_variables.resolveFirst("ARGS_POST_NAMES");
|
this->m_namesArgsPost = m_collections.resolveFirst("ARGS_POST_NAMES");
|
||||||
m_variables.store("ARGS_GET_NAMES", std::string(""));
|
m_collections.store("ARGS_GET_NAMES", std::string(""));
|
||||||
this->m_namesArgsGet = m_variables.resolveFirst("ARGS_GET_NAMES");
|
this->m_namesArgsGet = m_collections.resolveFirst("ARGS_GET_NAMES");
|
||||||
m_variables.store("REQUEST_HEADERS_NAMES", std::string(""));
|
m_collections.store("REQUEST_HEADERS_NAMES", std::string(""));
|
||||||
this->m_requestHeadersNames = m_variables.resolveFirst(
|
this->m_requestHeadersNames = m_collections.resolveFirst(
|
||||||
"REQUEST_HEADERS_NAMES");
|
"REQUEST_HEADERS_NAMES");
|
||||||
m_variables.store("RESPONSE_HEADERS_NAMES", std::string(""));
|
m_collections.store("RESPONSE_HEADERS_NAMES", std::string(""));
|
||||||
this->m_responseHeadersNames = m_variables.resolveFirst(
|
this->m_responseHeadersNames = m_collections.resolveFirst(
|
||||||
"RESPONSE_HEADERS_NAMES");
|
"RESPONSE_HEADERS_NAMES");
|
||||||
|
|
||||||
m_variables.setCollections(&collections);
|
|
||||||
collections.emplace("TX", new transaction::Variables());
|
|
||||||
#ifndef NO_LOGS
|
#ifndef NO_LOGS
|
||||||
this->debug(4, "Initialising transaction");
|
this->debug(4, "Initialising transaction");
|
||||||
#endif
|
#endif
|
||||||
@ -141,7 +139,7 @@ Assay::~Assay() {
|
|||||||
m_requestBody.str(std::string());
|
m_requestBody.str(std::string());
|
||||||
m_requestBody.clear();
|
m_requestBody.clear();
|
||||||
|
|
||||||
for (auto &a : collections) {
|
for (auto &a : m_collections) {
|
||||||
delete a.second;
|
delete a.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,12 +200,14 @@ int Assay::processConnection(const char *client, int cPort, const char *server,
|
|||||||
debug(4, "Starting phase CONNECTION. (SecRules 0)");
|
debug(4, "Starting phase CONNECTION. (SecRules 0)");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
this->m_variables.store("REMOTE_HOST", m_clientIpAddress);
|
this->m_collections.store("REMOTE_HOST", m_clientIpAddress);
|
||||||
this->m_variables.store("UNIQUE_ID", id);
|
this->m_collections.store("UNIQUE_ID", id);
|
||||||
this->m_variables.store("REMOTE_ADDR", m_clientIpAddress);
|
this->m_collections.store("REMOTE_ADDR", m_clientIpAddress);
|
||||||
this->m_variables.store("SERVER_ADDR", m_serverIpAddress);
|
this->m_collections.store("SERVER_ADDR", m_serverIpAddress);
|
||||||
this->m_variables.store("SERVER_PORT", std::to_string(this->m_serverPort));
|
this->m_collections.store("SERVER_PORT",
|
||||||
this->m_variables.store("REMOTE_PORT", std::to_string(this->m_clientPort));
|
std::to_string(this->m_serverPort));
|
||||||
|
this->m_collections.store("REMOTE_PORT",
|
||||||
|
std::to_string(this->m_clientPort));
|
||||||
this->m_rules->evaluate(ModSecurity::ConnectionPhase, this);
|
this->m_rules->evaluate(ModSecurity::ConnectionPhase, this);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -252,11 +252,11 @@ int Assay::processURI(const char *uri, const char *protocol,
|
|||||||
size_t pos = m_uri_decoded.find("?");
|
size_t pos = m_uri_decoded.find("?");
|
||||||
size_t pos_raw = uri_s.find("?");
|
size_t pos_raw = uri_s.find("?");
|
||||||
|
|
||||||
m_variables.store("REQUEST_LINE", std::string(protocol) + " " +
|
m_collections.store("REQUEST_LINE", std::string(protocol) + " " +
|
||||||
std::string(uri) + " HTTP/" + std::string(http_version));
|
std::string(uri) + " HTTP/" + std::string(http_version));
|
||||||
|
|
||||||
if (pos_raw != std::string::npos) {
|
if (pos_raw != std::string::npos) {
|
||||||
m_variables.store("QUERY_STRING", std::string(uri_s, pos_raw + 1,
|
m_collections.store("QUERY_STRING", std::string(uri_s, pos_raw + 1,
|
||||||
uri_s.length() - (pos_raw + 1)));
|
uri_s.length() - (pos_raw + 1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,19 +266,20 @@ int Assay::processURI(const char *uri, const char *protocol,
|
|||||||
} else {
|
} else {
|
||||||
path_info = std::string(m_uri_decoded, 0, pos);
|
path_info = std::string(m_uri_decoded, 0, pos);
|
||||||
}
|
}
|
||||||
m_variables.store("PATH_INFO", path_info);
|
m_collections.store("PATH_INFO", path_info);
|
||||||
m_variables.store("REQUEST_FILENAME", path_info);
|
m_collections.store("REQUEST_FILENAME", path_info);
|
||||||
|
|
||||||
size_t offset = path_info.find_last_of("/\\");
|
size_t offset = path_info.find_last_of("/\\");
|
||||||
if (offset != std::string::npos) {
|
if (offset != std::string::npos) {
|
||||||
std::string basename = std::string(path_info, offset,
|
std::string basename = std::string(path_info, offset,
|
||||||
path_info.length() - offset);
|
path_info.length() - offset);
|
||||||
m_variables.store("REQUEST_BASENAME", basename);
|
m_collections.store("REQUEST_BASENAME", basename);
|
||||||
}
|
}
|
||||||
m_variables.store("REQUEST_METHOD", protocol);
|
m_collections.store("REQUEST_METHOD", protocol);
|
||||||
m_variables.store("REQUEST_PROTOCOL", "HTTP/" + std::string(http_version));
|
m_collections.store("REQUEST_PROTOCOL",
|
||||||
m_variables.store("REQUEST_URI", uri);
|
"HTTP/" + std::string(http_version));
|
||||||
m_variables.store("REQUEST_URI_RAW", uri);
|
m_collections.store("REQUEST_URI", uri);
|
||||||
|
m_collections.store("REQUEST_URI_RAW", uri);
|
||||||
|
|
||||||
if (pos != std::string::npos && (m_uri_decoded.length() - pos) > 2) {
|
if (pos != std::string::npos && (m_uri_decoded.length() - pos) > 2) {
|
||||||
/**
|
/**
|
||||||
@ -317,8 +318,8 @@ int Assay::processURI(const char *uri, const char *protocol,
|
|||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_variables.store("ARGS:" + key, value);
|
m_collections.store("ARGS:" + key, value);
|
||||||
m_variables.store("ARGS_GET:" + key, value);
|
m_collections.store("ARGS_GET:" + key, value);
|
||||||
|
|
||||||
if (m_namesArgs->empty()) {
|
if (m_namesArgs->empty()) {
|
||||||
m_namesArgs->assign(key);
|
m_namesArgs->assign(key);
|
||||||
@ -398,11 +399,11 @@ int Assay::addRequestHeader(const std::string& key,
|
|||||||
const std::string& value) {
|
const std::string& value) {
|
||||||
m_requestHeadersNames->assign(*m_requestHeadersNames + " " + key);
|
m_requestHeadersNames->assign(*m_requestHeadersNames + " " + key);
|
||||||
|
|
||||||
this->m_variables.store("REQUEST_HEADERS:" + key, value);
|
this->m_collections.store("REQUEST_HEADERS:" + key, value);
|
||||||
|
|
||||||
if (tolower(key) == tolower("Authorization")) {
|
if (tolower(key) == tolower("Authorization")) {
|
||||||
std::vector<std::string> type = split(value, ' ');
|
std::vector<std::string> type = split(value, ' ');
|
||||||
this->m_variables.store("AUTH_TYPE", type[0]);
|
this->m_collections.store("AUTH_TYPE", type[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tolower(key) == "cookie") {
|
if (tolower(key) == "cookie") {
|
||||||
@ -413,8 +414,10 @@ int Assay::addRequestHeader(const std::string& key,
|
|||||||
if (s[0].at(0) == ' ') {
|
if (s[0].at(0) == ' ') {
|
||||||
s[0].erase(0, 1);
|
s[0].erase(0, 1);
|
||||||
}
|
}
|
||||||
this->m_variables.store("REQUEST_COOKIES:" + s[0], s[1]);
|
this->m_collections.store("REQUEST_COOKIES:"
|
||||||
this->m_variables.store("REQUEST_COOKIES_NAMES:" + s[0], s[0]);
|
+ s[0], s[1]);
|
||||||
|
this->m_collections.store("REQUEST_COOKIES_NAMES:"
|
||||||
|
+ s[0], s[0]);
|
||||||
}
|
}
|
||||||
cookies.pop_back();
|
cookies.pop_back();
|
||||||
}
|
}
|
||||||
@ -527,8 +530,8 @@ int Assay::processRequestBody() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_variables.resolveFirst("INBOUND_DATA_ERROR") == NULL) {
|
if (m_collections.resolveFirst("INBOUND_DATA_ERROR") == NULL) {
|
||||||
m_variables.store("INBOUND_DATA_ERROR", "0");
|
m_collections.store("INBOUND_DATA_ERROR", "0");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -541,7 +544,7 @@ int Assay::processRequestBody() {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if (m_requestBodyType == MultiPartRequestBody) {
|
if (m_requestBodyType == MultiPartRequestBody) {
|
||||||
std::string *a = m_variables.resolveFirst(
|
std::string *a = m_collections.resolveFirst(
|
||||||
"REQUEST_HEADERS:Content-Type");
|
"REQUEST_HEADERS:Content-Type");
|
||||||
if (a != NULL) {
|
if (a != NULL) {
|
||||||
Multipart m(*a, this);
|
Multipart m(*a, this);
|
||||||
@ -549,19 +552,19 @@ int Assay::processRequestBody() {
|
|||||||
if (m.init() == true) {
|
if (m.init() == true) {
|
||||||
m.process(m_requestBody.str());
|
m.process(m_requestBody.str());
|
||||||
for (auto &a : m.variables) {
|
for (auto &a : m.variables) {
|
||||||
m_variables.store(a.first, a.second);
|
m_collections.store(a.first, a.second);
|
||||||
}
|
}
|
||||||
if (m.crlf && m.lf) {
|
if (m.crlf && m.lf) {
|
||||||
m_variables.store("MULTIPART_CRLF_LF_LINES", "1");
|
m_collections.store("MULTIPART_CRLF_LF_LINES", "1");
|
||||||
} else {
|
} else {
|
||||||
m_variables.store("MULTIPART_CRLF_LF_LINES", "0");
|
m_collections.store("MULTIPART_CRLF_LF_LINES", "0");
|
||||||
}
|
}
|
||||||
if (m.boundaryStartsWithWhiteSpace) {
|
if (m.boundaryStartsWithWhiteSpace) {
|
||||||
#ifndef NO_LOGS
|
#ifndef NO_LOGS
|
||||||
debug(9, "Multipart: Boundary starts with white space, " \
|
debug(9, "Multipart: Boundary starts with white space, " \
|
||||||
"setting MULTIPART_STRICT_ERROR to 1");
|
"setting MULTIPART_STRICT_ERROR to 1");
|
||||||
#endif
|
#endif
|
||||||
m_variables.storeOrUpdateFirst(
|
m_collections.storeOrUpdateFirst(
|
||||||
"MULTIPART_STRICT_ERROR", "1");
|
"MULTIPART_STRICT_ERROR", "1");
|
||||||
}
|
}
|
||||||
if (m.boundaryIsQuoted) {
|
if (m.boundaryIsQuoted) {
|
||||||
@ -570,7 +573,7 @@ int Assay::processRequestBody() {
|
|||||||
debug(9, "Multipart: Boundary is quoted, " \
|
debug(9, "Multipart: Boundary is quoted, " \
|
||||||
"setting MULTIPART_STRICT_ERROR to 1");
|
"setting MULTIPART_STRICT_ERROR to 1");
|
||||||
#endif
|
#endif
|
||||||
m_variables.storeOrUpdateFirst(
|
m_collections.storeOrUpdateFirst(
|
||||||
"MULTIPART_STRICT_ERROR", "1");
|
"MULTIPART_STRICT_ERROR", "1");
|
||||||
}
|
}
|
||||||
if (m.containsDataAfter) {
|
if (m.containsDataAfter) {
|
||||||
@ -578,18 +581,18 @@ int Assay::processRequestBody() {
|
|||||||
debug(9, "Multipart: There is data after the boundary, " \
|
debug(9, "Multipart: There is data after the boundary, " \
|
||||||
"setting MULTIPART_STRICT_ERROR to 1");
|
"setting MULTIPART_STRICT_ERROR to 1");
|
||||||
#endif
|
#endif
|
||||||
m_variables.storeOrUpdateFirst(
|
m_collections.storeOrUpdateFirst(
|
||||||
"MULTIPART_STRICT_ERROR", "1");
|
"MULTIPART_STRICT_ERROR", "1");
|
||||||
m_variables.store("MULTIPART_UNMATCHED_BOUNDARY", "1");
|
m_collections.store("MULTIPART_UNMATCHED_BOUNDARY", "1");
|
||||||
} else {
|
} else {
|
||||||
m_variables.store("MULTIPART_UNMATCHED_BOUNDARY", "0");
|
m_collections.store("MULTIPART_UNMATCHED_BOUNDARY", "0");
|
||||||
}
|
}
|
||||||
if (m.containsDataBefore) {
|
if (m.containsDataBefore) {
|
||||||
#ifndef NO_LOGS
|
#ifndef NO_LOGS
|
||||||
debug(9, "Multipart: There is data before the boundary, " \
|
debug(9, "Multipart: There is data before the boundary, " \
|
||||||
"setting MULTIPART_STRICT_ERROR to 1");
|
"setting MULTIPART_STRICT_ERROR to 1");
|
||||||
#endif
|
#endif
|
||||||
m_variables.storeOrUpdateFirst(
|
m_collections.storeOrUpdateFirst(
|
||||||
"MULTIPART_STRICT_ERROR", "1");
|
"MULTIPART_STRICT_ERROR", "1");
|
||||||
}
|
}
|
||||||
if (m.lf) {
|
if (m.lf) {
|
||||||
@ -597,7 +600,7 @@ int Assay::processRequestBody() {
|
|||||||
debug(9, "Multipart: Lines are LF-terminated, " \
|
debug(9, "Multipart: Lines are LF-terminated, " \
|
||||||
"setting MULTIPART_STRICT_ERROR to 1");
|
"setting MULTIPART_STRICT_ERROR to 1");
|
||||||
#endif
|
#endif
|
||||||
m_variables.storeOrUpdateFirst(
|
m_collections.storeOrUpdateFirst(
|
||||||
"MULTIPART_STRICT_ERROR", "1");
|
"MULTIPART_STRICT_ERROR", "1");
|
||||||
}
|
}
|
||||||
if (m.missingSemicolon) {
|
if (m.missingSemicolon) {
|
||||||
@ -605,7 +608,7 @@ int Assay::processRequestBody() {
|
|||||||
debug(9, "Multipart: Boundary missing semicolon, " \
|
debug(9, "Multipart: Boundary missing semicolon, " \
|
||||||
"setting MULTIPART_STRICT_ERROR to 1");
|
"setting MULTIPART_STRICT_ERROR to 1");
|
||||||
#endif
|
#endif
|
||||||
m_variables.storeOrUpdateFirst(
|
m_collections.storeOrUpdateFirst(
|
||||||
"MULTIPART_STRICT_ERROR", "1");
|
"MULTIPART_STRICT_ERROR", "1");
|
||||||
}
|
}
|
||||||
if (m.invalidQuote) {
|
if (m.invalidQuote) {
|
||||||
@ -613,7 +616,7 @@ int Assay::processRequestBody() {
|
|||||||
debug(9, "Multipart: Invalid quote, " \
|
debug(9, "Multipart: Invalid quote, " \
|
||||||
"setting MULTIPART_STRICT_ERROR to 1");
|
"setting MULTIPART_STRICT_ERROR to 1");
|
||||||
#endif
|
#endif
|
||||||
m_variables.storeOrUpdateFirst(
|
m_collections.storeOrUpdateFirst(
|
||||||
"MULTIPART_STRICT_ERROR", "1");
|
"MULTIPART_STRICT_ERROR", "1");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -647,8 +650,8 @@ int Assay::processRequestBody() {
|
|||||||
char sep2 = '=';
|
char sep2 = '=';
|
||||||
|
|
||||||
std::vector<std::string> key_value = split(t, sep2);
|
std::vector<std::string> key_value = split(t, sep2);
|
||||||
m_variables.store("ARGS:" + key_value[0], key_value[1]);
|
m_collections.store("ARGS:" + key_value[0], key_value[1]);
|
||||||
m_variables.store("ARGS_POST:" + key_value[0], key_value[1]);
|
m_collections.store("ARGS_POST:" + key_value[0], key_value[1]);
|
||||||
|
|
||||||
if (m_namesArgs->empty()) {
|
if (m_namesArgs->empty()) {
|
||||||
m_namesArgs->assign(key_value[0]);
|
m_namesArgs->assign(key_value[0]);
|
||||||
@ -674,7 +677,7 @@ int Assay::processRequestBody() {
|
|||||||
*/
|
*/
|
||||||
std::string fullRequest;
|
std::string fullRequest;
|
||||||
std::list<transaction::Variable *> l;
|
std::list<transaction::Variable *> l;
|
||||||
m_variables.resolve("REQUEST_HEADERS", &l);
|
m_collections.resolve("REQUEST_HEADERS", &l);
|
||||||
for (auto &a : l) {
|
for (auto &a : l) {
|
||||||
fullRequest = fullRequest + \
|
fullRequest = fullRequest + \
|
||||||
std::string(a->m_key, 16, a->m_key.length() - 16) + ": " \
|
std::string(a->m_key, 16, a->m_key.length() - 16) + ": " \
|
||||||
@ -682,13 +685,13 @@ int Assay::processRequestBody() {
|
|||||||
}
|
}
|
||||||
fullRequest = fullRequest + "\n\n";
|
fullRequest = fullRequest + "\n\n";
|
||||||
fullRequest = fullRequest + m_requestBody.str();
|
fullRequest = fullRequest + m_requestBody.str();
|
||||||
m_variables.store("FULL_REQUEST", fullRequest);
|
m_collections.store("FULL_REQUEST", fullRequest);
|
||||||
m_variables.store("FULL_REQUEST_LENGTH",
|
m_collections.store("FULL_REQUEST_LENGTH",
|
||||||
std::to_string(fullRequest.size()));
|
std::to_string(fullRequest.size()));
|
||||||
|
|
||||||
if (m_requestBody.tellp() > 0) {
|
if (m_requestBody.tellp() > 0) {
|
||||||
m_variables.store("REQUEST_BODY", m_requestBody.str());
|
m_collections.store("REQUEST_BODY", m_requestBody.str());
|
||||||
m_variables.store("REQUEST_BODY_LENGTH",
|
m_collections.store("REQUEST_BODY_LENGTH",
|
||||||
std::to_string(m_requestBody.str().size()));
|
std::to_string(m_requestBody.str().size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -759,7 +762,7 @@ int Assay::appendRequestBody(const unsigned char *buf, size_t len) {
|
|||||||
|
|
||||||
if (this->m_rules->requestBodyLimit > 0
|
if (this->m_rules->requestBodyLimit > 0
|
||||||
&& this->m_rules->requestBodyLimit < len + current_size) {
|
&& this->m_rules->requestBodyLimit < len + current_size) {
|
||||||
m_variables.store("INBOUND_DATA_ERROR", "1");
|
m_collections.store("INBOUND_DATA_ERROR", "1");
|
||||||
#ifndef NO_LOGS
|
#ifndef NO_LOGS
|
||||||
debug(5, "Request body is bigger than the maximum expected.");
|
debug(5, "Request body is bigger than the maximum expected.");
|
||||||
#endif
|
#endif
|
||||||
@ -846,10 +849,10 @@ int Assay::addResponseHeader(const std::string& key,
|
|||||||
const std::string& value) {
|
const std::string& value) {
|
||||||
m_responseHeadersNames->assign(*m_responseHeadersNames + " " + key);
|
m_responseHeadersNames->assign(*m_responseHeadersNames + " " + key);
|
||||||
|
|
||||||
this->m_variables.store("RESPONSE_HEADERS:" + key, value);
|
this->m_collections.store("RESPONSE_HEADERS:" + key, value);
|
||||||
|
|
||||||
if (tolower(key) == "content-type") {
|
if (tolower(key) == "content-type") {
|
||||||
this->m_variables.store("RESPONSE_CONTENT_TYPE", value);
|
this->m_collections.store("RESPONSE_CONTENT_TYPE", value);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -940,12 +943,12 @@ int Assay::processResponseBody() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_variables.resolveFirst("OUTBOUND_DATA_ERROR") == NULL) {
|
if (m_collections.resolveFirst("OUTBOUND_DATA_ERROR") == NULL) {
|
||||||
m_variables.store("OUTBOUND_DATA_ERROR", "0");
|
m_collections.store("OUTBOUND_DATA_ERROR", "0");
|
||||||
}
|
}
|
||||||
|
|
||||||
m_variables.store("RESPONSE_BODY", m_responseBody.str());
|
m_collections.store("RESPONSE_BODY", m_responseBody.str());
|
||||||
m_variables.store("RESPONSE_CONTENT_LENGTH",
|
m_collections.store("RESPONSE_CONTENT_LENGTH",
|
||||||
std::to_string(m_responseBody.str().size()));
|
std::to_string(m_responseBody.str().size()));
|
||||||
|
|
||||||
this->m_rules->evaluate(ModSecurity::ResponseBodyPhase, this);
|
this->m_rules->evaluate(ModSecurity::ResponseBodyPhase, this);
|
||||||
@ -982,7 +985,7 @@ int Assay::appendResponseBody(const unsigned char *buf, size_t len) {
|
|||||||
|
|
||||||
if (this->m_rules->responseBodyLimit > 0
|
if (this->m_rules->responseBodyLimit > 0
|
||||||
&& this->m_rules->responseBodyLimit < len + current_size) {
|
&& this->m_rules->responseBodyLimit < len + current_size) {
|
||||||
m_variables.store("OUTBOUND_DATA_ERROR", "1");
|
m_collections.store("OUTBOUND_DATA_ERROR", "1");
|
||||||
#ifndef NO_LOGS
|
#ifndef NO_LOGS
|
||||||
debug(5, "Response body is bigger than the maximum expected.");
|
debug(5, "Response body is bigger than the maximum expected.");
|
||||||
#endif
|
#endif
|
||||||
@ -1195,12 +1198,14 @@ std::string Assay::toOldAuditLogFormatIndex(const std::string &filename,
|
|||||||
strftime(tstr, 299, "[%d/%b/%Y:%H:%M:%S %z]", &timeinfo);
|
strftime(tstr, 299, "[%d/%b/%Y:%H:%M:%S %z]", &timeinfo);
|
||||||
|
|
||||||
ss << dash_if_empty(
|
ss << dash_if_empty(
|
||||||
*this->m_variables.resolveFirst("REQUEST_HEADERS:Host")) << " ";
|
*this->m_collections.resolveFirst("REQUEST_HEADERS:Host")) << " ";
|
||||||
ss << dash_if_empty(this->m_clientIpAddress) << " ";
|
ss << dash_if_empty(this->m_clientIpAddress) << " ";
|
||||||
/** TODO: Check variable */
|
/** TODO: Check variable */
|
||||||
ss << dash_if_empty(*this->m_variables.resolveFirst("REMOTE_USER")) << " ";
|
ss << dash_if_empty(*this->m_collections.resolveFirst("REMOTE_USER"));
|
||||||
|
ss << " ";
|
||||||
/** TODO: Check variable */
|
/** TODO: Check variable */
|
||||||
ss << dash_if_empty(*this->m_variables.resolveFirst("LOCAL_USER")) << " ";
|
ss << dash_if_empty(*this->m_collections.resolveFirst("LOCAL_USER"));
|
||||||
|
ss << " ";
|
||||||
ss << tstr << " ";
|
ss << tstr << " ";
|
||||||
|
|
||||||
ss << "\"";
|
ss << "\"";
|
||||||
@ -1212,14 +1217,14 @@ std::string Assay::toOldAuditLogFormatIndex(const std::string &filename,
|
|||||||
ss << this->httpCodeReturned << " ";
|
ss << this->httpCodeReturned << " ";
|
||||||
ss << this->m_responseBody.tellp();
|
ss << this->m_responseBody.tellp();
|
||||||
/** TODO: Check variable */
|
/** TODO: Check variable */
|
||||||
ss << dash_if_empty(*this->m_variables.resolveFirst("REFERER")) << " ";
|
ss << dash_if_empty(*this->m_collections.resolveFirst("REFERER")) << " ";
|
||||||
ss << "\"";
|
ss << "\"";
|
||||||
ss << dash_if_empty(
|
ss << dash_if_empty(
|
||||||
*this->m_variables.resolveFirst("REQUEST_HEADERS:User-Agent"));
|
*this->m_collections.resolveFirst("REQUEST_HEADERS:User-Agent"));
|
||||||
ss << "\" ";
|
ss << "\" ";
|
||||||
ss << this->id << " ";
|
ss << this->id << " ";
|
||||||
/** TODO: Check variable */
|
/** TODO: Check variable */
|
||||||
ss << dash_if_empty(*this->m_variables.resolveFirst("REFERER")) << " ";
|
ss << dash_if_empty(*this->m_collections.resolveFirst("REFERER")) << " ";
|
||||||
|
|
||||||
ss << filename << " ";
|
ss << filename << " ";
|
||||||
ss << "0" << " ";
|
ss << "0" << " ";
|
||||||
@ -1253,7 +1258,7 @@ std::string Assay::toOldAuditLogFormat(int parts, const std::string &trailer) {
|
|||||||
audit_log << this->m_protocol << " " << this->m_uri << " " << "HTTP/";
|
audit_log << this->m_protocol << " " << this->m_uri << " " << "HTTP/";
|
||||||
audit_log << this->m_httpVersion << std::endl;
|
audit_log << this->m_httpVersion << std::endl;
|
||||||
|
|
||||||
for (auto h : m_variables) {
|
for (auto h : m_collections.m_transient) {
|
||||||
std::string filter = "REQUEST_HEADERS:";
|
std::string filter = "REQUEST_HEADERS:";
|
||||||
std::string a = h.first;
|
std::string a = h.first;
|
||||||
std::string b = h.second;
|
std::string b = h.second;
|
||||||
@ -1280,7 +1285,7 @@ std::string Assay::toOldAuditLogFormat(int parts, const std::string &trailer) {
|
|||||||
}
|
}
|
||||||
if (parts & AuditLog::FAuditLogPart) {
|
if (parts & AuditLog::FAuditLogPart) {
|
||||||
audit_log << "--" << trailer << "-" << "F--" << std::endl;
|
audit_log << "--" << trailer << "-" << "F--" << std::endl;
|
||||||
for (auto h : m_variables) {
|
for (auto h : m_collections.m_transient) {
|
||||||
std::string filter = "RESPONSE_HEADERS:";
|
std::string filter = "RESPONSE_HEADERS:";
|
||||||
std::string a = h.first;
|
std::string a = h.first;
|
||||||
std::string b = h.second;
|
std::string b = h.second;
|
||||||
@ -1369,7 +1374,7 @@ std::string Assay::to_json(int parts) {
|
|||||||
strlen("headers"));
|
strlen("headers"));
|
||||||
yajl_gen_map_open(g);
|
yajl_gen_map_open(g);
|
||||||
|
|
||||||
for (auto h : m_variables) {
|
for (auto h : m_collections.m_transient) {
|
||||||
std::string filter = "REQUEST_HEADERS:";
|
std::string filter = "REQUEST_HEADERS:";
|
||||||
std::string a = h.first;
|
std::string a = h.first;
|
||||||
std::string b = h.second;
|
std::string b = h.second;
|
||||||
@ -1404,7 +1409,7 @@ std::string Assay::to_json(int parts) {
|
|||||||
strlen("headers"));
|
strlen("headers"));
|
||||||
yajl_gen_map_open(g);
|
yajl_gen_map_open(g);
|
||||||
|
|
||||||
for (auto h : m_variables) {
|
for (auto h : m_collections.m_transient) {
|
||||||
std::string filter = "RESPONSE_HEADERS:";
|
std::string filter = "RESPONSE_HEADERS:";
|
||||||
std::string a = h.first;
|
std::string a = h.first;
|
||||||
std::string b = h.second;
|
std::string b = h.second;
|
||||||
@ -1474,24 +1479,6 @@ void Assay::serverLog(const std::string& msg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Assay::setCollection(const std::string& collectionName,
|
|
||||||
const std::string& variableName,
|
|
||||||
const std::string& targetValue) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
transaction::Variables *collection;
|
|
||||||
collection = collections.at(collectionName);
|
|
||||||
collection->storeOrUpdateFirst(collectionName + ":"
|
|
||||||
+ variableName, targetValue);
|
|
||||||
} catch (...) {
|
|
||||||
#ifndef NO_LOGS
|
|
||||||
debug(9, "don't know any collection named: "
|
|
||||||
+ collectionName + ". it was created?");
|
|
||||||
#endif
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name msc_new_assay
|
* @name msc_new_assay
|
||||||
* @brief Create a new assay for a given configuration and ModSecurity core.
|
* @brief Create a new assay for a given configuration and ModSecurity core.
|
||||||
|
@ -53,12 +53,12 @@ std::string MacroExpansion::expand(const std::string& input, Assay *assay) {
|
|||||||
std::string *variableValue;
|
std::string *variableValue;
|
||||||
size_t collection = variable.find(".");
|
size_t collection = variable.find(".");
|
||||||
if (collection == std::string::npos) {
|
if (collection == std::string::npos) {
|
||||||
variableValue = assay->m_variables.resolveFirst(variable);
|
variableValue = assay->m_collections.resolveFirst(variable);
|
||||||
} else {
|
} else {
|
||||||
std::string col = std::string(variable, 0, collection);
|
std::string col = std::string(variable, 0, collection);
|
||||||
std::string var = std::string(variable, collection + 1,
|
std::string var = std::string(variable, collection + 1,
|
||||||
variable.length() - (collection + 1));
|
variable.length() - (collection + 1));
|
||||||
variableValue = assay->m_variables.resolveFirst(col, var);
|
variableValue = assay->m_collections.resolveFirst(col, var);
|
||||||
}
|
}
|
||||||
|
|
||||||
res.erase(start, end - start + 2);
|
res.erase(start, end - start + 2);
|
||||||
|
@ -44,42 +44,42 @@ bool GeoLookup::evaluate(Assay *assay, const std::string &exp) {
|
|||||||
}
|
}
|
||||||
if (ret && gir) {
|
if (ret && gir) {
|
||||||
if (gir->country_code) {
|
if (gir->country_code) {
|
||||||
assay->m_variables.store("GEO:COUNTRY_CODE", gir->country_code);
|
assay->m_collections.store("GEO:COUNTRY_CODE", gir->country_code);
|
||||||
}
|
}
|
||||||
if (gir->country_code3) {
|
if (gir->country_code3) {
|
||||||
assay->m_variables.store("GEO:COUNTRY_CODE3", gir->country_code3);
|
assay->m_collections.store("GEO:COUNTRY_CODE3", gir->country_code3);
|
||||||
}
|
}
|
||||||
if (gir->country_name) {
|
if (gir->country_name) {
|
||||||
assay->m_variables.store("GEO:COUNTRY_NAME", gir->country_name);
|
assay->m_collections.store("GEO:COUNTRY_NAME", gir->country_name);
|
||||||
}
|
}
|
||||||
if (gir->continent_code) {
|
if (gir->continent_code) {
|
||||||
assay->m_variables.store("GEO:COUNTRY_CONTINENT",
|
assay->m_collections.store("GEO:COUNTRY_CONTINENT",
|
||||||
gir->continent_code);
|
gir->continent_code);
|
||||||
}
|
}
|
||||||
if (gir->country_code && gir->region) {
|
if (gir->country_code && gir->region) {
|
||||||
assay->m_variables.store("GEO:REGION",
|
assay->m_collections.store("GEO:REGION",
|
||||||
GeoIP_region_name_by_code(gir->country_code, gir->region));
|
GeoIP_region_name_by_code(gir->country_code, gir->region));
|
||||||
}
|
}
|
||||||
if (gir->city) {
|
if (gir->city) {
|
||||||
assay->m_variables.store("GEO:CITY", gir->city);
|
assay->m_collections.store("GEO:CITY", gir->city);
|
||||||
}
|
}
|
||||||
if (gir->postal_code) {
|
if (gir->postal_code) {
|
||||||
assay->m_variables.store("GEO:POSTAL_CODE", gir->postal_code);
|
assay->m_collections.store("GEO:POSTAL_CODE", gir->postal_code);
|
||||||
}
|
}
|
||||||
if (gir->latitude) {
|
if (gir->latitude) {
|
||||||
assay->m_variables.store("GEO:LATITUDE",
|
assay->m_collections.store("GEO:LATITUDE",
|
||||||
std::to_string(gir->latitude));
|
std::to_string(gir->latitude));
|
||||||
}
|
}
|
||||||
if (gir->longitude) {
|
if (gir->longitude) {
|
||||||
assay->m_variables.store("GEO:LONGITUDE",
|
assay->m_collections.store("GEO:LONGITUDE",
|
||||||
std::to_string(gir->longitude));
|
std::to_string(gir->longitude));
|
||||||
}
|
}
|
||||||
if (gir->metro_code) {
|
if (gir->metro_code) {
|
||||||
assay->m_variables.store("GEO:DMA_CODE",
|
assay->m_collections.store("GEO:DMA_CODE",
|
||||||
std::to_string(gir->metro_code));
|
std::to_string(gir->metro_code));
|
||||||
}
|
}
|
||||||
if (gir->area_code) {
|
if (gir->area_code) {
|
||||||
assay->m_variables.store("GEO:AREA_CODE",
|
assay->m_collections.store("GEO:AREA_CODE",
|
||||||
std::to_string(gir->area_code));
|
std::to_string(gir->area_code));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
24
src/rule.cc
24
src/rule.cc
@ -402,22 +402,24 @@ bool Rule::evaluate(Assay *assay) {
|
|||||||
#ifndef NO_LOGS
|
#ifndef NO_LOGS
|
||||||
assay->debug(4, "Executing chained rule.");
|
assay->debug(4, "Executing chained rule.");
|
||||||
#endif
|
#endif
|
||||||
if (assay->m_variables.storeOrUpdateFirst("MATCHED_VAR",
|
if (assay->m_collections.storeOrUpdateFirst("MATCHED_VAR",
|
||||||
value) == false) {
|
value) == false) {
|
||||||
assay->m_variables.store("MATCHED_VAR", value);
|
assay->m_collections.store("MATCHED_VAR", value);
|
||||||
}
|
}
|
||||||
if (assay->m_variables.storeOrUpdateFirst(
|
if (assay->m_collections.storeOrUpdateFirst(
|
||||||
"MATCHED_VAR_NAME", v->m_key) == false) {
|
"MATCHED_VAR_NAME", v->m_key) == false) {
|
||||||
assay->m_variables.store("MATCHED_VAR_NAME", v->m_key);
|
assay->m_collections.store("MATCHED_VAR_NAME",
|
||||||
|
v->m_key);
|
||||||
}
|
}
|
||||||
assay->m_variables.store("MATCHED_VARS:" + v->m_key, value);
|
assay->m_collections.store("MATCHED_VARS:"
|
||||||
assay->m_variables.store("MATCHED_VARS_NAMES:" + v->m_key,
|
+ v->m_key, value);
|
||||||
v->m_key);
|
assay->m_collections.store("MATCHED_VARS_NAMES:"
|
||||||
|
+ v->m_key, v->m_key);
|
||||||
chainResult = this->chainedRule->evaluate(assay);
|
chainResult = this->chainedRule->evaluate(assay);
|
||||||
assay->m_variables.storeOrUpdateFirst("MATCHED_VAR", "");
|
assay->m_collections.storeOrUpdateFirst("MATCHED_VAR", "");
|
||||||
assay->m_variables.del("MATCHED_VARS:" + v->m_key);
|
assay->m_collections.del("MATCHED_VARS:" + v->m_key);
|
||||||
assay->m_variables.del("MATCHED_VARS_NAMES:" + v->m_key);
|
assay->m_collections.del("MATCHED_VARS_NAMES:" + v->m_key);
|
||||||
assay->m_variables.del("MATCHED_VARS_NAME");
|
assay->m_collections.del("MATCHED_VARS_NAME");
|
||||||
}
|
}
|
||||||
if (this->chained && chainResult == true || !this->chained) {
|
if (this->chained && chainResult == true || !this->chained) {
|
||||||
for (Action *a :
|
for (Action *a :
|
||||||
|
165
src/variables.cc
165
src/variables.cc
@ -30,152 +30,87 @@ namespace ModSecurity {
|
|||||||
namespace transaction {
|
namespace transaction {
|
||||||
|
|
||||||
|
|
||||||
Variables::Variables() :
|
Variables::Variables() {
|
||||||
m_collections(NULL) {
|
|
||||||
this->reserve(1000);
|
this->reserve(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Variables::setCollections(std::unordered_map<std::string,
|
|
||||||
transaction::Variables *> *c) {
|
|
||||||
m_collections = c;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Variables::store(std::string key, std::string value) {
|
void Variables::store(std::string key, std::string value) {
|
||||||
this->emplace(key, value);
|
this->emplace(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Variables::storeOrUpdateFirst(const std::string &key,
|
bool Variables::storeOrUpdateFirst(const std::string &key,
|
||||||
const std::string &value) {
|
const std::string &value) {
|
||||||
if (updateFirst(key, value) == false) {
|
if (updateFirst(key, value) == false) {
|
||||||
store(key, value);
|
store(key, value);
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Variables::updateFirst(const std::string &key, const std::string &value) {
|
bool Variables::updateFirst(const std::string &key, const std::string &value) {
|
||||||
auto range = this->equal_range(key);
|
auto range = this->equal_range(key);
|
||||||
|
|
||||||
for (auto it = range.first; it != range.second; ++it) {
|
for (auto it = range.first; it != range.second; ++it) {
|
||||||
it->second = value;
|
it->second = value;
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Variables::del(const std::string& key) {
|
void Variables::del(const std::string& key) {
|
||||||
this->erase(key);
|
this->erase(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::list<transaction::Variable *> Variables::resolve(const std::string& key,
|
||||||
|
std::list<transaction::Variable *> *l) {
|
||||||
|
auto range = this->equal_range(key);
|
||||||
|
|
||||||
|
for (auto it = range.first; it != range.second; ++it) {
|
||||||
|
l->push_back(new transaction::Variable(key, it->second));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (key.find(":") == std::string::npos && l->size() == 0) {
|
||||||
std::list<Variable *>
|
size_t keySize = key.size() + 1;
|
||||||
Variables::resolveInt(const std::string& key,
|
for (auto& x : *this) {
|
||||||
std::list<Variable *> *l) {
|
if (x.first.size() <= keySize) {
|
||||||
auto range = this->equal_range(key);
|
continue;
|
||||||
|
|
||||||
for (auto it = range.first; it != range.second; ++it) {
|
|
||||||
l->push_back(new transaction::Variable(key, it->second));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key.find(":") == std::string::npos && l->size() == 0) {
|
|
||||||
size_t keySize = key.size() + 1;
|
|
||||||
for (auto& x : *this) {
|
|
||||||
if (x.first.size() <= keySize) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (x.first.at(keySize - 1) != ':') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (x.first.compare(0, keySize, key + ":") != 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// auto range = this->equal_range(x.first);
|
|
||||||
|
|
||||||
// for (auto it = range.first; it != range.second; ++it) {
|
|
||||||
l->push_back(new transaction::Variable(x.first, x.second));
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
if (x.first.at(keySize - 1) != ':') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (x.first.compare(0, keySize, key + ":") != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// auto range = this->equal_range(x.first);
|
||||||
|
|
||||||
|
// for (auto it = range.first; it != range.second; ++it) {
|
||||||
|
l->push_back(new transaction::Variable(x.first, x.second));
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
return *l;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return *l;
|
||||||
|
}
|
||||||
|
|
||||||
std::list<Variable *>
|
|
||||||
Variables::resolveInt(const std::string& key) {
|
|
||||||
std::list<Variable *> l;
|
|
||||||
|
|
||||||
return resolveInt(key, &l);
|
std::list<transaction::Variable *> Variables::resolve(const std::string& key) {
|
||||||
}
|
std::list<transaction::Variable *> l;
|
||||||
|
return resolve(key, &l);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string* Variables::resolveFirst(const std::string& var) {
|
std::string* Variables::resolveFirst(const std::string& var) {
|
||||||
auto range = equal_range(var);
|
auto range = equal_range(var);
|
||||||
|
|
||||||
for (auto it = range.first; it != range.second; ++it) {
|
for (auto it = range.first; it != range.second; ++it) {
|
||||||
return &it->second;
|
return &it->second;
|
||||||
}
|
|
||||||
|
|
||||||
if (m_collections == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto &a : *m_collections) {
|
|
||||||
auto range = a.second->equal_range(var);
|
|
||||||
for (auto it = range.first; it != range.second; ++it) {
|
|
||||||
return &it->second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
std::string* Variables::resolveFirst(const std::string& collectionName,
|
|
||||||
const std::string& var) {
|
|
||||||
if (m_collections == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto &a : *m_collections) {
|
|
||||||
if (tolower(a.first) == tolower(collectionName)) {
|
|
||||||
auto range = a.second->equal_range(toupper(collectionName)
|
|
||||||
+ ":" + var);
|
|
||||||
for (auto it = range.first; it != range.second; ++it) {
|
|
||||||
return &it->second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Variables::resolve(const std::string& var,
|
|
||||||
std::list<transaction::Variable *> *l) {
|
|
||||||
|
|
||||||
resolveInt(var, l);
|
|
||||||
|
|
||||||
if (m_collections == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* It may be a collection */
|
|
||||||
for (auto &a : *m_collections) {
|
|
||||||
a.second->resolveInt(var, l);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::list<transaction::Variable *> *
|
|
||||||
Variables::resolve(const std::string& var) {
|
|
||||||
std::list<transaction::Variable *> *l =
|
|
||||||
new std::list<transaction::Variable *>();
|
|
||||||
|
|
||||||
resolve(var, l);
|
|
||||||
|
|
||||||
return l;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ std::list<transaction::Variable *> *
|
|||||||
Variable::evaluate(Assay *assay) {
|
Variable::evaluate(Assay *assay) {
|
||||||
std::list<transaction::Variable *> *l =
|
std::list<transaction::Variable *> *l =
|
||||||
new std::list<transaction::Variable *>();
|
new std::list<transaction::Variable *>();
|
||||||
assay->m_variables.resolve(this->name, l);
|
assay->m_collections.resolve(this->name, l);
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ std::list<transaction::Variable *> *
|
|||||||
Exclusion::evaluate(Assay *assay) {
|
Exclusion::evaluate(Assay *assay) {
|
||||||
std::list<transaction::Variable *> *l =
|
std::list<transaction::Variable *> *l =
|
||||||
new std::list<transaction::Variable *>();
|
new std::list<transaction::Variable *>();
|
||||||
assay->m_variables.resolve(this->name, l);
|
assay->m_collections.resolve(this->name, l);
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user