mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-13 21:36:00 +03:00
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:
parent
94fd570e31
commit
23823bb2c3
6
CHANGES
6
CHANGES
@ -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
|
||||
-----------------------
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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])
|
||||
|
22
configure.ac
22
configure.ac
@ -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])
|
||||
|
@ -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@ \
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user