Makes Curl no longer a mandatory depedency for ModSecurity core

As reported by Rainer Jung, Curl may not be mandatory to build
	ModSecurity core. This patch make it optional by:
	- Concentrate all downloads using curl on msc_remote_rules.c
	- Split Curl build definitions checks into: WITH_CURL, WITH_REMOTE_RULES
	and WITH_CRYPTO.
	  - WITH_CURL: Contains Culr headers and binaries during the build time.
	  - WITH_REMOTE_RULES: Currently enabled if Curl is present.
	  - WITH_CRYPTO: Set if apr tool was compiled with crypto support.
	- Renames msc_remote_grab_content to msc_remote_download_content
This commit is contained in:
Felipe Zimmerle 2014-11-26 11:14:34 -08:00
parent 94fd570e31
commit 23823bb2c3
12 changed files with 180 additions and 275 deletions

View File

@ -1,3 +1,9 @@
DD mmm YYYY - 2.9.????? (To be released)
-----------------------
* Curl is not a mandatory dependency to ModSecurity core anymore.
[Rainer Jung and ModSecurity team]
18 Nov 2014 - 2.9.0-RC1
-----------------------

View File

@ -2239,7 +2239,7 @@ static const char *cmd_remote_rules(cmd_parms *cmd, void *_dcfg, const char *p1,
{
char *error_msg = NULL;
directory_config *dcfg = (directory_config *)_dcfg;
#ifdef WITH_REMOTE_RULES_SUPPORT
#ifdef WITH_REMOTE_RULES
int crypto = 0;
const char *uri = p2;
const char *key = p1;
@ -2247,12 +2247,18 @@ static const char *cmd_remote_rules(cmd_parms *cmd, void *_dcfg, const char *p1,
if (dcfg == NULL) return NULL;
#ifdef WITH_REMOTE_RULES_SUPPORT
#ifdef WITH_REMOTE_RULES
if (strncasecmp(p1, "crypto", 6) == 0)
{
#ifdef WITH_APU_CRYPTO
uri = p3;
key = p2;
crypto = 1;
#else
return apr_psprintf(cmd->pool, "ModSecurity: SecRemoteRule using " \
"`crypto' but ModSecurity was not compiled with crypto " \
"support.");
#endif
}
if (uri == NULL || key == NULL)
@ -2269,14 +2275,14 @@ static const char *cmd_remote_rules(cmd_parms *cmd, void *_dcfg, const char *p1,
// FIXME: Should we handle more then one server at once?
if (remote_rules_server != NULL)
{
return apr_psprintf(cmd->pool, "ModSecurity: " \
return apr_psprintf(cmd->pool, "ModSecurity: " \
"SecRemoteRules cannot be used more than once.");
}
remote_rules_server = apr_pcalloc(cmd->pool, sizeof(msc_remote_rules_server));
if (remote_rules_server == NULL)
{
return apr_psprintf(cmd->pool, "ModSecurity: " \
return apr_psprintf(cmd->pool, "ModSecurity: " \
"SecRemoteRules: Internal failure. Not enougth memory.");
}
@ -2293,8 +2299,8 @@ static const char *cmd_remote_rules(cmd_parms *cmd, void *_dcfg, const char *p1,
return error_msg;
}
#else
return apr_psprintf(cmd->pool, "ModSecurity: " \
"SecRemoteRules: ModSecurity was not compiled with such functionality.");
return apr_psprintf(cmd->pool, "ModSecurity: SecRemoteRules: " \
"ModSecurity was not compiled with SecRemoteRules support.");
#endif
return NULL;

View File

@ -68,7 +68,7 @@ unsigned long int DSOLOCAL msc_pcre_match_limit = 0;
unsigned long int DSOLOCAL msc_pcre_match_limit_recursion = 0;
#ifdef WITH_REMOTE_RULES_SUPPORT
#ifdef WITH_REMOTE_RULES
msc_remote_rules_server DSOLOCAL *remote_rules_server = NULL;
#endif
int DSOLOCAL remote_rules_fail_action = REMOTE_RULES_ABORT_ON_FAIL;
@ -761,7 +761,7 @@ static int hook_post_config(apr_pool_t *mp, apr_pool_t *mp_log, apr_pool_t *mp_t
}
#endif
#ifdef WITH_REMOTE_RULES_SUPPORT
#ifdef WITH_REMOTE_RULES
if (remote_rules_server != NULL)
{
if (remote_rules_server->amount_of_rules == 1)

View File

@ -146,7 +146,7 @@ extern DSOLOCAL unsigned long int msc_pcre_match_limit;
extern DSOLOCAL unsigned long int msc_pcre_match_limit_recursion;
#ifdef WITH_REMOTE_RULES_SUPPORT
#ifdef WITH_REMOTE_RULES
extern DSOLOCAL msc_remote_rules_server *remote_rules_server;
#endif
extern DSOLOCAL int remote_rules_fail_action;

View File

@ -16,17 +16,22 @@
#include "msc_status_engine.h"
#include <apr_thread_pool.h>
#ifdef WITH_CURL
#include <curl/curl.h>
#endif
#include <apu.h>
#ifdef WITH_REMOTE_RULES
#include <apr_crypto.h>
#include <apr_sha1.h>
#endif
#ifndef AP_MAX_ARGC
#define AP_MAX_ARGC 64
#endif
#ifdef WITH_REMOTE_RULES_SUPPORT
/**
* @brief Insert a new SecRule to be processed by ModSecurity
@ -201,6 +206,7 @@ const char *msc_remote_invoke_cmd(const command_rec *cmd, cmd_parms *parms,
NULL);
}
}
/**
* @brief Fetch an URL and fill the content into a memory buffer.
*
@ -225,11 +231,14 @@ const char *msc_remote_invoke_cmd(const command_rec *cmd, cmd_parms *parms,
*
* @retval n>=0 everything went fine.
* @retval n<-1 Something wrong happened, further details on error_msg.
* n=-2 Download failed, but operation should not be aborted.
* n=-3 ModSecurity was not compiled with curl support.
*
*/
int msc_remote_grab_content(apr_pool_t *mp, const char *uri, const char *key,
int msc_remote_download_content(apr_pool_t *mp, const char *uri, const char *key,
struct msc_curl_memory_buffer_t *chunk, char **error_msg)
{
#ifdef WITH_CURL
CURL *curl;
CURLcode res;
@ -237,9 +246,10 @@ int msc_remote_grab_content(apr_pool_t *mp, const char *uri, const char *key,
char *apr_id = NULL;
char *beacon_str = NULL;
char *beacon_apr = NULL;
char *header_key = NULL;
int beacon_str_len = 0;
chunk->size = 0;
memset(id, '\0', sizeof(id));
if (msc_status_engine_unique_id(id))
{
@ -266,11 +276,6 @@ int msc_remote_grab_content(apr_pool_t *mp, const char *uri, const char *key,
free(beacon_str);
}
if (key != NULL)
{
header_key = apr_psprintf(mp, "ModSec-key: %s", key);
}
if (curl)
{
struct curl_slist *headers_chunk = NULL;
@ -279,12 +284,14 @@ int msc_remote_grab_content(apr_pool_t *mp, const char *uri, const char *key,
char *ptr = NULL;
DWORD res_len;
#endif
curl_easy_setopt(curl, CURLOPT_URL, remote_rules_server->uri);
curl_easy_setopt(curl, CURLOPT_URL, uri);
headers_chunk = curl_slist_append(headers_chunk, apr_id);
headers_chunk = curl_slist_append(headers_chunk, beacon_apr);
if (key != NULL)
{
char *header_key = NULL;
header_key = apr_psprintf(mp, "ModSec-key: %s", key);
headers_chunk = curl_slist_append(headers_chunk, header_key);
}
@ -321,17 +328,19 @@ int msc_remote_grab_content(apr_pool_t *mp, const char *uri, const char *key,
if (remote_rules_fail_action == REMOTE_RULES_WARN_ON_FAIL)
{
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL,
"Failed to fetch \"%s\" error: %s ",
remote_rules_server->uri, curl_easy_strerror(res));
"Failed to download \"%s\" error: %s ",
uri, curl_easy_strerror(res));
return -2;
}
else
{
*error_msg = apr_psprintf(mp, "Failed to fetch \"%s\" " \
*error_msg = apr_psprintf(mp, "Failed to download \"%s\" " \
"error: %s ",
remote_rules_server->uri, curl_easy_strerror(res));
}
uri, curl_easy_strerror(res));
return -1;
return -1;
}
}
curl_slist_free_all(headers_chunk);
@ -341,8 +350,12 @@ int msc_remote_grab_content(apr_pool_t *mp, const char *uri, const char *key,
curl_global_cleanup();
return 0;
#else
return -3;
#endif
}
/**
* @brief Setup an apr_crypto_key_t from a given password and salt.
*
@ -369,6 +382,7 @@ int msc_remote_grab_content(apr_pool_t *mp, const char *uri, const char *key,
* @retval n<-1 Something wrong happened, check error_msg for further details.
*
*/
#ifdef WITH_APU_CRYPTO
int msc_remote_enc_key_setup(apr_pool_t *pool,
const char *key,
apr_crypto_key_t **apr_key,
@ -411,11 +425,6 @@ int msc_remote_enc_key_setup(apr_pool_t *pool,
*error_msg = "Internal error - apr_crypto_passphrase: APR_EKEYTYPE";
return -1;
}
else if (rv == APR_EKEYTYPE)
{
*error_msg = "Internal error - apr_crypto_passphrase: APR_EKEYTYPE";
return -1;
}
else if (rv != APR_SUCCESS)
{
*error_msg = "Internal error - apr_crypto_passphrase: Unknown error";
@ -424,6 +433,7 @@ int msc_remote_enc_key_setup(apr_pool_t *pool,
return 0;
}
#endif
/**
* @brief Decrypt an buffer into a memory buffer.
@ -449,6 +459,7 @@ int msc_remote_enc_key_setup(apr_pool_t *pool,
* @retval n<-1 Something wrong happened, further details on error_msg.
*
*/
#ifdef WITH_APU_CRYPTO
int msc_remote_decrypt(apr_pool_t *pool,
const char *key,
struct msc_curl_memory_buffer_t *chunk,
@ -488,12 +499,9 @@ int msc_remote_decrypt(apr_pool_t *pool,
return -1;
}
#ifndef APU_CRYPTO_RECOMMENDED_DRIVER
rv = apr_crypto_get_driver(&driver, "openssl", NULL, &err, pool);
#else
rv = apr_crypto_get_driver(&driver, APU_CRYPTO_RECOMMENDED_DRIVER, NULL,
&err, pool);
#endif
if (rv != APR_SUCCESS || driver == NULL)
{
*error_msg = "Internal error - apr_crypto_get_driver: Unknown error";
@ -573,7 +581,7 @@ int msc_remote_decrypt(apr_pool_t *pool,
return 0;
}
#endif
/**
* @brief Add SecRules from a given URI.
@ -598,6 +606,8 @@ int msc_remote_add_rules_from_uri(cmd_parms *orig_parms,
msc_remote_rules_server *remote_rules_server,
char **error_msg)
{
#ifdef WITH_REMOTE_RULES
struct msc_curl_memory_buffer_t chunk_encrypted;
unsigned char *plain_text = NULL;
int len = 0;
@ -612,13 +622,12 @@ int msc_remote_add_rules_from_uri(cmd_parms *orig_parms,
chunk_encrypted.size = 0;
chunk_encrypted.memory = NULL;
res = msc_remote_grab_content(mp, remote_rules_server->uri,
res = msc_remote_download_content(mp, remote_rules_server->uri,
remote_rules_server->key, &chunk_encrypted, error_msg);
if (*error_msg != NULL)
{
return -1;
}
/* error_msg is not filled when the user set SecRemoteRulesFailAction
* to warn
*/
@ -629,14 +638,21 @@ int msc_remote_add_rules_from_uri(cmd_parms *orig_parms,
if (remote_rules_server->crypto == 1)
{
#ifdef WITH_APU_CRYPTO
msc_remote_decrypt(mp, remote_rules_server->key, &chunk_encrypted,
&plain_text,
&plain_text_len,
error_msg);
if (*error_msg != NULL)
{
msc_remote_clean_chunk(&chunk_encrypted);
return -1;
}
#else
*error_msg = "ModSecurity was not compiled with crypto support.\n";
msc_remote_clean_chunk(&chunk_encrypted);
return -1;
#endif
msc_remote_clean_chunk(&chunk_encrypted);
}
@ -725,12 +741,17 @@ next:
{
msc_remote_clean_chunk(&chunk_encrypted);
}
#else
*error_msg = "SecRemoteRules was not enabled during ModSecurity " \
"compilation.";
return -1;
#endif
}
int msc_remote_clean_chunk(struct msc_curl_memory_buffer_t *chunk)
{
if (chunk->size <= 0)
if (chunk->size == 0)
{
goto end;
}
@ -747,4 +768,3 @@ end:
return 0;
}
#endif

View File

@ -12,12 +12,6 @@
* directly using the email address security@modsecurity.org.
*/
#if APU_HAVE_CRYPTO
#define WITH_REMOTE_RULES_SUPPORT
#endif
#ifdef WITH_REMOTE_RULES_SUPPORT
#ifndef MSC_REMOTE_RULES_H
#define MSC_REMOTE_RULES_H
@ -35,9 +29,9 @@ struct msc_curl_memory_buffer_t;
#include "http_core.h"
#include "http_config.h"
#include <curl/curl.h>
#ifdef WITH_APU_CRYPTO
#include <apr_crypto.h>
#endif
struct msc_remote_rules_server {
directory_config *context;
@ -51,9 +45,10 @@ struct msc_remote_rules_server {
const char *msc_remote_invoke_cmd(const command_rec *cmd, cmd_parms *parms,
void *mconfig, const char *args);
int msc_remote_grab_content(apr_pool_t *mp, const char *uri, const char *key,
int msc_remote_download_content(apr_pool_t *mp, const char *uri, const char *key,
struct msc_curl_memory_buffer_t *chunk, char **error_msg);
#ifdef WITH_APU_CRYPTO
int msc_remote_enc_key_setup(apr_pool_t *pool,
const char *key,
apr_crypto_key_t **apr_key,
@ -67,6 +62,7 @@ int msc_remote_decrypt(apr_pool_t *pool,
unsigned char **plain_text,
apr_size_t *plain_text_len,
char **error_msg);
#endif
int msc_remote_add_rules_from_uri(cmd_parms *orig_parms,
msc_remote_rules_server *remote_rules_server,
@ -75,5 +71,4 @@ int msc_remote_add_rules_from_uri(cmd_parms *orig_parms,
int msc_remote_clean_chunk(struct msc_curl_memory_buffer_t *chunk);
#endif
#endif

View File

@ -26,7 +26,11 @@
#include <apr_sha1.h>
#include "modsecurity_config.h"
#include "msc_remote_rules.h"
#ifdef WITH_CURL
#include "curl/curl.h"
#endif
/**
* NOTE: Be careful as these can ONLY be used on static values for X.
@ -2613,6 +2617,7 @@ int ip_tree_from_file(TreeRoot **rtree, char *uri,
return 0;
}
#ifdef WITH_CURL
int ip_tree_from_uri(TreeRoot **rtree, char *uri,
apr_pool_t *mp, char **error_msg)
{
@ -2621,118 +2626,24 @@ int ip_tree_from_uri(TreeRoot **rtree, char *uri,
int line = 0;
apr_file_t *fd;
char *start;
char buf[HUGE_STRING_LEN + 1]; // FIXME: 2013-10-29 zimmerle: dynamic?
char errstr[1024]; //
int res;
CURL *curl;
CURLcode res;
char id[(APR_SHA1_DIGESTSIZE*2) + 1];
char *apr_id = NULL;
char *beacon_str = NULL;
int beacon_str_len = 0;
char *beacon_apr = NULL;
struct msc_curl_memory_buffer_t chunk;
char *word = NULL;
char *brkt = NULL;
char *sep = "\n";
chunk.memory = malloc(1); /* will be grown as needed by the realloc above */
chunk.size = 0; /* no data at this point */
if (create_radix_tree(mp, rtree, error_msg))
{
return -1;
}
/* Retrieve the beacon string */
beacon_str_len = msc_beacon_string(NULL, 0);
beacon_str = malloc(sizeof(char) * beacon_str_len + 1);
if (beacon_str == NULL) {
beacon_str = "Failed to retrieve beacon string";
beacon_apr = apr_psprintf(mp, "ModSec-status: %s", beacon_str);
}
else
res = msc_remote_download_content(mp, uri, NULL, &chunk, error_msg);
if (res)
{
msc_beacon_string(beacon_str, beacon_str_len);
beacon_apr = apr_psprintf(mp, "ModSec-status: %s", beacon_str);
free(beacon_str);
return res;
}
memset(id, '\0', sizeof(id));
if (msc_status_engine_unique_id(id)) {
sprintf(id, "no unique id");
}
apr_id = apr_psprintf(mp, "ModSec-unique-id: %s", id);
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
if (curl) {
struct curl_slist *headers_chunk = NULL;
#ifdef WIN32
char *buf = malloc(sizeof(TCHAR) * (2048 + 1));
char *ptr = NULL;
DWORD res_len;
#endif
curl_easy_setopt(curl, CURLOPT_URL, uri);
headers_chunk = curl_slist_append(headers_chunk, apr_id);
headers_chunk = curl_slist_append(headers_chunk, beacon_apr);
/* send all data to this function */
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, msc_curl_write_memory_cb);
/* we pass our 'chunk' struct to the callback function */
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
/* Make it TLS 1.x only. */
curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
#ifdef WIN32
res_len = SearchPathA(NULL, "curl-ca-bundle.crt", NULL, (2048 + 1), buf, &ptr);
if (res_len > 0) {
curl_easy_setopt(curl, CURLOPT_CAINFO, strdup(buf));
}
free(buf);
#endif
/* thoseeare the default options, but lets make sure */
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 1);
/* some servers don't like requests that are made without a user-agent
field, so we provide one */
curl_easy_setopt(curl, CURLOPT_USERAGENT, "ModSecurity");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers_chunk);
res = curl_easy_perform(curl);
if (res != CURLE_OK)
{
if (remote_rules_fail_action == REMOTE_RULES_WARN_ON_FAIL)
{
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL,
"Failed to fetch \"%s\" error: %s ",
uri, curl_easy_strerror(res));
return 0;
}
else
{
*error_msg = apr_psprintf(mp, "Failed to fetch \"%s\" " \
"error: %s ", uri,
curl_easy_strerror(res));
return -1;
}
}
curl_easy_cleanup(curl);
curl_slist_free_all(headers_chunk);
}
curl_global_cleanup();
for (word = strtok_r(chunk.memory, sep, &brkt);
word;
word = strtok_r(NULL, sep, &brkt))
@ -2774,9 +2685,12 @@ int ip_tree_from_uri(TreeRoot **rtree, char *uri,
}
}
msc_remote_clean_chunk(&chunk);
return 0;
}
#endif
int tree_contains_ip(apr_pool_t *mp, TreeRoot *rtree,
const char *value, modsec_rec *msr, char **error_msg)
@ -2859,34 +2773,36 @@ int ip_tree_from_param(apr_pool_t *mp,
return 0;
}
#ifdef WITH_CURL
size_t msc_curl_write_memory_cb(void *contents, size_t size,
size_t nmemb, void *userp)
{
size_t realsize = size * nmemb;
struct msc_curl_memory_buffer_t *mem = (struct msc_curl_memory_buffer_t *)userp;
size_t realsize = size * nmemb;
struct msc_curl_memory_buffer_t *mem = (struct msc_curl_memory_buffer_t *)userp;
if (mem->size == 0)
{
mem->memory = malloc(realsize + 1);
memset(mem->memory, '\0', sizeof(realsize + 1));
}
else
{
mem->memory = realloc(mem->memory, mem->size + realsize + 1);
memset(mem->memory + mem->size, '\0', sizeof(realsize + 1));
}
if (mem->size == 0)
{
mem->memory = malloc(realsize + 1);
memset(mem->memory, '\0', sizeof(realsize + 1));
}
else
{
mem->memory = realloc(mem->memory, mem->size + realsize + 1);
memset(mem->memory + mem->size, '\0', sizeof(realsize + 1));
}
if(mem->memory == NULL) {
/* out of memory! */
return 0;
}
if (mem->memory == NULL) {
/* out of memory! */
return 0;
}
memcpy(&(mem->memory[mem->size]), contents, realsize);
mem->size += realsize;
mem->memory[mem->size] = 0;
memcpy(&(mem->memory[mem->size]), contents, realsize);
mem->size += realsize;
mem->memory[mem->size] = 0;
return realsize;
return realsize;
}
#endif
#ifdef WIN32
char* strtok_r(
@ -2914,5 +2830,5 @@ char* strtok_r(
*nextp = str;
return ret;
}
#endif

View File

@ -23,7 +23,7 @@
#include "msc_util.h"
#include "msc_tree.h"
#include "msc_crypt.h"
#include "curl/curl.h"
#include "msc_remote_rules.h"
#include <apr_sha1.h>
#if APR_HAVE_ARPA_INET_H
@ -196,19 +196,32 @@ static int msre_op_ipmatchFromFile_param_init(msre_rule *rule, char **error_msg)
}
filepath = fn;
if (strlen(fn) > strlen("http://") && strncmp(fn, "http://", strlen("http://")) == 0)
if (strlen(fn) > strlen("http://") &&
strncmp(fn, "http://", strlen("http://")) == 0)
{
*error_msg = apr_psprintf(rule->ruleset->mp, "HTTPS address or file " \
"path are expected for operator ipmatchFromFile \"%s\"", fn);
return 0;
}
else if (strlen(fn) > strlen("https://") && strncmp(fn, "https://", strlen("https://")) == 0)
else if (strlen(fn) > strlen("https://") &&
strncmp(fn, "https://", strlen("https://")) == 0)
{
#ifdef WITH_CURL
res = ip_tree_from_uri(&rtree, fn, rule->ruleset->mp, error_msg);
if (res)
if (res == -2)
{
/* Failed to download but we won't stop the webserver to start. */
return 1;
}
else if (res)
{
return 0;
}
#else
*error_msg = apr_psprintf(rule->ruleset->mp, "ModSecurity was not " \
"compiled with Curl support, it cannot load: \"%s\"", fn);
return 0;
#endif
}
else
{
@ -1257,118 +1270,30 @@ static int msre_op_pmFromFile_param_init(msre_rule *rule, char **error_msg) {
/* Add path of the rule filename for a relative phrase filename */
filepath = fn;
if (strlen(fn) > strlen("http://") && strncmp(fn, "http://", strlen("http://")) == 0)
if (strlen(fn) > strlen("http://") &&
strncmp(fn, "http://", strlen("http://")) == 0)
{
*error_msg = apr_psprintf(rule->ruleset->mp, "HTTPS address or " \
"file path are expected for operator pmFromFile \"%s\"", fn);
"file path are expected for operator pmFromFile \"%s\"", fn);
return 0;
}
else if (strlen(fn) > strlen("https://") && strncmp(fn, "https://", strlen("https://")) == 0)
else if (strlen(fn) > strlen("https://") &&
strncmp(fn, "https://", strlen("https://")) == 0)
{
CURL *curl;
CURLcode res;
char id[(APR_SHA1_DIGESTSIZE*2) + 1];
char *apr_id = NULL;
char *beacon_str = NULL;
int beacon_str_len = 0;
char *beacon_apr = NULL;
struct msc_curl_memory_buffer_t chunk;
#ifdef WITH_CURL
int res = 0;
char *word = NULL;
char *brkt = NULL;
char *sep = "\n";
struct msc_curl_memory_buffer_t chunk;
/* Retrieve the beacon string */
beacon_str_len = msc_beacon_string(NULL, 0);
beacon_str = malloc(sizeof(char) * beacon_str_len + 1);
if (beacon_str == NULL) {
beacon_str = "Failed to retrieve beacon string";
beacon_apr = apr_psprintf(rule->ruleset->mp, "ModSec-status: %s", beacon_str);
}
else
res = msc_remote_download_content(rule->ruleset->mp, fn, NULL,
&chunk, error_msg);
if (res == -1)
{
msc_beacon_string(beacon_str, beacon_str_len);
beacon_apr = apr_psprintf(rule->ruleset->mp, "ModSec-status: %s", beacon_str);
free(beacon_str);
return 0;
}
memset(id, '\0', sizeof(id));
if (msc_status_engine_unique_id(id)) {
sprintf(id, "no unique id");
}
apr_id = apr_psprintf(rule->ruleset->mp, "ModSec-unique-id: %s", id);
chunk.memory = malloc(1); /* will be grown as needed by the realloc above */
chunk.size = 0; /* no data at this point */
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
if (curl) {
struct curl_slist *headers_chunk = NULL;
#ifdef WIN32
char *buf = malloc(sizeof(TCHAR) * (2048 + 1));
char *ptr = NULL;
DWORD res_len;
#endif
curl_easy_setopt(curl, CURLOPT_URL, fn);
headers_chunk = curl_slist_append(headers_chunk, apr_id);
headers_chunk = curl_slist_append(headers_chunk, beacon_apr);
/* send all data to this function */
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, msc_curl_write_memory_cb);
/* we pass our 'chunk' struct to the callback function */
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
/* Make it TLS 1.x only. */
curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
#ifdef WIN32
res_len = SearchPathA(NULL, "curl-ca-bundle.crt", NULL, (2048 + 1), buf, &ptr);
if (res_len > 0) {
curl_easy_setopt(curl, CURLOPT_CAINFO, strdup(buf));
}
free(buf);
#endif
/* 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);
/* some servers don't like requests that are made without a user-agent
field, so we provide one */
curl_easy_setopt(curl, CURLOPT_USERAGENT, "ModSecurity");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers_chunk);
res = curl_easy_perform(curl);
if (res != CURLE_OK)
{
if (remote_rules_fail_action == REMOTE_RULES_WARN_ON_FAIL)
{
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL,
"Failed to fetch \"%s\" error: %s ", fn,
curl_easy_strerror(res));
return 1;
}
else
{
*error_msg = apr_psprintf(rule->ruleset->mp,
"Failed to fetch \"%s\" error: %s ", fn,
curl_easy_strerror(res));
return 0;
}
}
curl_easy_cleanup(curl);
curl_slist_free_all(headers_chunk);
}
curl_global_cleanup();
for (word = strtok_r(chunk.memory, sep, &brkt);
word;
word = strtok_r(NULL, sep, &brkt))
@ -1377,8 +1302,13 @@ static int msre_op_pmFromFile_param_init(msre_rule *rule, char **error_msg) {
if (*word == '#') continue;
acmp_add_pattern(p, word, NULL, NULL, strlen(word));
}
msc_remote_clean_chunk(&chunk);
#else
*error_msg = apr_psprintf(rule->ruleset->mp, "ModSecurity was not " \
"compiled with Curl support, it cannot load: \"%s\"", fn);
return 0;
#endif
}
else
{

View File

@ -70,6 +70,7 @@ if test -n "${curl_path}"; then
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])

View File

@ -702,7 +702,27 @@ CHECK_CURL()
CHECK_YAJL()
#AC_SEARCH_LIBS([yajl_alloc], [yajl])
CHECK_SSDEEP()
AC_SEARCH_LIBS([fuzzy_hash_buf], [fuzzy])
#AC_SEARCH_LIBS([fuzzy_hash_buf], [fuzzy])
CFLAGS="$CFLAGS $APU_CFLAGS"
AC_TRY_COMPILE(
[#include <apr_crypto.h>],
[
#if APU_HAVE_CRYPTO == 0
#error APR util was not compiled with crypto support.
#endif
],
[ AC_DEFINE([WITH_APU_CRYPTO], [1], [APR util was compiled with crypto support])
MODSEC_EXTRA_CFLAGS="$MODSEC_EXTRA_CFLAGS -DWITH_APU_CRYPTO"
],
[ AC_MSG_WARN([APR util was not compiled with crypto support. SecRemoteRule will not support the parameter 'crypto']) ]
)
# Current our unique download backend is curl, furhter we can support more.
if test ! -z "${CURL_VERSION}"; then
AC_DEFINE([WITH_REMOTE_RULES], [1], [Enables SecRemoteRules support])
MODSEC_EXTRA_CFLAGS="$MODSEC_EXTRA_CFLAGS -DWITH_REMOTE_RULES"
fi
AC_CONFIG_FILES([Makefile])
AC_CONFIG_FILES([tools/Makefile])

View File

@ -6,6 +6,7 @@ msc_test_SOURCES = msc_test.c \
../apache2/libinjection/libinjection_xss.c \
../apache2/modsecurity.c \
../apache2/msc_status_engine.c \
../apache2/msc_remote_rules.c \
../apache2/msc_crypt.c \
../apache2/msc_geo.c \
../apache2/msc_gsb.c \
@ -28,7 +29,8 @@ msc_test_SOURCES = msc_test.c \
../apache2/re_tfns.c \
../apache2/re_variables.c \
../standalone/regex.c \
../standalone/server.c
../standalone/server.c \
../standalone/config.c
msc_test_CFLAGS = @APR_CFLAGS@ \
@APU_CFLAGS@ \

View File

@ -79,6 +79,15 @@ unsigned long int DSOLOCAL msc_pcre_match_limit = 0;
unsigned long int DSOLOCAL msc_pcre_match_limit_recursion = 0;
char DSOLOCAL *real_server_signature = NULL;
int DSOLOCAL remote_rules_fail_action = REMOTE_RULES_ABORT_ON_FAIL;
module AP_MODULE_DECLARE_DATA security2_module = {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
};
/* Stubs */
char *format_error_log_message(apr_pool_t *mp, error_message_t *em) {