From 76b34af3571586d22093c59056f2517651e3b0fc Mon Sep 17 00:00:00 2001 From: Felipe Zimmerle Date: Thu, 23 Jul 2015 14:36:11 -0300 Subject: [PATCH] Adds support to load remote rules --- build/curl.m4 | 109 ++++++++++++++++++ configure.ac | 13 +++ examples/Makefile.am | 2 +- .../simple_example_using_c/basic_rules.conf | 4 + examples/simple_example_using_c/test.c | 23 +++- headers/modsecurity/rules.h | 17 ++- src/Makefile.am | 15 ++- src/modsecurity.cc | 6 + src/parser/driver.cc | 8 +- src/parser/driver.h | 3 +- src/rules.cc | 106 ++++++++++++----- src/utils/https_client.cc | 106 +++++++++++++++++ src/utils/https_client.h | 55 +++++++++ test/Makefile.am | 45 ++++---- test/benchmark/Makefile.am | 11 +- 15 files changed, 449 insertions(+), 74 deletions(-) create mode 100644 build/curl.m4 create mode 100644 src/utils/https_client.cc create mode 100644 src/utils/https_client.h diff --git a/build/curl.m4 b/build/curl.m4 new file mode 100644 index 00000000..6432124d --- /dev/null +++ b/build/curl.m4 @@ -0,0 +1,109 @@ +dnl Check for CURL Libraries +dnl CHECK_CURL(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]) +dnl Sets: +dnl CURL_CFLAGS +dnl CURL_LIBS + +CURL_CONFIG="" +CURL_VERSION="" +CURL_CPPFLAGS="" +CURL_CFLAGS="" +CURL_LDFLAGS="" +CURL_LDADD="" +CURL_MIN_VERSION="7.15.1" + +AC_DEFUN([CHECK_CURL], +[dnl + +AC_ARG_WITH( + curl, + [AC_HELP_STRING([--with-curl=PATH],[Path to curl prefix or config script])], + [test_paths="${with_curl}"], + [test_paths="/usr/local/libcurl /usr/local/curl /usr/local /opt/libcurl /opt/curl /opt /usr"]) + +AC_MSG_CHECKING([for libcurl 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 + CURL_CONFIG=$x + curl_path="no" + break + fi + + dnl # Try known config script names/locations + for CURL_CONFIG in curl-config; do + if test -e "${x}/bin/${CURL_CONFIG}"; then + curl_path="${x}/bin" + break + elif test -e "${x}/${CURL_CONFIG}"; then + curl_path="${x}" + break + else + curl_path="" + fi + done + if test -n "$curl_path"; then + break + fi +done + +if test -n "${curl_path}"; then + if test "${curl_path}" != "no"; then + CURL_CONFIG="${curl_path}/${CURL_CONFIG}" + fi + AC_MSG_RESULT([${CURL_CONFIG}]) + CURL_VERSION=`${CURL_CONFIG} --version | sed 's/^[[^0-9]][[^[:space:]]][[^[:space:]]]*[[[:space:]]]*//'` + if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(curl VERSION: $CURL_VERSION); fi + CURL_CFLAGS="`${CURL_CONFIG} --cflags`" + if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(curl CFLAGS: $CURL_CFLAGS); fi + CURL_LDADD="`${CURL_CONFIG} --libs`" + if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(curl LDADD: $CURL_LIBS); fi + + dnl # Check version is ok + AC_MSG_CHECKING([if libcurl is at least v${CURL_MIN_VERSION}]) + curl_min_ver=`echo ${CURL_MIN_VERSION} | awk -F. '{print (\$ 1 * 1000000) + (\$ 2 * 1000) + \$ 3}'` + curl_ver=`echo ${CURL_VERSION} | awk -F. '{print (\$ 1 * 1000000) + (\$ 2 * 1000) + \$ 3}'` + if test "$curl_min_ver" -le "$curl_ver"; then + AC_MSG_RESULT([yes, $CURL_VERSION]) + curl_tlsv2_ver=`echo 7.34.0 | awk -F. '{print (\$ 1 * 1000000) + (\$ 2 * 1000) + \$ 3}'` + if test "$curl_tlsv2_ver" -le "$curl_ver"; then + CURL_CFLAGS="${CURL_CFLAGS} -DWITH_CURL_SSLVERSION_TLSv1_2" + fi + CURL_CFLAGS="${CURL_CFLAGS} -DWITH_CURL" + else + AC_MSG_RESULT([no, $CURL_VERSION]) + AC_MSG_NOTICE([NOTE: curl library may be too old]) + fi + + dnl # Check/warn if GnuTLS is used + AC_MSG_CHECKING([if libcurl is linked with gnutls]) + curl_uses_gnutls=`echo ${CURL_LIBS} | grep gnutls | wc -l` + if test "$curl_uses_gnutls" -ne 0; then + AC_MSG_RESULT([yes]) + AC_MSG_NOTICE([NOTE: curl linked with gnutls may be buggy, openssl recommended]) + CURL_USES_GNUTLS=yes + else + AC_MSG_RESULT([no]) + CURL_USES_GNUTLS=no + fi + +else + AC_MSG_RESULT([no]) +fi + +AC_SUBST(CURL_CONFIG) +AC_SUBST(CURL_VERSION) +AC_SUBST(CURL_CPPFLAGS) +AC_SUBST(CURL_CFLAGS) +AC_SUBST(CURL_LDFLAGS) +AC_SUBST(CURL_LDADD) +AC_SUBST(CURL_USES_GNUTLS) + +if test -z "${CURL_VERSION}"; then + AC_MSG_NOTICE([*** curl library not found.]) +else + AC_MSG_NOTICE([using curl v${CURL_VERSION}]) + ifelse([$1], , , $1) +fi +]) diff --git a/configure.ac b/configure.ac index ea53232b..9cd2e907 100644 --- a/configure.ac +++ b/configure.ac @@ -44,6 +44,19 @@ PROG_GEOIP AM_CONDITIONAL([GEOIP_VERSION], [test "$GEOIP_VERSION" != ""]) +# +# Check for curl +# +CHECK_CURL + +if test -z "${CURL_VERSION}"; then + AC_MSG_NOTICE([NOTE: curl was not found. SecRemoteRules support was disabled.]) +else + AC_DEFINE([MSC_WITH_CURL], [1], [Define if libcurl is available]) +fi + + + # Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS([string]) diff --git a/examples/Makefile.am b/examples/Makefile.am index 7279a338..8ebb7e3b 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -11,4 +11,4 @@ CLEANFILES = # make maintainer-clean MAINTAINERCLEANFILES = \ Makefile.in - + diff --git a/examples/simple_example_using_c/basic_rules.conf b/examples/simple_example_using_c/basic_rules.conf index 8021518b..1bc84619 100644 --- a/examples/simple_example_using_c/basic_rules.conf +++ b/examples/simple_example_using_c/basic_rules.conf @@ -1,3 +1,7 @@ +SecRuleEngine On +SecDebugLog /tmp/modsec_debug.log +SecDebugLogLevel 9 + SecRule ARGS:test "@detectSQLi" "allow" SecRule ARGS|ARGS:test "!@contains asdfsafdt" "allow" SecRule ARGS "@detectSQLi" "allow" diff --git a/examples/simple_example_using_c/test.c b/examples/simple_example_using_c/test.c index 80d83150..4f9c5e8f 100644 --- a/examples/simple_example_using_c/test.c +++ b/examples/simple_example_using_c/test.c @@ -24,6 +24,8 @@ char main_rule_uri[] = "basic_rules.conf"; int main (int argc, char **argv) { + int ret = 1; + const char *error = NULL; ModSecurity *modsec = NULL; Assay *assay = NULL; Rules *rules = NULL; @@ -34,7 +36,24 @@ int main (int argc, char **argv) "example on how to use ModSecurity API"); rules = msc_create_rules_set(); - msc_rules_add_file(rules, main_rule_uri); + + ret = msc_rules_add_file(rules, main_rule_uri, &error); + if (ret == 0) { + fprintf(stderr, "Problems loading the rules --\n"); + fprintf(stderr, "%s\n", error); + goto end; + } + msc_rules_dump(rules); + + ret = msc_rules_add_remote(rules, "test", + "https://www.modsecurity.org/modsecurity-regression-test-secremoterules.txt", + &error); + if (ret == 0) { + fprintf(stderr, "Problems loading the rules --\n"); + fprintf(stderr, "%s\n", error); + goto end; + } + msc_rules_dump(rules); assay = msc_new_assay(modsec, rules); @@ -46,7 +65,7 @@ int main (int argc, char **argv) msc_process_request_body(assay); msc_process_response_headers(assay); msc_process_response_body(assay); - +end: msc_rules_cleanup(rules); msc_cleanup(modsec); diff --git a/headers/modsecurity/rules.h b/headers/modsecurity/rules.h index 5218a09f..6e900e4c 100644 --- a/headers/modsecurity/rules.h +++ b/headers/modsecurity/rules.h @@ -66,9 +66,12 @@ class Rules { * names should follow a patterner * */ - int loadFromUri(char *uri); - int loadRemote(char *key, char *uri); - int load(const char *rules); + bool loadFromUri(char *uri); + bool loadRemote(char *key, char *uri); + bool load(const char *rules); + bool load(const char *rules, const std::string &ref); + + void dump(); int merge(Parser::Driver *driver); int merge(Rules *rules); @@ -160,10 +163,12 @@ extern "C" { #endif Rules *msc_create_rules_set(); +void msc_rules_dump(Rules *rules); int msc_rules_merge(Rules *rules_dst, Rules *rules_from); -int msc_rules_add_remote(Rules *rules, char *key, char *uri); -int msc_rules_add_file(Rules *rules, char *file); -int msc_rules_add(Rules *rules, const char *plain_rules); +int msc_rules_add_remote(Rules *rules, char *key, char *uri, + const char **error); +int msc_rules_add_file(Rules *rules, char *file, const char **error); +int msc_rules_add(Rules *rules, const char *plain_rules, const char **error); int msc_rules_cleanup(Rules *rules); #ifdef __cplusplus diff --git a/src/Makefile.am b/src/Makefile.am index 84caf5eb..a18bcb7d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -94,10 +94,13 @@ ACTIONS = \ actions/transformations/url_encode.cc \ actions/transformations/utf8_to_unicode.cc + UTILS = \ - utils/sha1.cc \ + utils/geo_lookup.cc \ + utils/https_client.cc \ utils/md5.cc \ - utils/geo_lookup.cc + utils/sha1.cc + libmodsecurity_la_SOURCES = \ parser/seclang-parser.yy \ @@ -171,9 +174,11 @@ libmodsecurity_la_CPPFLAGS = \ -I ../headers libmodsecurity_la_LIBADD = \ - @LEXLIB@ \ - $(GEOIP_LDADD) \ - $(YAJL_LDADD) + $(CURL_LDADD) \ + $(GEOIP_LDADD) \ + @LEXLIB@ \ + $(YAJL_LDADD) + libmodsecurity_la_LDFLAGS = \ -version-info @MSC_VERSION_INFO@ diff --git a/src/modsecurity.cc b/src/modsecurity.cc index 65d24d3f..5dfc8429 100644 --- a/src/modsecurity.cc +++ b/src/modsecurity.cc @@ -20,6 +20,9 @@ #include "src/config.h" #include "src/unique_id.h" +#ifdef MSC_WITH_CURL +#include +#endif namespace ModSecurity { @@ -42,6 +45,9 @@ ModSecurity::ModSecurity() : m_connector("") { UniqueId::uniqueId(); srand(time(NULL)); +#ifdef MSC_WITH_CURL + curl_global_init(CURL_GLOBAL_ALL); +#endif } diff --git a/src/parser/driver.cc b/src/parser/driver.cc index 82d098cc..0cb24ea6 100644 --- a/src/parser/driver.cc +++ b/src/parser/driver.cc @@ -70,11 +70,12 @@ int Driver::addSecRule(Rule *rule) { } -int Driver::parse(const std::string &f) { +int Driver::parse(const std::string &f, const std::string &ref) { + this->ref = ref; buffer = f; scan_begin(); yy::seclang_parser parser(*this); - parser.set_debug_level(0); + parser.set_debug_level(trace_parsing); int res = parser.parse(); if (audit_log->init() == false) { @@ -87,6 +88,7 @@ int Driver::parse(const std::string &f) { int Driver::parseFile(const std::string &f) { + this->ref = f; file = f; scan_begin(); yy::seclang_parser parser(*this); @@ -106,7 +108,7 @@ void Driver::error(const yy::location& l, const std::string& m, const std::string& c) { if (parserError.tellp() == 0) { parserError << "Parser error, "; - parserError << "Filename: " << file << ". "; + parserError << "File: " << ref << ". "; parserError << "Line: " << l.end.line << ". "; parserError << "Column: " << l.end.column << ". "; } diff --git a/src/parser/driver.h b/src/parser/driver.h index 872ef22e..32f872a1 100644 --- a/src/parser/driver.h +++ b/src/parser/driver.h @@ -71,7 +71,7 @@ class Driver : public Rules { // Run the parser on file F. // Return 0 on success. int parseFile(const std::string& f); - int parse(const std::string& f); + int parse(const std::string& f, const std::string &ref); // The name of the file being parsed. // Used later to pass the file name to the location tracker. @@ -87,6 +87,7 @@ class Driver : public Rules { void error(const yy::location& l, const std::string& m, const std::string& c); + std::string ref; std::string buffer; }; diff --git a/src/rules.cc b/src/rules.cc index 4b9ee159..be358891 100644 --- a/src/rules.cc +++ b/src/rules.cc @@ -25,8 +25,10 @@ #include "modsecurity/assay.h" #include "src/utils.h" #include "parser/driver.h" +#include "utils/https_client.h" using ModSecurity::Parser::Driver; +using ModSecurity::Utils::HttpsClient; namespace ModSecurity { @@ -75,6 +77,11 @@ void Rules::decrementReferenceCount(void) { } +Rules::~Rules() { + // audit_log->refCountDecreaseAndCheck(); +} + + /** * @name loadFromUri * @brief load rules from a give uri @@ -90,11 +97,14 @@ void Rules::decrementReferenceCount(void) { * @retval false Problem loading the rules. * */ -int Rules::loadFromUri(char *uri) { - std::cout << "Loading rules from: " << uri << std::endl; - +bool Rules::loadFromUri(char *uri) { Driver *driver = new Driver(); - driver->parse(uri); + + if (driver->parseFile(uri) == false) { + parserError << driver->parserError.rdbuf(); + return false; + } + this->merge(driver); delete driver; @@ -102,24 +112,30 @@ int Rules::loadFromUri(char *uri) { } -Rules::~Rules() { - // audit_log->refCountDecreaseAndCheck(); -} +bool Rules::loadRemote(char *key, char *uri) { + HttpsClient client; + bool ret = client.download(uri); - -int Rules::loadRemote(char *key, char *uri) { - return true; -} - - -int Rules::load(const char *plain_rules) { - Driver *driver = new Driver(); - - if (driver->parse(plain_rules) == false) { - parserError << driver->parserError.rdbuf(); - return false; + if (ret) { + return this->load(client.content.c_str(), uri); } + return false; +} + + +bool Rules::load(const char *plain_rules) { + return this->load(plain_rules, ""); +} + + +bool Rules::load(const char *plain_rules, const std::string &ref) { + Driver *driver = new Driver(); + + if (driver->parse(plain_rules, ref) == false) { + parserError << driver->parserError.str(); + return false; + } this->merge(driver); delete driver; @@ -225,6 +241,21 @@ int Rules::merge(Rules *from) { } +void Rules::dump() { + std::cout << "Rules: " << std::endl; + for (int i = 0; i < ModSecurity::Phases::NUMBER_OF_PHASES; i++) { + std::vector rules = this->rules[i]; + std::cout << "Phase: " << std::to_string(i); + std::cout << " (" << std::to_string(rules.size()); + std::cout << " rules)" << std::endl; + for (int j = 0; j < rules.size(); j++) { + std::cout << " Rule ID: " << std::to_string(rules[j]->rule_id); + std::cout << std::endl; + } + } +} + + extern "C" Rules *msc_create_rules_set() { Rules *rules = new Rules(); @@ -232,6 +263,11 @@ extern "C" Rules *msc_create_rules_set() { } +extern "C" void msc_rules_dump(Rules *rules) { + rules->dump(); +} + + extern "C" int msc_rules_merge(Rules *rules_dst, Rules *rules_from) { rules_dst->merge(rules_from); @@ -241,24 +277,32 @@ extern "C" int msc_rules_merge(Rules *rules_dst, extern "C" int msc_rules_add_remote(Rules *rules, - char *key, char *uri) { - rules->loadRemote(key, uri); - - return 0; + char *key, char *uri, const char **error) { + int ret = rules->loadRemote(key, uri); + if (ret == 0) { + *error = rules->getParserError().c_str(); + } + return ret; } -extern "C" int msc_rules_add_file(Rules *rules, char *file) { - rules->loadFromUri(file); - - return 0; +extern "C" int msc_rules_add_file(Rules *rules, char *file, + const char **error) { + int ret = rules->loadFromUri(file); + if (ret == 0) { + *error = rules->getParserError().c_str(); + } + return ret; } -extern "C" int msc_rules_add(Rules *rules, const char *plain_rules) { - rules->load(plain_rules); - - return 0; +extern "C" int msc_rules_add(Rules *rules, const char *plain_rules, + const char **error) { + int ret = rules->load(plain_rules); + if (ret == 0) { + *error = rules->getParserError().c_str(); + } + return ret; } diff --git a/src/utils/https_client.cc b/src/utils/https_client.cc new file mode 100644 index 00000000..2fb48905 --- /dev/null +++ b/src/utils/https_client.cc @@ -0,0 +1,106 @@ +/* + * 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 "utils/https_client.h" +#include "src/config.h" + +#ifdef MSC_WITH_CURL +#include +#endif + +#include +#include +#include +#include +#include + +#include +#include + +#include "src/unique_id.h" + +namespace ModSecurity { +namespace Utils { + + +size_t HttpsClient::handle(char * data, size_t size, size_t nmemb, void * p) { + return static_cast(p)->handle_impl(data, size, nmemb); +} + + +size_t HttpsClient::handle_impl(char* data, size_t size, size_t nmemb) { + content.append(data, size * nmemb); + return size * nmemb; +} + + +#ifdef MSC_WITH_CURL +bool HttpsClient::download(const std::string &uri) { + CURL *curl; + CURLcode res; + std::string uniqueId = "ModSec-unique-id: " + UniqueId::uniqueId(); + + curl = curl_easy_init(); + if (!curl) { + error = "Not able to initialize libcurl"; + return false; + } + + struct curl_slist *headers_chunk = NULL; + curl_easy_setopt(curl, CURLOPT_URL, uri.c_str()); + + headers_chunk = curl_slist_append(headers_chunk, uniqueId.c_str()); + + /* Make it TLS 1.x only. */ + curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); + + /* those are the default options, but lets make sure */ + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 1); + + /* send all data to this function */ + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &HttpsClient::handle); + + /* we pass our 'chunk' struct to the callback function */ + curl_easy_setopt(curl, CURLOPT_WRITEDATA, this); + + curl_easy_setopt(curl, CURLOPT_USERAGENT, "modesecurity3"); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers_chunk); + + /* We want Curl to return error in case there is an HTTP error code */ + curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1); + + res = curl_easy_perform(curl); + + curl_slist_free_all(headers_chunk); + + if (res != CURLE_OK) { + error = curl_easy_strerror(res); + } + + curl_easy_cleanup(curl); + + return res == CURLE_OK; +} +#else +bool HttpsClient::download(const std::string &uri) { + error = "Not compiled with libcurl support"; + return false; +} +#endif + +} // namespace Utils +} // namespace ModSecurity + diff --git a/src/utils/https_client.h b/src/utils/https_client.h new file mode 100644 index 00000000..bb43d562 --- /dev/null +++ b/src/utils/https_client.h @@ -0,0 +1,55 @@ +/* + * 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 MSC_WITH_CURL +#include +#endif + +#include +#include +#include +#include + +#include + +#ifndef SRC_UTILS_HTTPS_CLIENT_H_ +#define SRC_UTILS_HTTPS_CLIENT_H_ + +#include "modsecurity/assay.h" + +namespace ModSecurity { +namespace Utils { + + +class HttpsClient { + public: + HttpsClient() + : content(""), + error("") { } + + bool download(const std::string &uri); + std::string content; + + static size_t handle(char * data, size_t size, size_t nmemb, void * p); + size_t handle_impl(char * data, size_t size, size_t nmemb); + + std::string error; +}; + + +} // namespace Utils +} // namespace ModSecurity + +#endif // SRC_UTILS_HTTPS_CLIENT_H_ diff --git a/test/Makefile.am b/test/Makefile.am index 001f3ee6..c9221a26 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -16,6 +16,7 @@ MAINTAINERCLEANFILES = \ bin_PROGRAMS = unit-tests regression-tests + # unit_tests unit_tests_SOURCES = \ @@ -23,18 +24,20 @@ unit_tests_SOURCES = \ unit/unit_test.cc unit_tests_LDADD = \ - $(top_builddir)/src/.libs/libmodsecurity.a \ - $(GEOIP_LDADD) \ - $(YAJL_LDADD) + $(top_builddir)/src/.libs/libmodsecurity.a \ + $(CURL_LDADD) \ + $(GEOIP_LDADD) \ + $(YAJL_LDADD) unit_tests_CPPFLAGS = \ - -std=c++11 \ - -Icommon \ - -O0 \ - -g \ - -I$(top_builddir)/headers \ - $(GEOIP_CFLAGS) \ - $(YAJL_CFLAGS) + -std=c++11 \ + -Icommon \ + -O0 \ + -g \ + -I$(top_builddir)/headers \ + $(CURL_CFLAGS) \ + $(GEOIP_CFLAGS) \ + $(YAJL_CFLAGS) # regression @@ -45,15 +48,17 @@ regression_tests_SOURCES = \ regression/custom_debug_log.cc regression_tests_LDADD = \ - $(top_builddir)/src/.libs/libmodsecurity.a \ - $(GEOIP_LDADD) \ - $(YAJL_LDADD) + $(top_builddir)/src/.libs/libmodsecurity.a \ + $(CURL_LDADD) \ + $(GEOIP_LDADD) \ + $(YAJL_LDADD) regression_tests_CPPFLAGS = \ - -std=c++11 \ - -Icommon \ - -O0 \ - -g \ - -I$(top_builddir)/headers \ - $(GEOIP_CFLAGS) \ - $(YAJL_CFLAGS) + -std=c++11 \ + -Icommon \ + -O0 \ + -g \ + -I$(top_builddir)/headers \ + $(CURL_CFLAGS) \ + $(GEOIP_CFLAGS) \ + $(YAJL_CFLAGS) diff --git a/test/benchmark/Makefile.am b/test/benchmark/Makefile.am index 23e4356e..11edcaa7 100644 --- a/test/benchmark/Makefile.am +++ b/test/benchmark/Makefile.am @@ -6,13 +6,14 @@ benchmark_SOURCES = \ benchmark.cc benchmark_LDADD = \ - $(top_builddir)/src/.libs/libmodsecurity.a \ - $(GEOIP_LDADD) \ - $(YAJL_LDADD) + $(top_builddir)/src/.libs/libmodsecurity.a \ + $(CURL_LDADD) \ + $(GEOIP_LDADD) \ + $(YAJL_LDADD) benchmark_CPPFLAGS = \ - -std=c++11 \ - -I$(top_builddir)/headers + -std=c++11 \ + -I$(top_builddir)/headers MAINTAINERCLEANFILES = \ Makefile.in