diff --git a/headers/modsecurity/transaction/collection.h b/headers/modsecurity/transaction/collection.h new file mode 100644 index 00000000..069f1940 --- /dev/null +++ b/headers/modsecurity/transaction/collection.h @@ -0,0 +1,51 @@ +/* + * 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. + * + */ + + +#ifndef HEADERS_MODSECURITY_TRANSACTION_COLLECTION_H_ +#define HEADERS_MODSECURITY_TRANSACTION_COLLECTION_H_ + + +#ifndef __cplusplus +typedef struct Collection_t Collection; +#endif + + +#ifdef __cplusplus +namespace ModSecurity { + +class Collection : public transaction::Variables { + public: + Collection(std::string name, std::string key) + : m_name(name), + m_key(key) { }; + + std::string m_name; + clock_t m_createTime; + bool m_persisted; /* IS_NEW from the old documentation */ + std::string m_key; + clock_t m_lastUpdateTime; + double m_timeout; + double m_updateCounter; + double m_updateRate; +}; + +} // namespace ModSecurity +#endif + + +#endif // HEADERS_MODSECURITY_TRANSACTION_COLLECTION_H_ + + diff --git a/headers/modsecurity/transaction/collections.h b/headers/modsecurity/transaction/collections.h index 02119ed9..95573884 100644 --- a/headers/modsecurity/transaction/collections.h +++ b/headers/modsecurity/transaction/collections.h @@ -29,6 +29,7 @@ #include "modsecurity/transaction/variables.h" #include "modsecurity/transaction/variable.h" +#include "modsecurity/transaction/collection.h" #ifndef HEADERS_MODSECURITY_TRANSACTION_COLLECTIONS_H_ #define HEADERS_MODSECURITY_TRANSACTION_COLLECTIONS_H_ @@ -42,11 +43,12 @@ namespace ModSecurity { namespace transaction { class Collections : - public std::unordered_map { + public std::unordered_map { public: Collections(); ~Collections(); + void init(const std::string& name, const std::string& key); void store(std::string key, std::string value); void storeOrUpdateFirst(const std::string& collectionName, const std::string& variableName, @@ -62,7 +64,6 @@ class Collections : std::list *l); std::list *resolve(const std::string& var); - /** * This is a special collection to host the transaction variables. * diff --git a/src/collections.cc b/src/collections.cc new file mode 100644 index 00000000..2528ec2d --- /dev/null +++ b/src/collections.cc @@ -0,0 +1,145 @@ +/* + * 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. + * + */ + + +#include "modsecurity/transaction/collections.h" + +#ifdef __cplusplus +#include +#include +#include +#include +#endif + +#include "modsecurity/transaction/variable.h" +#include "src/utils.h" + +namespace ModSecurity { +namespace transaction { + + +Collections::Collections() { + /* Create collection TX */ + this->emplace("TX", new Collection("TX", "")); +} + + +Collections::~Collections() { } + + +void Collections::init(const std::string& name, const std::string& key) { + this->emplace(name, new Collection(name, key)); +} + + +void Collections::storeOrUpdateFirst(const std::string& collectionName, + const std::string& variableName, + const std::string& targetValue) { + try { + transaction::Variables *collection; + collection = this->at(collectionName); + collection->storeOrUpdateFirst(collectionName + ":" + + variableName, targetValue); + } catch (...) { +#if 0 + debug(9, "don't know any collection named: " + + collectionName + ". it was created?"); +#endif + } +} + + +void Collections::store(std::string key, std::string value) { + m_transient.store(key, value); +} + + +bool Collections::storeOrUpdateFirst(const std::string &key, + const std::string &value) { + return m_transient.storeOrUpdateFirst(key, value); +} + + +bool Collections::updateFirst(const std::string &key, + const std::string &value) { + return m_transient.updateFirst(key, value); +} + + +void Collections::del(const std::string& key) { + return m_transient.del(key); +} + + +std::string* Collections::resolveFirst(const std::string& var) { + std::string *transientVar = m_transient.resolveFirst(var); + + if (transientVar != NULL) { + return transientVar; + } + + for (auto &a : *this) { + auto range = a.second->equal_range(var); + for (auto it = range.first; it != range.second; ++it) { + return &it->second; + } + } + + return NULL; +} + + +std::string* Collections::resolveFirst(const std::string& collectionName, + const std::string& var) { + for (auto &a : *this) { + if (tolower(a.first) == tolower(collectionName)) { + transaction::Variables *t = a.second; + auto range = t->equal_range(toupper(collectionName) + + ":" + var); + for (auto it = range.first; it != range.second; ++it) { + return &it->second; + } + } + } + + return NULL; + } + + +void Collections::resolve(const std::string& var, + std::list *l) { + + m_transient.resolve(var, l); + + /* It may be a collection */ + for (auto &a : *this) { + transaction::Variables *t = a.second; + a.second->resolve(var, l); + } +} + + +std::list * + Collections::resolve(const std::string& var) { + std::list *l = + new std::list(); + + resolve(var, l); + + return l; +} + +} // namespace transaction +} // namespace ModSecurity