ModSec 2.x without libxml

This commit is contained in:
Felipe Zimmerle
2015-11-18 14:45:28 -08:00
parent fecefbe8b4
commit bfb22ab16f
17 changed files with 323 additions and 39 deletions

View File

@@ -157,7 +157,9 @@ void *create_directory_config(apr_pool_t *mp, char *path)
/* xml external entity */
#ifdef WITH_LIBXML
dcfg->xml_external_entity = NOT_SET;
#endif
return dcfg;
}
@@ -616,8 +618,10 @@ void *merge_directory_configs(apr_pool_t *mp, void *_parent, void *_child)
? parent->crypto_hash_framesrc_pm : child->crypto_hash_framesrc_pm);
/* xml external entity */
#ifdef WITH_LIBXML
merged->xml_external_entity = (child->xml_external_entity == NOT_SET
? parent->xml_external_entity : child->xml_external_entity);
#endif
return merged;
}
@@ -722,6 +726,7 @@ void init_directory_config(directory_config *dcfg)
if (dcfg->col_timeout == NOT_SET) dcfg->col_timeout = 3600;
/* Hash */
#ifdef WITH_LIBXML
if (dcfg->crypto_key == NOT_SET_P) dcfg->crypto_key = getkey(dcfg->mp);
if (dcfg->crypto_key_len == NOT_SET) dcfg->crypto_key_len = strlen(dcfg->crypto_key);
if (dcfg->crypto_key_add == NOT_SET) dcfg->crypto_key_add = HASH_KEYONLY;
@@ -738,9 +743,12 @@ void init_directory_config(directory_config *dcfg)
if (dcfg->crypto_hash_location_pm == NOT_SET) dcfg->crypto_hash_location_pm = 0;
if (dcfg->crypto_hash_iframesrc_pm == NOT_SET) dcfg->crypto_hash_iframesrc_pm = 0;
if (dcfg->crypto_hash_framesrc_pm == NOT_SET) dcfg->crypto_hash_framesrc_pm = 0;
#endif
#ifdef WITH_LIBXML
/* xml external entity */
if (dcfg->xml_external_entity == NOT_SET) dcfg->xml_external_entity = 0;
#endif
}
@@ -2592,6 +2600,7 @@ static const char *cmd_sensor_id(cmd_parms *cmd, void *_dcfg, const char *p1)
* \retval NULL On failure
* \retval apr_psprintf On Success
*/
#ifdef WITH_LIBXML
static const char *cmd_xml_external_entity(cmd_parms *cmd, void *_dcfg, const char *p1)
{
directory_config *dcfg = (directory_config *)_dcfg;
@@ -2607,7 +2616,7 @@ static const char *cmd_xml_external_entity(cmd_parms *cmd, void *_dcfg, const ch
return NULL;
}
#endif
/**
* \brief Add SecHashEngine configuration option
@@ -3610,7 +3619,7 @@ const command_rec module_directives[] = {
"Abort or Warn"
),
#ifdef WITH_LIBXML
AP_INIT_TAKE1 (
"SecXmlExternalEntity",
cmd_xml_external_entity,
@@ -3618,6 +3627,7 @@ const command_rec module_directives[] = {
CMD_SCOPE_ANY,
"On or Off"
),
#endif
AP_INIT_FLAG (
"SecRuleInheritance",

View File

@@ -135,9 +135,11 @@ static void version(apr_pool_t *mp) {
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL,
"ModSecurity: YAJL compiled version=\"%d.%d.%d\"", YAJL_MAJOR, YAJL_MINOR, YAJL_MICRO);
#endif /* WITH_YAJL */
#ifdef WITH_LIBXML
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL,
"ModSecurity: LIBXML compiled version=\"%s\"", LIBXML_DOTTED_VERSION);
"ModSecurity: LIBXML compiled version=\"%s\"", LIBXML_DOTTED_VERSION
);
#endif
}

View File

@@ -179,7 +179,9 @@ int modsecurity_init(msc_engine *msce, apr_pool_t *mp) {
*/
void modsecurity_child_init(msc_engine *msce) {
/* Need to call this once per process before any other XML calls. */
#ifdef WITH_LIBXML
xmlInitParser();
#endif
if (msce->auditlog_lock != NULL) {
apr_status_t rc = apr_global_mutex_child_init(&msce->auditlog_lock, NULL, msce->mp);
@@ -266,7 +268,9 @@ static apr_status_t modsecurity_tx_cleanup(void *data) {
if (msr->mpd != NULL) multipart_cleanup(msr);
/* XML processor cleanup. */
#ifdef WITH_LIBXML
if (msr->xml != NULL) xml_cleanup(msr);
#endif
#ifdef WITH_YAJL
/* JSON processor cleanup. */

View File

@@ -19,8 +19,10 @@
#include <stdlib.h>
#include <limits.h>
#ifdef WITH_LIBXML
#include <libxml/tree.h>
#include <libxml/HTMLparser.h>
#endif
typedef struct rule_exception rule_exception;
typedef struct rule_exception hash_method;
@@ -384,8 +386,11 @@ struct modsec_rec {
char *multipart_filename;
char *multipart_name;
multipart_data *mpd; /* MULTIPART processor data structure */
#ifdef WITH_LIBXML
xml_data *xml; /* XML processor data structure */
#else
void *xml;
#endif
#ifdef WITH_YAJL
json_data *json; /* JSON processor data structure */
#endif
@@ -465,7 +470,9 @@ struct modsec_rec {
/* Generic request body processor context to be used by custom parsers. */
void *reqbody_processor_ctx;
#ifdef WITH_LIBXML
htmlDocPtr crypto_html_tree;
#endif
#if defined(WITH_LUA)
#ifdef CACHE_LUA
lua_State *L;
@@ -628,7 +635,9 @@ struct directory_config {
int crypto_hash_framesrc_pm;
/* xml */
#ifdef WITH_LIBXML
int xml_external_entity;
#endif
/* This will be used whenever ModSecurity will be ready
* to ask the server for newer rules.

View File

@@ -18,8 +18,10 @@
#include "apr_uri.h"
#include "apr_base64.h"
#include "acmp.h"
#ifdef WITH_LIBXML
#include "libxml/HTMLtree.h"
#include "libxml/uri.h"
#endif
#include <string.h>
/**
@@ -32,6 +34,7 @@
* \retval NULL on fail
*/
char *normalize_path(modsec_rec *msr, char *input) {
#ifdef WITH_LIBXML
xmlURI *uri = NULL;
char *parsed_content = NULL;
char *content = NULL;
@@ -136,6 +139,8 @@ char *normalize_path(modsec_rec *msr, char *input) {
if(uri != NULL) xmlFreeURI(uri);
return apr_pstrdup(msr->mp, input);
#endif
return;
}
/**
@@ -146,6 +151,7 @@ char *normalize_path(modsec_rec *msr, char *input) {
* \retval key random key
*/
char *getkey(apr_pool_t *mp) {
#ifdef WITH_LIBXML
unsigned char digest[APR_SHA1_DIGESTSIZE];
char *sig, *key, *value;
apr_sha1_ctx_t ctx;
@@ -168,6 +174,8 @@ char *getkey(apr_pool_t *mp) {
apr_base64_encode (sig, (const char*)digest, sizeof (digest));
return sig;
#endif
return NULL;
}
@@ -184,6 +192,7 @@ char *getkey(apr_pool_t *mp) {
*/
char *hmac(modsec_rec *msr, const char *key, int key_len,
unsigned char *msg, int msglen) {
#ifdef WITH_XML
apr_sha1_ctx_t ctx;
unsigned char digest[APR_SHA1_DIGESTSIZE];
unsigned char hmac_ipad[HMAC_PAD_SIZE], hmac_opad[HMAC_PAD_SIZE];
@@ -227,6 +236,8 @@ char *hmac(modsec_rec *msr, const char *key, int key_len,
*hmac_digest = '\0';
return apr_pstrdup (msr->mp, hex_digest);
#endif
return NULL;
}
@@ -239,6 +250,7 @@ char *hmac(modsec_rec *msr, const char *key, int key_len,
* \retval -1 on fail
*/
int init_response_body_html_parser(modsec_rec *msr) {
#ifdef WITH_LIBXML
char *charset = NULL;
char *final_charset = NULL;
char sep;
@@ -319,7 +331,7 @@ int init_response_body_html_parser(modsec_rec *msr) {
"init_response_body_html_parser: Successfully html parser generated.");
return 1;
}
#endif
return 1;
}
@@ -335,6 +347,7 @@ int init_response_body_html_parser(modsec_rec *msr) {
* \retval -1 on fail
*/
int do_hash_method(modsec_rec *msr, char *link, int type) {
#ifdef WITH_LIBXML
hash_method **em = NULL;
int i = 0;
char *error_msg = NULL;
@@ -633,6 +646,7 @@ int do_hash_method(modsec_rec *msr, char *link, int type) {
}
}
#endif
return 0;
}
@@ -646,6 +660,7 @@ int do_hash_method(modsec_rec *msr, char *link, int type) {
* \retval -1 On fail
*/
int hash_response_body_links(modsec_rec *msr) {
#ifdef WITH_LIBXML
int lsize = 0, fsize = 0, lcount = 0, fcount = 0, i;
int isize = 0, icount = 0, frsize = 0, frcount = 0;
int bytes = 0;
@@ -987,6 +1002,7 @@ obj_error:
if(xpathCtx != NULL)
xmlXPathFreeContext(xpathCtx);
ctx_error:
#endif
return -1;
}
@@ -1000,6 +1016,7 @@ ctx_error:
* \retval -1 On fail
*/
int inject_hashed_response_body(modsec_rec *msr, int elts) {
#ifdef WITH_LIBXML
xmlOutputBufferPtr output_buf = NULL;
xmlCharEncodingHandlerPtr handler = NULL;
char *p = NULL;
@@ -1215,7 +1232,7 @@ int inject_hashed_response_body(modsec_rec *msr, int elts) {
if (msr->txcfg->debuglog_level >= 4)
msr_log(msr, 4, "inject_hashed_response_body: Stream buffer [%"APR_SIZE_T_FMT"]. Done",msr->stream_output_length);
#endif
return 1;
}
@@ -1230,6 +1247,7 @@ int inject_hashed_response_body(modsec_rec *msr, int elts) {
* \retval NULL on fail
*/
char *do_hash_link(modsec_rec *msr, char *link, int type) {
#ifdef WITH_LIBXML
char *mac_link = NULL;
char *path_chunk = NULL;
char *hash_value = NULL;
@@ -1433,6 +1451,8 @@ char *do_hash_link(modsec_rec *msr, char *link, int type) {
}
return mac_link;
#endif
return NULL;
}
/**
@@ -1444,6 +1464,7 @@ char *do_hash_link(modsec_rec *msr, char *link, int type) {
* \retval 0 on fail
*/
int modify_response_header(modsec_rec *msr) {
#ifdef WITH_LIBXML
char *mac_link = NULL;
const char *location = NULL;
int rc = 0;
@@ -1500,6 +1521,6 @@ int modify_response_header(modsec_rec *msr) {
apr_table_unset(msr->r->headers_out,"Location");
apr_table_set(msr->r->headers_out, "Location",(char*)apr_psprintf(msr->mp,"%s", mac_link));
}
#endif
return 1;
}

View File

@@ -16,8 +16,10 @@
#define _MSC_CRYPT_H_
#include "modsecurity.h"
#ifdef WITH_LIBXML
#include <libxml/HTMLparser.h>
#include <libxml/xpath.h>
#endif
#define HMAC_PAD_SIZE 65
#define HASH_ONLY 0

View File

@@ -23,7 +23,9 @@
#include "msc_util.h"
#include "apr_version.h"
#ifdef WITH_LIBXML
#include <libxml/xmlversion.h>
#endif
/**
* Write the supplied data to the audit log (if the FD is ready), update

View File

@@ -15,7 +15,7 @@
#include "msc_remote_rules.h"
#include "msc_status_engine.h"
#include <apr_thread_pool.h>
// #include <apr_thread_pool.h>
#ifdef WITH_CURL
#include <curl/curl.h>

View File

@@ -120,13 +120,16 @@ apr_status_t modsecurity_request_body_start(modsec_rec *msr, char **error_msg) {
}
}
else if (strcmp(msr->msc_reqbody_processor, "XML") == 0) {
#ifdef WITH_LIBXML
if (xml_init(msr, &my_error_msg) < 0) {
*error_msg = apr_psprintf(msr->mp, "XML parsing error (init): %s", my_error_msg);
msr->msc_reqbody_error = 1;
msr->msc_reqbody_error_msg = my_error_msg;
msr_log(msr, 2, "%s", *error_msg);
}
#endif
}
else if (strcmp(msr->msc_reqbody_processor, "JSON") == 0) {
#ifdef WITH_YAJL
if (json_init(msr, &my_error_msg) < 0) {
@@ -352,12 +355,14 @@ apr_status_t modsecurity_request_body_store(modsec_rec *msr,
msr->msc_reqbody_no_files_length += length;
/* Process data as XML. */
#ifdef WITH_LIBXML
if (xml_process_chunk(msr, data, length, &my_error_msg) < 0) {
*error_msg = apr_psprintf(msr->mp, "XML parsing error: %s", my_error_msg);
msr->msc_reqbody_error = 1;
msr->msc_reqbody_error_msg = *error_msg;
msr_log(msr, 2, "%s", *error_msg);
}
#endif
}
else if (strcmp(msr->msc_reqbody_processor, "JSON") == 0) {
/* Increase per-request data length counter. */
@@ -657,6 +662,7 @@ apr_status_t modsecurity_request_body_end(modsec_rec *msr, char **error_msg) {
return modsecurity_request_body_end_urlencoded(msr, error_msg);
}
else if (strcmp(msr->msc_reqbody_processor, "XML") == 0) {
#ifdef WITH_LIBXML
if (xml_complete(msr, &my_error_msg) < 0) {
*error_msg = apr_psprintf(msr->mp, "XML parser error: %s", my_error_msg);
msr->msc_reqbody_error = 1;
@@ -664,6 +670,7 @@ apr_status_t modsecurity_request_body_end(modsec_rec *msr, char **error_msg) {
msr_log(msr, 2, "%s", *error_msg);
return -1;
}
#endif
}
} else if (msr->txcfg->reqbody_buffering != REQUEST_BODY_FORCEBUF_OFF) {
/* Convert to a single continous buffer, but don't do anything else. */

View File

@@ -347,7 +347,12 @@ int DSOLOCAL msc_beacon_string (char *beacon_string, int beacon_string_max_len)
#ifdef WITH_LUA
lua = LUA_VERSION;
#endif
#ifdef WITH_LIBXML
libxml = LIBXML_DOTTED_VERSION;
#else
libxml = "(null)";
#endif
modsec = MODSEC_VERSION;
#ifdef VERSION_IIS
apache = "IIS";

View File

@@ -14,6 +14,7 @@
#include "msc_xml.h"
#ifdef WITH_XML
static xmlParserInputBufferPtr
xml_unload_external_entity(const char *URI, xmlCharEncoding enc) {
return NULL;
@@ -32,10 +33,11 @@ int xml_init(modsec_rec *msr, char **error_msg) {
msr->xml = apr_pcalloc(msr->mp, sizeof(xml_data));
if (msr->xml == NULL) return -1;
#ifdef WITH_LIBXML
if(msr->txcfg->xml_external_entity == 0) {
entity = xmlParserInputBufferCreateFilenameDefault(xml_unload_external_entity);
}
#endif
return 1;
}
@@ -144,3 +146,5 @@ apr_status_t xml_cleanup(modsec_rec *msr) {
return 1;
}
#endif

View File

@@ -15,18 +15,24 @@
#ifndef _MSC_XML_H_
#define _MSC_XML_H_
#ifdef WITH_LIBXML
typedef struct xml_data xml_data;
#endif
#include "modsecurity.h"
#if WITH_LIBXML
#include <libxml/xmlschemas.h>
#include <libxml/xpath.h>
#endif
/* Structures */
struct xml_data {
#ifdef WITH_LIBXML
xmlSAXHandler *sax_handler;
xmlParserCtxtPtr parsing_ctx;
xmlDocPtr doc;
#endif // WITH_LIBXML
unsigned int well_formed;
};

View File

@@ -1293,6 +1293,7 @@ static apr_status_t msre_action_ctl_execute(modsec_rec *msr, apr_pool_t *mptmp,
return -1;
}
#ifdef WITH_LIBXML
/* xmlns */
static char *msre_action_xmlns_validate(msre_engine *engine, apr_pool_t *mp, msre_action *action) {
char *name = NULL;
@@ -1313,6 +1314,7 @@ static char *msre_action_xmlns_validate(msre_engine *engine, apr_pool_t *mp, msr
return NULL;
}
#endif
/* sanitizeArg */
static apr_status_t msre_action_sanitizeArg_execute(modsec_rec *msr, apr_pool_t *mptmp,
@@ -2629,6 +2631,7 @@ void msre_engine_register_default_actions(msre_engine *engine) {
msre_action_ctl_execute
);
#ifdef WITH_LIBXML
/* xmlns */
msre_engine_action_register(engine,
"xmlns",
@@ -2641,6 +2644,7 @@ void msre_engine_register_default_actions(msre_engine *engine) {
NULL,
NULL
);
#endif
/* capture */
msre_engine_action_register(engine,

View File

@@ -2536,6 +2536,7 @@ static int msre_op_validateDTD_init(msre_rule *rule, char **error_msg) {
static int msre_op_validateDTD_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
char **error_msg)
{
#ifdef WITH_LIBXML
xmlValidCtxtPtr cvp;
xmlDtdPtr dtd;
@@ -2591,7 +2592,7 @@ static int msre_op_validateDTD_execute(modsec_rec *msr, msre_rule *rule, msre_va
xmlFreeValidCtxt(cvp);
xmlFreeDtd(dtd);
#endif
/* Match. */
return 0;
}
@@ -2606,6 +2607,7 @@ static int msre_op_validateSchema_init(msre_rule *rule, char **error_msg) {
static int msre_op_validateSchema_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
char **error_msg)
{
#ifdef WITH_LIBXML
xmlSchemaParserCtxtPtr parserCtx;
xmlSchemaValidCtxtPtr validCtx;
xmlSchemaPtr schema;
@@ -2673,7 +2675,7 @@ static int msre_op_validateSchema_execute(modsec_rec *msr, msre_rule *rule, msre
xmlSchemaFree(schema);
xmlSchemaFreeValidCtxt(validCtx);
#endif
return 0;
}

View File

@@ -19,7 +19,9 @@
#include "re.h"
#include "msc_util.h"
#ifdef WITH_LIBXML
#include "libxml/xpathInternals.h"
#endif
/**
* Generates a variable from a string and a length.
@@ -560,6 +562,7 @@ static int var_reqbody_processor_error_msg_generate(modsec_rec *msr, msre_var *v
/* XML */
#ifdef WITH_LIBXML
static char *var_xml_validate(msre_ruleset *ruleset, msre_var *var) {
/* It's OK if there's no parameter. */
if (var->param == NULL) return NULL;
@@ -674,6 +677,8 @@ static int var_xml_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
return count;
}
#endif
/* WEBSERVER_ERROR_LOG */
static int var_webserver_error_log_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
@@ -4159,6 +4164,7 @@ void msre_engine_register_default_variables(msre_engine *engine) {
PHASE_REQUEST_HEADERS
);
#ifdef WITH_LIBXML
/* XML */
msre_engine_variable_register(engine,
"XML",
@@ -4169,4 +4175,6 @@ void msre_engine_register_default_variables(msre_engine *engine) {
VAR_DONT_CACHE, /* dynamic */
PHASE_REQUEST_BODY
);
#endif
}