diff --git a/build/libgeoip.m4 b/build/libgeoip.m4 new file mode 100644 index 00000000..9f413263 --- /dev/null +++ b/build/libgeoip.m4 @@ -0,0 +1,155 @@ +dnl Check for GEOIP Libraries +dnl CHECK_GEOIP(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]) +dnl Sets: +dnl GEOIP_CFLAGS +dnl GEOIP_LDADD +dnl GEOIP_LDFLAGS +dnl GEOIP_LIBS +dnl GEOIP_VERSION + +AC_DEFUN([PROG_GEOIP], +[dnl + +AC_REQUIRE([PKG_PROG_PKG_CONFIG]) + +GEOIP_CONFIG="" +GEOIP_VERSION="" +GEOIP_CFLAGS="" +GEOIP_CPPFLAGS="" +GEOIP_LDADD="" +GEOIP_LDFLAGS="" +GEOIP_CONFIG=${PKG_CONFIG} +GEOIP_PKGNAMES="geoip2 geoip" +GEOIP_SONAMES="so la sl dll dylib" + +AC_ARG_WITH( + geoip, + [AC_HELP_STRING([--with-geoip=PATH],[Path to geoip prefix or config script])] + ,, with_geoip=yes) + +AS_CASE(["${with_geoip}"], + [no], [test_paths=], + [yes], [test_paths="/usr/local/libgeoip /usr/local/geoip /usr/local /opt/libgeoip /opt/geoip /opt /usr"], + [test_paths="${with_geoip}"]) + +AS_IF([test "x${test_paths}" != "x"], [ +AC_MSG_CHECKING([for libgeoip config script]) +for x in ${test_paths}; do + dnl # Determine if the script was specified and use it directly + if test ! -d "$x" -a -e "$x"; then + GEOIP_CONFIG=$x + break + fi + + dnl # Try known config script names/locations + for y in $GEOIP_CONFIG; do + if test -e "${x}/bin/${y}"; then + GEOIP_CONFIG="${x}/bin/${y}" + geoip_config="${GEOIP_CONFIG}" + break + elif test -e "${x}/${y}"; then + GEOIP_CONFIG="${x}/${y}" + geoip_config="${GEOIP_CONFIG}" + break + fi + done + if test -n "${geoip_config}"; then + break + fi +done + +dnl # Try known package names +if test -n "${GEOIP_CONFIG}"; then + GEOIP_PKGNAME="" + for x in ${GEOIP_PKGNAMES}; do + if ${GEOIP_CONFIG} --exists ${x}; then + GEOIP_PKGNAME="$x" + break + fi + done +fi + +if test -n "${GEOIP_PKGNAME}"; then + AC_MSG_RESULT([${GEOIP_CONFIG}]) + GEOIP_VERSION="`${GEOIP_CONFIG} ${GEOIP_PKGNAME} --modversion`" + if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(geoip VERSION: $GEOIP_VERSION); fi + GEOIP_CFLAGS="`${GEOIP_CONFIG} ${GEOIP_PKGNAME} --cflags`" + if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(geoip CFLAGS: $GEOIP_CFLAGS); fi + GEOIP_LDADD="`${GEOIP_CONFIG} ${GEOIP_PKGNAME} --libs-only-l`" + if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(geoip LDADD: $GEOIP_LDADD); fi + GEOIP_LDFLAGS="`${GEOIP_CONFIG} ${GEOIP_PKGNAME} --libs-only-L --libs-only-other`" + if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(geoip LDFLAGS: $GEOIP_LDFLAGS); fi +else + AC_MSG_RESULT([no]) + + dnl Hack to just try to find the lib and include + AC_MSG_CHECKING([for geoip install]) + for x in ${test_paths}; do + for y in ${GEOIP_SONAMES}; do + if test -e "${x}/libgeoip.${y}"; then + geoip_lib_path="${x}/" + geoip_lib_name="geoip" + break + else + geoip_lib_path="" + geoip_lib_name="" + fi + done + if test -n "$geoip_lib_path"; then + break + fi + done + for x in ${test_paths}; do + if test -e "${x}/include/geoip_parse.h"; then + geoip_inc_path="${x}/include" + break + elif test -e "${x}/geoip_parse.h"; then + geoip_inc_path="${x}" + break + fi + + dnl # Check some sub-paths as well + for geoip_pkg_name in ${geoip_lib_name} ${GEOIP_PKGNAMES}; do + if test -e "${x}/include/${geoip_pkg_name}/geoip_parse.h"; then + geoip_inc_path="${x}/include" + break + elif test -e "${x}/${geoip_pkg_name}/geoip_parse.h"; then + geoip_inc_path="${x}" + break + else + geoip_inc_path="" + fi + done + if test -n "$geoip_inc_path"; then + break + fi + done + if test -n "${geoip_lib_path}" -a -n "${geoip_inc_path}"; then + GEOIP_CONFIG="" + AC_MSG_RESULT([${geoip_lib_path} ${geoip_inc_path}]) + GEOIP_VERSION="2" + GEOIP_CFLAGS="-I${geoip_inc_path}" + GEOIP_LDADD="-l${geoip_lib_name}" + GEOIP_LDFLAGS="-L${geoip_lib_path}" + else + GEOIP_VERSION="" + AC_MSG_RESULT([no]) + fi +fi + +]) + +GEOIP_LIBS=${GEOIP_LDADD} +AC_SUBST(GEOIP_CFLAGS) +AC_SUBST(GEOIP_VERSION) +AC_SUBST(GEOIP_LDADD) +AC_SUBST(GEOIP_LIBS) +AC_SUBST(GEOIP_LDFLAGS) + if test -z "${GEOIP_VERSION}"; then + ifelse([$2], , AC_MSG_NOTICE([optional geoip library not found]), $2) + else + AC_MSG_NOTICE([using geoip v${GEOIP_VERSION}]) + GEOIP_CFLAGS="-DWITH_GEOIP ${GEOIP_CFLAGS}" + ifelse([$1], , , $1) + fi +]) diff --git a/configure.ac b/configure.ac index 7c8356c7..ea53232b 100644 --- a/configure.ac +++ b/configure.ac @@ -39,6 +39,11 @@ PROG_YAJL AM_CONDITIONAL([YAJL_VERSION], [test "$YAJL_VERSION" != ""]) +# Check for libgeoip +PROG_GEOIP + +AM_CONDITIONAL([GEOIP_VERSION], [test "$GEOIP_VERSION" != ""]) + # Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS([string]) diff --git a/src/Makefile.am b/src/Makefile.am index b9f56372..210fdb53 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -76,7 +76,8 @@ ACTIONS = \ UTILS = \ utils/sha1.cc \ - utils/md5.cc + utils/md5.cc \ + utils/geo_lookup.cc libmodsecurity_la_SOURCES = \ parser/seclang-parser.yy \ @@ -113,7 +114,7 @@ libmodsecurity_la_SOURCES = \ operators/verify_cc.cc \ operators/verify_cpf.cc \ operators/verify_ssn.cc \ - operators/geolookup.cc \ + operators/geo_lookup.cc \ operators/gsblookup.cc \ operators/rsub.cc \ operators/within.cc \ @@ -152,10 +153,10 @@ libmodsecurity_la_CPPFLAGS = \ -O0 \ -I ../headers - libmodsecurity_la_LIBADD = \ @LEXLIB@ \ - $(YAJL_LDADD) + $(GEOIP_LDADD) \ + $(YAJL_LDADD) libmodsecurity_la_LDFLAGS = \ -version-info @MSC_VERSION_INFO@ diff --git a/src/operators/geo_lookup.cc b/src/operators/geo_lookup.cc new file mode 100644 index 00000000..886f1e8a --- /dev/null +++ b/src/operators/geo_lookup.cc @@ -0,0 +1,95 @@ +/* + * 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 "operators/geo_lookup.h" + +#include + +#include +#include + +#include "operators/operator.h" +#include "utils/geo_lookup.h" + + +namespace ModSecurity { +namespace operators { + + +bool GeoLookup::evaluate(Assay *assay, const std::string &exp) { + using std::placeholders::_1; + using std::placeholders::_2; + + GeoIPRecord *gir; + + bool ret = Utils::GeoLookup::getInstance().lookup(exp, &gir, + std::bind(&GeoLookup::debug, this, assay, _1, _2)); + + if (ret && gir) { + if (gir->country_code) { + assay->store_variable("GEO:COUNTRY_CODE", gir->country_code); + } + if (gir->country_code3) { + assay->store_variable("GEO:COUNTRY_CODE3", gir->country_code3); + } + if (gir->country_name) { + assay->store_variable("GEO:COUNTRY_NAME", gir->country_name); + } + if (gir->continent_code) { + assay->store_variable("GEO:COUNTRY_CONTINENT", + gir->continent_code); + } + if (gir->country_code && gir->region) { + assay->store_variable("GEO:REGION", + GeoIP_region_name_by_code(gir->country_code, gir->region)); + } + if (gir->city) { + assay->store_variable("GEO:CITY", gir->city); + } + if (gir->postal_code) { + assay->store_variable("GEO:POSTAL_CODE", gir->postal_code); + } + if (gir->latitude) { + assay->store_variable("GEO:LATITUDE", + std::to_string(gir->latitude)); + } + if (gir->longitude) { + assay->store_variable("GEO:LONGITUDE", + std::to_string(gir->longitude)); + } + if (gir->metro_code) { + assay->store_variable("GEO:DMA_CODE", + std::to_string(gir->metro_code)); + } + if (gir->area_code) { + assay->store_variable("GEO:AREA_CODE", + std::to_string(gir->area_code)); + } + + GeoIPRecord_delete(gir); + } + + return ret; +} + +GeoLookup::GeoLookup(std::string op, std::string param, +bool negation) + : Operator() { + this->op = op; + this->param = param; +} + +} // namespace operators +} // namespace ModSecurity diff --git a/src/operators/geolookup.h b/src/operators/geo_lookup.h similarity index 82% rename from src/operators/geolookup.h rename to src/operators/geo_lookup.h index 58ed409a..9052dfdf 100644 --- a/src/operators/geolookup.h +++ b/src/operators/geo_lookup.h @@ -1,4 +1,4 @@ -/** +/* * ModSecurity, http://www.modsecurity.org/ * Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/) * @@ -13,8 +13,8 @@ * */ -#ifndef SRC_OPERATORS_GEOLOOKUP_H_ -#define SRC_OPERATORS_GEOLOOKUP_H_ +#ifndef SRC_OPERATORS_GEO_LOOKUP_H_ +#define SRC_OPERATORS_GEO_LOOKUP_H_ #include @@ -28,7 +28,7 @@ class GeoLookup : public Operator { public: /** @ingroup ModSecurity_Operator */ GeoLookup(std::string o, std::string p, bool i); - bool evaluate(Assay *assay); + bool evaluate(Assay *assay, const std::string &exp) override; }; } // namespace operators @@ -36,4 +36,4 @@ class GeoLookup : public Operator { #endif -#endif // SRC_OPERATORS_GEOLOOKUP_H_ +#endif // SRC_OPERATORS_GEO_LOOKUP_H_ diff --git a/src/operators/geolookup.cc b/src/operators/geolookup.cc deleted file mode 100644 index 01740aad..00000000 --- a/src/operators/geolookup.cc +++ /dev/null @@ -1,41 +0,0 @@ -/** - * 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 "operators/geolookup.h" - -#include - -#include "operators/operator.h" - -namespace ModSecurity { -namespace operators { - -bool GeoLookup::evaluate(Assay *assay) { - /** - * @todo Implement the operator GeoLookup. - * Reference: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#geolookup - */ - return true; -} - -GeoLookup::GeoLookup(std::string op, std::string param, -bool negation) - : Operator() { - this->op = op; - this->param = param; -} - -} // namespace operators -} // namespace ModSecurity diff --git a/src/operators/operator.cc b/src/operators/operator.cc index f1712d69..a66d6d8c 100644 --- a/src/operators/operator.cc +++ b/src/operators/operator.cc @@ -34,7 +34,7 @@ #include "operators/verify_cc.h" #include "operators/verify_cpf.h" #include "operators/verify_ssn.h" -#include "operators/geolookup.h" +#include "operators/geo_lookup.h" #include "operators/gsblookup.h" #include "operators/rsub.h" #include "operators/within.h" @@ -68,6 +68,12 @@ Operator::Operator() { } +bool Operator::debug(Assay *assay, int x, std::string a) { + assay->debug(x, a); + return true; +} + + Operator::Operator(std::string op, std::string param, bool negation) { this->op = op; this->param = param; diff --git a/src/operators/operator.h b/src/operators/operator.h index 28ed5e49..5f5c5d75 100644 --- a/src/operators/operator.h +++ b/src/operators/operator.h @@ -39,6 +39,7 @@ class Operator { virtual bool evaluate(Assay *assay, const std::string &str); static Operator *instantiate(std::string op); protected: + bool debug(Assay *assay, int x, std::string a); }; } // namespace operators diff --git a/src/parser/seclang-parser.yy b/src/parser/seclang-parser.yy index b38831eb..d5e81b9f 100644 --- a/src/parser/seclang-parser.yy +++ b/src/parser/seclang-parser.yy @@ -18,6 +18,7 @@ class Driver; #include "variable_duration.h" #include "variable_env.h" #include "variable_modsec_build.h" +#include "utils/geo_lookup.h" using ModSecurity::actions::Action; using ModSecurity::actions::transformations::Transformation; @@ -27,6 +28,7 @@ using ModSecurity::VariableDuration; using ModSecurity::VariableEnv; using ModSecurity::VariableModsecBuild; using ModSecurity::Rule; +using ModSecurity::Utils::GeoLookup; } // The parsing context. @@ -90,6 +92,8 @@ using ModSecurity::Rule; %token RUN_TIME_VAR_ENV %token RUN_TIME_VAR_BLD +%token CONFIG_DIR_GEO_DB + %token OPERATOR %token ACTION %token TRANSFORMATION @@ -238,6 +242,10 @@ expression: driver.debug_log_path = $1; } /* Debug log: end */ + | CONFIG_DIR_GEO_DB + { + GeoLookup::getInstance().setDataBase($1); + } variables: variables PIPE VARIABLE diff --git a/src/parser/seclang-scanner.ll b/src/parser/seclang-scanner.ll index 9097509d..c0db21a2 100755 --- a/src/parser/seclang-scanner.ll +++ b/src/parser/seclang-scanner.ll @@ -23,6 +23,7 @@ DIRECTIVE SecRule CONFIG_DIRECTIVE SecRequestBodyLimitAction|SecRequestBodyNoFilesLimit|SecRequestBodyInMemoryLimit|SecRequestBodyLimit|SecPcreMatchLimitRecursion|SecPcreMatchLimit|SecResponseBodyMimeType|SecResponseBodyLimitAction|SecResponseBodyLimit|SecTmpDir|SecDataDir|SecArgumentSeparator|SecCookieFormat|SecStatusEngine +CONFIG_DIR_GEO_DB (?i:SecGeoLookupDb) CONFIG_DIR_RULE_ENG SecRuleEngine CONFIG_DIR_REQ_BODY SecRequestBodyAccess @@ -56,7 +57,7 @@ OPERATORNOARG (?i:@detectSQLi|@detectXSS|@geoLookup|@validateUrlEncoding|@valida TRANSFORMATION t:(lowercase|urlDecodeUni|urlDecode|none|compressWhitespace|removeWhitespace|replaceNulls|removeNulls|htmlEntityDecode|jsDecode|cssDecode|trim) -VARIABLE (?i:FULL_REQUEST|FILES|AUTH_TYPE|ARGS_NAMES|ARGS|QUERY_STRING|REMOTE_ADDR|REQUEST_BASENAME|REQUEST_BODY|REQUEST_COOKIES_NAMES|REQUEST_COOKIES|REQUEST_FILENAME|REQUEST_HEADERS_NAMES|REQUEST_HEADERS|REQUEST_METHOD|REQUEST_PROTOCOL|REQUEST_URI|RESPONSE_BODY|RESPONSE_CONTENT_LENGTH|RESPONSE_CONTENT_TYPE|RESPONSE_HEADERS_NAMES|RESPONSE_HEADERS|RESPONSE_PROTOCOL|RESPONSE_STATUS|TX) +VARIABLE (?i:FULL_REQUEST|FILES|AUTH_TYPE|ARGS_NAMES|ARGS|QUERY_STRING|REMOTE_ADDR|REQUEST_BASENAME|REQUEST_BODY|REQUEST_COOKIES_NAMES|REQUEST_COOKIES|REQUEST_FILENAME|REQUEST_HEADERS_NAMES|REQUEST_HEADERS|REQUEST_METHOD|REQUEST_PROTOCOL|REQUEST_URI|RESPONSE_BODY|RESPONSE_CONTENT_LENGTH|RESPONSE_CONTENT_TYPE|RESPONSE_HEADERS_NAMES|RESPONSE_HEADERS|RESPONSE_PROTOCOL|RESPONSE_STATUS|TX|GEO) RUN_TIME_VAR_DUR (?i:DURATION) RUN_TIME_VAR_ENV (?i:ENV) RUN_TIME_VAR_BLD (?i:MODSEC_BUILD) @@ -75,6 +76,7 @@ AUDIT_PARTS [ABCDEFHJKZ]+ CONFIG_VALUE_NUMBER [0-9]+ FREE_TEXT [^\"]+ +FREE_TEXT_NEW_LINE [^\"|\n]+ %{ // Code run each time a pattern is matched. @@ -115,6 +117,8 @@ FREE_TEXT [^\"]+ {RUN_TIME_VAR_ENV}:?{DICT_ELEMENT}? { return yy::seclang_parser::make_RUN_TIME_VAR_ENV(yytext, loc); } {RUN_TIME_VAR_BLD} { return yy::seclang_parser::make_RUN_TIME_VAR_BLD(yytext, loc); } +%{ /* Geo DB loopkup */ %} +{CONFIG_DIR_GEO_DB}[ ]{FREE_TEXT_NEW_LINE} { return yy::seclang_parser::make_CONFIG_DIR_GEO_DB(strchr(yytext, ' ') + 1, loc); } {CONFIG_COMPONENT_SIG}[ ]["]{FREE_TEXT}["] { return yy::seclang_parser::make_CONFIG_COMPONENT_SIG(strchr(yytext, ' ') + 2, loc); } diff --git a/src/utils/geo_lookup.cc b/src/utils/geo_lookup.cc new file mode 100644 index 00000000..9a55adb6 --- /dev/null +++ b/src/utils/geo_lookup.cc @@ -0,0 +1,62 @@ +/* + * 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 +#include +#include +#include +#include + +#include +#include + +#include "utils/geo_lookup.h" + +#include + +namespace ModSecurity { +namespace Utils { + + +bool GeoLookup::setDataBase(std::string file_path) { + m_gi = GeoIP_open(file_path.c_str(), GEOIP_INDEX_CACHE); + + if (m_gi == NULL) { + return false; + } + + return true; +} + + +bool GeoLookup::lookup(const std::string& target, GeoIPRecord **gir, + std::function debug) { + if (m_gi == NULL) { + debug(4, "GeoIP: Database is not open. Use: SecGeoLookupDb directive."); + return false; + } + + *gir = GeoIP_record_by_name(m_gi, target.c_str()); + if (*gir == NULL) { + return false; + } + + return true; +} + + +} // namespace Utils +} // namespace ModSecurity + diff --git a/src/utils/geo_lookup.h b/src/utils/geo_lookup.h new file mode 100644 index 00000000..bd195f45 --- /dev/null +++ b/src/utils/geo_lookup.h @@ -0,0 +1,56 @@ +/* + * 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 +#include +#include +#include + +#include + +#ifndef SRC_UTILS_GEO_LOOKUP_H_ +#define SRC_UTILS_GEO_LOOKUP_H_ + +#include "modsecurity/assay.h" + +namespace ModSecurity { +namespace Utils { + + +class GeoLookup { + public: + static GeoLookup& getInstance() { + static GeoLookup instance; + return instance; + } + + bool setDataBase(std::string file_path); + bool lookup(const std::string& target, GeoIPRecord **georec, + std::function callback); + + private: + GeoLookup() : m_gi(NULL) {} + + GeoLookup(GeoLookup const&); + void operator=(GeoLookup const&); + + GeoIP *m_gi; +}; + + +} // namespace Utils +} // namespace ModSecurity + +#endif // SRC_UTILS_GEO_LOOKUP_H_ diff --git a/test/Makefile.am b/test/Makefile.am index 53a18e42..001f3ee6 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -24,6 +24,7 @@ unit_tests_SOURCES = \ unit_tests_LDADD = \ $(top_builddir)/src/.libs/libmodsecurity.a \ + $(GEOIP_LDADD) \ $(YAJL_LDADD) unit_tests_CPPFLAGS = \ @@ -32,8 +33,10 @@ unit_tests_CPPFLAGS = \ -O0 \ -g \ -I$(top_builddir)/headers \ + $(GEOIP_CFLAGS) \ $(YAJL_CFLAGS) + # regression regression_tests_SOURCES = \ @@ -43,6 +46,7 @@ regression_tests_SOURCES = \ regression_tests_LDADD = \ $(top_builddir)/src/.libs/libmodsecurity.a \ + $(GEOIP_LDADD) \ $(YAJL_LDADD) regression_tests_CPPFLAGS = \ @@ -51,5 +55,5 @@ regression_tests_CPPFLAGS = \ -O0 \ -g \ -I$(top_builddir)/headers \ + $(GEOIP_CFLAGS) \ $(YAJL_CFLAGS) - diff --git a/test/benchmark/Makefile.am b/test/benchmark/Makefile.am index 469924a9..23e4356e 100644 --- a/test/benchmark/Makefile.am +++ b/test/benchmark/Makefile.am @@ -7,6 +7,7 @@ benchmark_SOURCES = \ benchmark_LDADD = \ $(top_builddir)/src/.libs/libmodsecurity.a \ + $(GEOIP_LDADD) \ $(YAJL_LDADD) benchmark_CPPFLAGS = \ diff --git a/test/test-cases/data/geo/GeoIPCity.dat b/test/test-cases/data/geo/GeoIPCity.dat new file mode 100644 index 00000000..230526c6 Binary files /dev/null and b/test/test-cases/data/geo/GeoIPCity.dat differ diff --git a/test/test-cases/data/geo/README.txt b/test/test-cases/data/geo/README.txt new file mode 100644 index 00000000..11dda78f --- /dev/null +++ b/test/test-cases/data/geo/README.txt @@ -0,0 +1,4 @@ +This data was download from: + +https://github.com/maxmind/geoip-api-php/tree/master/tests + diff --git a/test/test-cases/regression/variable-GEO.json b/test/test-cases/regression/variable-GEO.json new file mode 100644 index 00000000..02d39e78 --- /dev/null +++ b/test/test-cases/regression/variable-GEO.json @@ -0,0 +1,476 @@ +[ + { + "enabled":1, + "version_min":300000, + "title":"Testing Variables :: GEO:LONGITUDE", + "client":{ + "ip":"64.17.254.216", + "port":123 + }, + "server":{ + "ip":"200.249.12.31", + "port":80 + }, + "request":{ + "headers":{ + "Host":"localhost", + "User-Agent":"curl/7.38.0", + "Accept":"*/*" + }, + "uri":"/?key=value&key=other_value", + "protocol":"GET" + }, + "response":{ + "headers":{ + "Date":"Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type":"text/html" + }, + "body":[ + "no need." + ] + }, + "expected":{ + "debug_log":"Target value: \"-118.403999\" \\(Variable: GEO:LONGITUDE\\)" + }, + "rules":[ + "SecRuleEngine On", + "SecDebugLog \/tmp\/modsec_debug.log", + "SecDebugLogLevel 9", + "SecGeoLookupDb test-cases\/data\/geo\/GeoIPCity.dat", + "SecRule REMOTE_ADDR \"@geoLookup\" \"pass,t:trim\"", + "SecRule GEO \"@contains test \" \"pass,t:trim\"" + ] + }, + { + "enabled":1, + "version_min":300000, + "title":"Testing Variables :: GEO:COUNTRY_NAME", + "client":{ + "ip":"64.17.254.216", + "port":123 + }, + "server":{ + "ip":"200.249.12.31", + "port":80 + }, + "request":{ + "headers":{ + "Host":"localhost", + "User-Agent":"curl/7.38.0", + "Accept":"*/*" + }, + "uri":"/?key=value&key=other_value", + "protocol":"GET" + }, + "response":{ + "headers":{ + "Date":"Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type":"text/html" + }, + "body":[ + "no need." + ] + }, + "expected":{ + "debug_log":"Target value: \"United States\" \\(Variable: GEO:COUNTRY_NAME\\)" + }, + "rules":[ + "SecRuleEngine On", + "SecDebugLog \/tmp\/modsec_debug.log", + "SecDebugLogLevel 9", + "SecGeoLookupDb test-cases\/data\/geo\/GeoIPCity.dat", + "SecRule REMOTE_ADDR \"@geoLookup\" \"pass,t:trim\"", + "SecRule GEO \"@contains test \" \"pass,t:trim\"" + ] + }, + { + "enabled":1, + "version_min":300000, + "title":"Testing Variables :: GEO:LATITUDE", + "client":{ + "ip":"64.17.254.216", + "port":123 + }, + "server":{ + "ip":"200.249.12.31", + "port":80 + }, + "request":{ + "headers":{ + "Host":"localhost", + "User-Agent":"curl/7.38.0", + "Accept":"*/*" + }, + "uri":"/?key=value&key=other_value", + "protocol":"GET" + }, + "response":{ + "headers":{ + "Date":"Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type":"text/html" + }, + "body":[ + "no need." + ] + }, + "expected":{ + "debug_log":"Target value: \"33.916401\" \\(Variable: GEO:LATITUDE\\)" + }, + "rules":[ + "SecRuleEngine On", + "SecDebugLog \/tmp\/modsec_debug.log", + "SecDebugLogLevel 9", + "SecGeoLookupDb test-cases\/data\/geo\/GeoIPCity.dat", + "SecRule REMOTE_ADDR \"@geoLookup\" \"pass,t:trim\"", + "SecRule GEO \"@contains test \" \"pass,t:trim\"" + ] + }, + { + "enabled":1, + "version_min":300000, + "title":"Testing Variables :: GEO:COUNTRY_CODE3", + "client":{ + "ip":"64.17.254.216", + "port":123 + }, + "server":{ + "ip":"200.249.12.31", + "port":80 + }, + "request":{ + "headers":{ + "Host":"localhost", + "User-Agent":"curl/7.38.0", + "Accept":"*/*" + }, + "uri":"/?key=value&key=other_value", + "protocol":"GET" + }, + "response":{ + "headers":{ + "Date":"Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type":"text/html" + }, + "body":[ + "no need." + ] + }, + "expected":{ + "debug_log":"Target value: \"USA\" \\(Variable: GEO:COUNTRY_CODE3\\)" + }, + "rules":[ + "SecRuleEngine On", + "SecDebugLog \/tmp\/modsec_debug.log", + "SecDebugLogLevel 9", + "SecGeoLookupDb test-cases\/data\/geo\/GeoIPCity.dat", + "SecRule REMOTE_ADDR \"@geoLookup\" \"pass,t:trim\"", + "SecRule GEO \"@contains test \" \"pass,t:trim\"" + ] + }, + { + "enabled":1, + "version_min":300000, + "title":"Testing Variables :: GEO:COUNTRY_CODE", + "client":{ + "ip":"64.17.254.216", + "port":123 + }, + "server":{ + "ip":"200.249.12.31", + "port":80 + }, + "request":{ + "headers":{ + "Host":"localhost", + "User-Agent":"curl/7.38.0", + "Accept":"*/*" + }, + "uri":"/?key=value&key=other_value", + "protocol":"GET" + }, + "response":{ + "headers":{ + "Date":"Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type":"text/html" + }, + "body":[ + "no need." + ] + }, + "expected":{ + "debug_log":"Target value: \"US\" \\(Variable: GEO:COUNTRY_CODE\\)" + }, + "rules":[ + "SecRuleEngine On", + "SecDebugLog \/tmp\/modsec_debug.log", + "SecDebugLogLevel 9", + "SecGeoLookupDb test-cases\/data\/geo\/GeoIPCity.dat", + "SecRule REMOTE_ADDR \"@geoLookup\" \"pass,t:trim\"", + "SecRule GEO \"@contains test \" \"pass,t:trim\"" + ] + }, + { + "enabled":1, + "version_min":300000, + "title":"Testing Variables :: GEO:COUNTRY_CONTINENT", + "client":{ + "ip":"64.17.254.216", + "port":123 + }, + "server":{ + "ip":"200.249.12.31", + "port":80 + }, + "request":{ + "headers":{ + "Host":"localhost", + "User-Agent":"curl/7.38.0", + "Accept":"*/*" + }, + "uri":"/?key=value&key=other_value", + "protocol":"GET" + }, + "response":{ + "headers":{ + "Date":"Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type":"text/html" + }, + "body":[ + "no need." + ] + }, + "expected":{ + "debug_log":"Target value: \"NA\" \\(Variable: GEO:COUNTRY_CONTINENT\\)" + }, + "rules":[ + "SecRuleEngine On", + "SecDebugLog \/tmp\/modsec_debug.log", + "SecDebugLogLevel 9", + "SecGeoLookupDb test-cases\/data\/geo\/GeoIPCity.dat", + "SecRule REMOTE_ADDR \"@geoLookup\" \"pass,t:trim\"", + "SecRule GEO \"@contains test \" \"pass,t:trim\"" + ] + }, + { + "enabled":1, + "version_min":300000, + "title":"Testing Variables :: GEO:AREA_CODE", + "client":{ + "ip":"64.17.254.216", + "port":123 + }, + "server":{ + "ip":"200.249.12.31", + "port":80 + }, + "request":{ + "headers":{ + "Host":"localhost", + "User-Agent":"curl/7.38.0", + "Accept":"*/*" + }, + "uri":"/?key=value&key=other_value", + "protocol":"GET" + }, + "response":{ + "headers":{ + "Date":"Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type":"text/html" + }, + "body":[ + "no need." + ] + }, + "expected":{ + "debug_log":"Target value: \"310\" \\(Variable: GEO:AREA_CODE\\)" + }, + "rules":[ + "SecRuleEngine On", + "SecDebugLog \/tmp\/modsec_debug.log", + "SecDebugLogLevel 9", + "SecGeoLookupDb test-cases\/data\/geo\/GeoIPCity.dat", + "SecRule REMOTE_ADDR \"@geoLookup\" \"pass,t:trim\"", + "SecRule GEO \"@contains test \" \"pass,t:trim\"" + ] + }, + { + "enabled":1, + "version_min":300000, + "title":"Testing Variables :: GEO:DMA_CODE", + "client":{ + "ip":"64.17.254.216", + "port":123 + }, + "server":{ + "ip":"200.249.12.31", + "port":80 + }, + "request":{ + "headers":{ + "Host":"localhost", + "User-Agent":"curl/7.38.0", + "Accept":"*/*" + }, + "uri":"/?key=value&key=other_value", + "protocol":"GET" + }, + "response":{ + "headers":{ + "Date":"Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type":"text/html" + }, + "body":[ + "no need." + ] + }, + "expected":{ + "debug_log":"Target value: \"803\" \\(Variable: GEO:DMA_CODE\\)" + }, + "rules":[ + "SecRuleEngine On", + "SecDebugLog \/tmp\/modsec_debug.log", + "SecDebugLogLevel 9", + "SecGeoLookupDb test-cases\/data\/geo\/GeoIPCity.dat", + "SecRule REMOTE_ADDR \"@geoLookup\" \"pass,t:trim\"", + "SecRule GEO \"@contains test \" \"pass,t:trim\"" + ] + }, + { + "enabled":1, + "version_min":300000, + "title":"Testing Variables :: GEO:POSTAL_CODE", + "client":{ + "ip":"64.17.254.216", + "port":123 + }, + "server":{ + "ip":"200.249.12.31", + "port":80 + }, + "request":{ + "headers":{ + "Host":"localhost", + "User-Agent":"curl/7.38.0", + "Accept":"*/*" + }, + "uri":"/?key=value&key=other_value", + "protocol":"GET" + }, + "response":{ + "headers":{ + "Date":"Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type":"text/html" + }, + "body":[ + "no need." + ] + }, + "expected":{ + "debug_log":"Target value: \"90245\" \\(Variable: GEO:POSTAL_CODE\\)" + }, + "rules":[ + "SecRuleEngine On", + "SecDebugLog \/tmp\/modsec_debug.log", + "SecDebugLogLevel 9", + "SecGeoLookupDb test-cases\/data\/geo\/GeoIPCity.dat", + "SecRule REMOTE_ADDR \"@geoLookup\" \"pass,t:trim\"", + "SecRule GEO \"@contains test \" \"pass,t:trim\"" + ] + }, + { + "enabled":1, + "version_min":300000, + "title":"Testing Variables :: GEO:REGION", + "client":{ + "ip":"64.17.254.216", + "port":123 + }, + "server":{ + "ip":"200.249.12.31", + "port":80 + }, + "request":{ + "headers":{ + "Host":"localhost", + "User-Agent":"curl/7.38.0", + "Accept":"*/*" + }, + "uri":"/?key=value&key=other_value", + "protocol":"GET" + }, + "response":{ + "headers":{ + "Date":"Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type":"text/html" + }, + "body":[ + "no need." + ] + }, + "expected":{ + "debug_log":"Target value: \"California\" \\(Variable: GEO:REGION\\)" + }, + "rules":[ + "SecRuleEngine On", + "SecDebugLog \/tmp\/modsec_debug.log", + "SecDebugLogLevel 9", + "SecGeoLookupDb test-cases\/data\/geo\/GeoIPCity.dat", + "SecRule REMOTE_ADDR \"@geoLookup\" \"pass,t:trim\"", + "SecRule GEO \"@contains test \" \"pass,t:trim\"" + ] + }, + { + "enabled":1, + "version_min":300000, + "title":"Testing Variables :: GEO:CITY", + "client":{ + "ip":"64.17.254.216", + "port":123 + }, + "server":{ + "ip":"200.249.12.31", + "port":80 + }, + "request":{ + "headers":{ + "Host":"localhost", + "User-Agent":"curl/7.38.0", + "Accept":"*/*" + }, + "uri":"/?key=value&key=other_value", + "protocol":"GET" + }, + "response":{ + "headers":{ + "Date":"Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type":"text/html" + }, + "body":[ + "no need." + ] + }, + "expected":{ + "debug_log":"Target value: \"El Segundo\" \\(Variable: GEO:CITY\\)" + }, + "rules":[ + "SecRuleEngine On", + "SecDebugLog \/tmp\/modsec_debug.log", + "SecDebugLogLevel 9", + "SecGeoLookupDb test-cases\/data\/geo\/GeoIPCity.dat", + "SecRule REMOTE_ADDR \"@geoLookup\" \"pass,t:trim\"", + "SecRule GEO \"@contains test \" \"pass,t:trim\"" + ] + } +] +