diff --git a/CHANGES b/CHANGES index ef2ae267..d0ee408f 100644 --- a/CHANGES +++ b/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 ----------------------- diff --git a/apache2/apache2_config.c b/apache2/apache2_config.c index 7cd0cf66..bfbcb834 100644 --- a/apache2/apache2_config.c +++ b/apache2/apache2_config.c @@ -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; diff --git a/apache2/mod_security2.c b/apache2/mod_security2.c index 1d709740..693ac500 100644 --- a/apache2/mod_security2.c +++ b/apache2/mod_security2.c @@ -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) diff --git a/apache2/modsecurity.h b/apache2/modsecurity.h index b4a89d62..8ab9b220 100644 --- a/apache2/modsecurity.h +++ b/apache2/modsecurity.h @@ -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; diff --git a/apache2/msc_remote_rules.c b/apache2/msc_remote_rules.c index 7f9b0753..8a943150 100644 --- a/apache2/msc_remote_rules.c +++ b/apache2/msc_remote_rules.c @@ -16,17 +16,22 @@ #include "msc_status_engine.h" #include + +#ifdef WITH_CURL #include +#endif #include + +#ifdef WITH_REMOTE_RULES #include #include +#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 diff --git a/apache2/msc_remote_rules.h b/apache2/msc_remote_rules.h index 248e3cd2..89111eab 100644 --- a/apache2/msc_remote_rules.h +++ b/apache2/msc_remote_rules.h @@ -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 - +#ifdef WITH_APU_CRYPTO #include +#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 diff --git a/apache2/msc_util.c b/apache2/msc_util.c index fbe8eb43..33447ba0 100644 --- a/apache2/msc_util.c +++ b/apache2/msc_util.c @@ -26,7 +26,11 @@ #include #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 + diff --git a/apache2/re_operators.c b/apache2/re_operators.c index 4aee63df..7c742308 100644 --- a/apache2/re_operators.c +++ b/apache2/re_operators.c @@ -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 #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 { diff --git a/build/find_curl.m4 b/build/find_curl.m4 index d1918268..6b23ad69 100644 --- a/build/find_curl.m4 +++ b/build/find_curl.m4 @@ -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]) diff --git a/configure.ac b/configure.ac index 0b92b52d..8ff19ee2 100644 --- a/configure.ac +++ b/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 ], + [ + #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]) diff --git a/tests/Makefile.am b/tests/Makefile.am index 2c97caec..8ffc3bb3 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -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@ \ diff --git a/tests/msc_test.c b/tests/msc_test.c index 453fa4e6..18139039 100644 --- a/tests/msc_test.c +++ b/tests/msc_test.c @@ -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) {