diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b081fb93bd..158317124c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -178,7 +178,7 @@ jobs: - name: Setup Dependencies run: | sudo apt-get update -y -qq - sudo apt-get install -y cppcheck + sudo apt-get install -y cppcheck libyajl-dev - name: Get libModSecurity v3 source uses: actions/checkout@v4 with: diff --git a/.gitignore b/.gitignore index be0de1557c..e61c1ed6c5 100644 --- a/.gitignore +++ b/.gitignore @@ -18,7 +18,7 @@ config.guess config.log config.status config.sub -config.h.in~ +src/config.h.in~ configure configure~ depcomp diff --git a/Makefile.am b/Makefile.am index 5983c7c47e..955080b088 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,5 @@ -if TEST_UTILITIES export MAYBE_TEST = test -endif if EXAMPLES export MAYBE_EXAMPLES = examples diff --git a/README.md b/README.md index 99a664a7ae..4d22815dfd 100644 --- a/README.md +++ b/README.md @@ -75,15 +75,25 @@ Windows build information can be found [here](build/win32/README.md). ## Dependencies -This library is written in C++ using the C++17 standards. It also uses Flex -and Yacc to produce the “Sec Rules Language” parser. Other, mandatory dependencies include YAJL, as ModSecurity uses JSON for producing logs and its testing framework, libpcre (not yet mandatory) for processing regular expressions in SecRules, and libXML2 (not yet mandatory) which is used for parsing XML requests. +This library is written in C++ using the C++17 standard. -All others dependencies are related to operators specified within SecRules or configuration directives and may not be required for compilation. A short list of such dependencies is as follows: +The following dependencies are used to build libModSecurity: -* libinjection is needed for the operator @detectXSS and @detectSQL -* curl is needed for the directive SecRemoteRules. + * Flex and Yacc to produce the “Sec Rules Language” parser. + * YAJL, as ModSecurity uses JSON for producing logs and its testing framework. + * PCRE or PCRE2 for processing regular expressions in SecRules. + * libinjection for the operators [@detectXSS](../../wiki/Reference-Manual-(v3.x)#detectxss) and [@detectSQL](../../wiki/Reference-Manual-(v3.x)#detectsqli). + * Mbed TLS for basic encoding/hashing functions (base64, md5 & sha1). -If those libraries are missing ModSecurity will be compiled without the support for the operator @detectXSS and the configuration directive SecRemoteRules. +All others dependencies are related to operators specified within SecRules or configuration directives and may not be required for compilation. If those libraries are missing ModSecurity will be compiled without the support for the associated operator or configuration directive. + +A short list of such dependencies is as follows: + + * libXML2 which for parsing XML requests. + * curl is needed for the directive [SecRemoteRules](../../wiki/Reference-Manual-(v3.x)#user-content-SecRemoteRules). + * LUA is needed for the directive [SecRuleScript](../../wiki/Reference-Manual-(v3.x)#secrulescript). + * GeoIP/MaxMind to perform geolocation lookups using operator [geoLookup](../../wiki/Reference-Manual-(v3.x)%29#geolookup) + * ssdeep is needed for the operator [fuzzyHash](../../wiki/Reference-Manual-(v3.x)%29#fuzzyhash). # Library documentation diff --git a/build/yajl.m4 b/build/yajl.m4 index dd69571562..30ed3f7e9f 100644 --- a/build/yajl.m4 +++ b/build/yajl.m4 @@ -1,7 +1,7 @@ dnl Check for YAJL Libraries dnl CHECK_YAJL(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]) -AC_DEFUN([PROG_YAJL], [ +AC_DEFUN([CHECK_YAJL], [ # Possible names for the yajl library/package (pkg-config) YAJL_POSSIBLE_LIB_NAMES="yajl2 yajl" @@ -24,80 +24,52 @@ AC_ARG_WITH( [AS_HELP_STRING([--with-yajl=PATH],[Path to yajl prefix or config script])] ) -if test "x${with_yajl}" == "xno"; then - AC_DEFINE(HAVE_YAJL, 0, [Support for YAJL was disabled by the utilization of --without-yajl or --with-yajl=no]) - AC_MSG_NOTICE([Support for YAJL was disabled by the utilization of --without-yajl or --with-yajl=no]) - YAJL_DISABLED=yes -else - if test "x${with_yajl}" == "xyes"; then - YAJL_MANDATORY=yes - AC_MSG_NOTICE([YAJL support was marked as mandatory by the utilization of --with-yajl=yes]) - fi -# for x in ${YAJL_POSSIBLE_LIB_NAMES}; do -# CHECK_FOR_YAJL_AT(${x}) -# if test -n "${YAJL_VERSION}"; then -# break -# fi -# done - -# if test "x${with_yajl}" != "xyes" or test "x${with_yajl}" == "xyes"; then - if test "x${with_yajl}" == "x" || test "x${with_yajl}" == "xyes"; then - # Nothing about YAJL was informed, using the pkg-config to figure things out. - if test -n "${PKG_CONFIG}"; then - YAJL_PKG_NAME="" - for x in ${YAJL_POSSIBLE_LIB_NAMES}; do - if ${PKG_CONFIG} --exists ${x}; then - YAJL_PKG_NAME="$x" - break - fi - done +YAJL_MANDATORY=yes +AC_MSG_NOTICE([YAJL is mandatory]) + + +if test "x${with_yajl}" == "x" || test "x${with_yajl}" == "xyes"; then + # Nothing about YAJL was informed, using the pkg-config to figure things out. + if test -n "${PKG_CONFIG}"; then + YAJL_PKG_NAME="" + for x in ${YAJL_POSSIBLE_LIB_NAMES}; do + if ${PKG_CONFIG} --exists ${x}; then + YAJL_PKG_NAME="$x" + break fi - AC_MSG_NOTICE([Nothing about YAJL was informed during the configure phase. Trying to detect it on the platform...]) - if test -n "${YAJL_PKG_NAME}"; then - # Package was found using the pkg-config scripts - YAJL_VERSION="`${PKG_CONFIG} ${YAJL_PKG_NAME} --modversion`" - YAJL_CFLAGS="`${PKG_CONFIG} ${YAJL_PKG_NAME} --cflags`" - YAJL_LDADD="`${PKG_CONFIG} ${YAJL_PKG_NAME} --libs-only-l`" - YAJL_LDFLAGS="`${PKG_CONFIG} ${YAJL_PKG_NAME} --libs-only-L --libs-only-other`" - YAJL_DISPLAY="${YAJL_LDADD}, ${YAJL_CFLAGS}" - else - # If pkg-config did not find anything useful, go over file lookup. - for x in ${YAJL_POSSIBLE_LIB_NAMES}; do - CHECK_FOR_YAJL_AT(${x}) - if test -n "${YAJL_VERSION}"; then - break - fi - done + done + fi + AC_MSG_NOTICE([Nothing about YAJL was informed during the configure phase. Trying to detect it on the platform...]) + if test -n "${YAJL_PKG_NAME}"; then + # Package was found using the pkg-config scripts + YAJL_VERSION="`${PKG_CONFIG} ${YAJL_PKG_NAME} --modversion`" + YAJL_CFLAGS="`${PKG_CONFIG} ${YAJL_PKG_NAME} --cflags`" + YAJL_LDADD="`${PKG_CONFIG} ${YAJL_PKG_NAME} --libs-only-l`" + YAJL_LDFLAGS="`${PKG_CONFIG} ${YAJL_PKG_NAME} --libs-only-L --libs-only-other`" + else + # If pkg-config did not find anything useful, go over file lookup. + for x in ${YAJL_POSSIBLE_PATHS}; do + CHECK_FOR_YAJL_AT(${x}) + if test -n "${YAJL_LDADD}"; then + break fi - fi - if test "x${with_yajl}" != "x"; then - # An specific path was informed, lets check. - YAJL_MANDATORY=yes - CHECK_FOR_YAJL_AT(${with_yajl}) - fi -# fi + done + fi +elif test "x${with_yajl}" != "x"; then + # A specific path was informed, let's check. + CHECK_FOR_YAJL_AT(${with_yajl}) fi if test -z "${YAJL_LDADD}"; then - if test -z "${YAJL_MANDATORY}"; then - if test -z "${YAJL_DISABLED}"; then - AC_MSG_NOTICE([YAJL library was not found]) - YAJL_FOUND=0 - else - YAJL_FOUND=2 - fi - else - AC_MSG_ERROR([YAJL was explicitly referenced but it was not found]) - YAJL_FOUND=-1 - fi + AC_MSG_ERROR([YAJL is mandatory but it was not found]) + YAJL_FOUND=-1 else YAJL_FOUND=1 AC_MSG_NOTICE([using YAJL v${YAJL_VERSION}]) - YAJL_CFLAGS="-DWITH_YAJL ${YAJL_CFLAGS}" + YAJL_CFLAGS="${YAJL_CFLAGS}" YAJL_DISPLAY="${YAJL_LDADD}, ${YAJL_CFLAGS}" AC_SUBST(YAJL_VERSION) AC_SUBST(YAJL_LDADD) - AC_SUBST(YAJL_LIBS) AC_SUBST(YAJL_LDFLAGS) AC_SUBST(YAJL_CFLAGS) AC_SUBST(YAJL_DISPLAY) @@ -107,7 +79,7 @@ fi AC_SUBST(YAJL_FOUND) -]) # AC_DEFUN [PROG_YAJL] +]) # AC_DEFUN [CHECK_YAJL] AC_DEFUN([CHECK_FOR_YAJL_AT], [ @@ -164,6 +136,5 @@ AC_DEFUN([CHECK_FOR_YAJL_AT], [ YAJL_CFLAGS="-I${yajl_inc_path}" YAJL_LDADD="-l${yajl_lib_name}" YAJL_LDFLAGS="-L${yajl_lib_path}" - YAJL_DISPLAY="${yajl_lib_file}, ${yajl_inc_path}" fi ]) # AC_DEFUN [CHECK_FOR_YAJL_AT] diff --git a/configure.ac b/configure.ac index d8636036b9..20a6b6f58a 100644 --- a/configure.ac +++ b/configure.ac @@ -81,9 +81,7 @@ AC_DEFUN([SECLANG_TEST_VERSION], m4_esyscmd_s(cd "test/test-cases/secrules-langu # Check for yajl -PROG_YAJL - -AM_CONDITIONAL([YAJL_VERSION], [test "$YAJL_VERSION" != ""]) +CHECK_YAJL # Check for LibGeoIP PROG_GEOIP @@ -318,24 +316,9 @@ if test $buildParser = true; then fi fi - -# Decide if we want to build the tests or not. -buildTestUtilities=false -if test "x$YAJL_FOUND" = "x1"; then - # Regression tests will not be able to run without the logging support. - # But we still have the unit tests. - # if test "$debugLogs" = "true"; then - buildTestUtilities=true - # fi -fi - - -AM_CONDITIONAL([TEST_UTILITIES], [test $buildTestUtilities = true]) -if test $buildTestUtilities = true; then - if test $debugLogs = true; then - if test -f ./test/test-list.sh; then - TEST_CASES=`./test/test-list.sh` - fi +if test $debugLogs = true; then + if test -f ./test/test-list.sh; then + TEST_CASES=`./test/test-list.sh` fi fi @@ -374,8 +357,7 @@ AC_CONFIG_FILES([\ tools/rules-check/Makefile ]) -AM_COND_IF([TEST_UTILITIES], - [AC_CONFIG_FILES([test/Makefile test/benchmark/Makefile])]) +AC_CONFIG_FILES([test/Makefile test/benchmark/Makefile]) AM_COND_IF([EXAMPLES], [AC_CONFIG_FILES([ \ @@ -423,6 +405,16 @@ echo " " echo "ModSecurity - ${MSC_GIT_VERSION} for $PLATFORM" echo " " echo " Mandatory dependencies" + +## YAJL +AS_ECHO_N(" + YAJL ....") +if ! test "x$YAJL_VERSION" = "x"; then + echo "v${YAJL_VERSION}" +else + echo "" +fi +echo " ${YAJL_DISPLAY}" + AS_ECHO_N(" + libInjection ....") echo LIBINJECTION_VERSION AS_ECHO_N(" + SecLang tests ....") @@ -472,24 +464,6 @@ if test "x$CURL_FOUND" = "x2"; then fi -## YAJL -if test "x$YAJL_FOUND" = "x0"; then - echo " + YAJL ....not found" -fi -if test "x$YAJL_FOUND" = "x1"; then - AS_ECHO_N(" + YAJL ....found ") - if ! test "x$YAJL_VERSION" = "x"; then - echo "v${YAJL_VERSION}" - else - echo "" - fi - echo " ${YAJL_DISPLAY}" -fi -if test "x$YAJL_FOUND" = "x2"; then - echo " + YAJL ....disabled" -fi - - ## LMDB if test "x$LMDB_FOUND" = "x0"; then echo " + LMDB ....not found" @@ -580,14 +554,10 @@ fi echo " " echo " Other Options" -if test $buildTestUtilities = true; then - if test $debugLogs = true; then - echo " + Test Utilities ....enabled" - else - echo " + Test Utilities ....partially" - fi +if test $debugLogs = true; then + echo " + Test Utilities ....enabled" else - echo " + Test Utilities ....disabled" + echo " + Test Utilities ....partially" fi if test $debugLogs = true; then echo " + SecDebugLog ....enabled" diff --git a/src/modsecurity.cc b/src/modsecurity.cc index 7319bb9699..a2494e5bcd 100644 --- a/src/modsecurity.cc +++ b/src/modsecurity.cc @@ -17,10 +17,8 @@ #include "modsecurity/modsecurity.h" #include "src/config.h" -#ifdef WITH_YAJL #include #include -#endif #ifdef WITH_LIBXML2 #include #include @@ -222,7 +220,6 @@ void ModSecurity::serverLog(void *data, std::shared_ptr rm) { int ModSecurity::processContentOffset(const char *content, size_t len, const char *matchString, std::string *json, const char **err) { -#ifdef WITH_YAJL Utils::Regex variables("v([0-9]+),([0-9]+)"); Utils::Regex operators("o([0-9]+),([0-9]+)"); Utils::Regex transformations("t:(?:(?!t:).)+"); @@ -389,10 +386,6 @@ int ModSecurity::processContentOffset(const char *content, size_t len, yajl_gen_free(g); return 0; -#else - *err = "Without YAJL support, we cannot generate JSON."; - return -1; -#endif } diff --git a/src/request_body_processor/json.cc b/src/request_body_processor/json.cc index 585976b48a..f386cd7c62 100644 --- a/src/request_body_processor/json.cc +++ b/src/request_body_processor/json.cc @@ -14,8 +14,6 @@ */ -#ifdef WITH_YAJL - #include "src/request_body_processor/json.h" #include @@ -314,7 +312,3 @@ int JSON::yajl_end_map(void *ctx) { } // namespace RequestBodyProcessor } // namespace modsecurity - - -#endif // WITH_YAJL - diff --git a/src/request_body_processor/json.h b/src/request_body_processor/json.h index 19c469ee9f..3fb174b691 100644 --- a/src/request_body_processor/json.h +++ b/src/request_body_processor/json.h @@ -17,8 +17,6 @@ #define SRC_REQUEST_BODY_PROCESSOR_JSON_H_ -#ifdef WITH_YAJL - #include #include @@ -122,7 +120,5 @@ class JSON { } // namespace RequestBodyProcessor } // namespace modsecurity -#endif // WITH_YAJL - #endif // SRC_REQUEST_BODY_PROCESSOR_JSON_H_ diff --git a/src/transaction.cc b/src/transaction.cc index a076212571..cacb80ee01 100644 --- a/src/transaction.cc +++ b/src/transaction.cc @@ -15,10 +15,8 @@ #include "modsecurity/transaction.h" -#ifdef WITH_YAJL #include #include -#endif #include #include @@ -38,9 +36,7 @@ #include "modsecurity/modsecurity.h" #include "src/request_body_processor/multipart.h" #include "src/request_body_processor/xml.h" -#ifdef WITH_YAJL #include "src/request_body_processor/json.h" -#endif #include "modsecurity/audit_log.h" #include "src/unique_id.h" #include "src/utils/string.h" @@ -145,11 +141,7 @@ Transaction::Transaction(ModSecurity *ms, RulesSet *rules, void *logCbData) #else m_xml(NULL), #endif -#ifdef WITH_YAJL m_json(new RequestBodyProcessor::JSON(this)), -#else - m_json(NULL), -#endif m_secRuleEngine(RulesSetProperties::PropertyNotSetRuleEngine), m_variableDuration(""), m_variableEnvs(), @@ -221,11 +213,7 @@ Transaction::Transaction(ModSecurity *ms, RulesSet *rules, char *id, void *logCb #else m_xml(NULL), #endif -#ifdef WITH_YAJL m_json(new RequestBodyProcessor::JSON(this)), -#else - m_json(NULL), -#endif m_secRuleEngine(RulesSetProperties::PropertyNotSetRuleEngine), m_variableDuration(""), m_variableEnvs(), @@ -264,9 +252,7 @@ Transaction::~Transaction() { intervention::free(&m_it); intervention::clean(&m_it); -#ifdef WITH_YAJL delete m_json; -#endif #ifdef WITH_LIBXML2 delete m_xml; #endif @@ -847,7 +833,6 @@ int Transaction::processRequestBody() { } } #endif -#if WITH_YAJL #ifdef WITH_LIBXML2 } else if (m_requestBodyProcessor == JSONRequestBody) { #else @@ -877,12 +862,7 @@ int Transaction::processRequestBody() { m_variableReqbodyProcessorError.set("0", m_variableOffset); } } -#endif -#if defined(WITH_LIBXML2) or defined(WITH_YAJL) } else if (m_requestBodyType == MultiPartRequestBody) { -#else - if (m_requestBodyType == MultiPartRequestBody) { -#endif std::string error; int reqbodyNoFilesLength = 0; if (a != NULL) { @@ -1666,7 +1646,6 @@ std::string Transaction::toOldAuditLogFormat(int parts, std::string Transaction::toJSON(int parts) { -#ifdef WITH_YAJL const unsigned char *buf; size_t len; yajl_gen g; @@ -1852,10 +1831,6 @@ std::string Transaction::toJSON(int parts) { yajl_gen_free(g); return log; -#else - return std::string("{\"error\":\"ModSecurity was " \ - "not compiled with JSON support.\"}"); -#endif } diff --git a/test/common/modsecurity_test.cc b/test/common/modsecurity_test.cc index 227571919b..698c8f9a63 100644 --- a/test/common/modsecurity_test.cc +++ b/test/common/modsecurity_test.cc @@ -15,9 +15,7 @@ #include "test/common/modsecurity_test.h" -#ifdef WITH_YAJL #include -#endif #include #include #include