Updates to build on Windows with MS VC++ 8.

This commit is contained in:
brectanus 2008-02-13 07:10:54 +00:00
parent 1789b9935e
commit cc2110b187
8 changed files with 241 additions and 122 deletions

View File

@ -1,3 +1,9 @@
12 Feb 2008 - 2.5.0-rc4
-----------------------
* Updated code to be more portable so it builds with MS VC++ 8.
11 Feb 2008 - 2.5.0-rc3
-----------------------

View File

@ -1,42 +1,62 @@
# Path to Apache installation
BASE = "C:/Program Files/Apache Group/Apache2/"
CC = cl
DEFS = /nologo /Od /LD /W3 -DWIN32 -DWINNT
DLL = mod_security2.dll
# Path to the headers - configure the libxml2 include path
INCLUDES = -I. -I$(BASE)\include -IC:\libxml2\include
CFLAGS= -O $(INCLUDES) $(DEFS)
# Paths to the required libraries
# Use the line below if you want to link against libxml2
# LIBS = $(BASE)\lib\libhttpd.lib $(BASE)\lib\libapr.lib $(BASE)\lib\libaprutil.lib $(BASE)\lib\pcre.lib C:\libxml2\lib\libxml2.lib
# Use the line belof if you don't want to link against libxml2
LIBS = $(BASE)\lib\libhttpd.lib $(BASE)\lib\libapr.lib $(BASE)\lib\libaprutil.lib $(BASE)\lib\pcre.lib
OBJS = mod_security2.obj apache2_config.obj apache2_io.obj apache2_util.obj \
re.obj re_operators.obj re_actions.obj re_tfns.obj re_variables.obj \
msc_logging.obj msc_xml.obj msc_multipart.obj modsecurity.obj msc_parsers.obj \
msc_util.obj msc_pcre.obj persist_dbm.obj msc_reqbody.obj pdf_protect.obj \
msc_geo.obj acmp.obj
all: $(DLL)
dll: $(DLL)
.c.obj:
$(CC) $(CFLAGS) -c $< -Fo$@
.cpp.obj:
$(CC) $(CFLAGS) -c $< -Fo$@
$(DLL): $(OBJS)
$(CC) $(CFLAGS) -LD $(OBJS) -Fe$(DLL) $(LIBS) /link /NODEFAULTLIB:MSVCRT
clean:
del $(OBJS) *.dll *.lib *.pdb *.idb *.ilk *.exp *.res *.rc *.bin
###########################################################################
### You Will need to modify the following variables for your system
###########################################################################
###########################################################################
# Path to Apache httpd installation
BASE = C:\Apache2
# Path to required libraries
LIBXML2 = C:\work\libxml2-2.6.31
LUA = C:\work\lua-5.1.3\src
PCRE = C:\work\httpd-2.2.8\srclib\pcre
###########################################################################
###########################################################################
CC = cL
DEFS = /nologo /O2 /LD /W3 /wd4244 -DWIN32 -DWINNT -Dinline=APR_INLINE
DLL = mod_security2.so
INCLUDES = -I. -I$(PCRE) -I$(LIBXML2)\include -I$(LUA) -I$(BASE)\include
CFLAGS= -MD $(INCLUDES) $(DEFS)
LIBS = $(BASE)\lib\libhttpd.lib \
$(BASE)\lib\libapr-1.lib \
$(BASE)\lib\libaprutil-1.lib \
$(PCRE)\LibR\pcre.lib \
$(LIBXML2)\win32\bin.msvc\libxml2.lib \
$(LUA)\lua.lib \
wsock32.lib
OBJS = mod_security2.obj apache2_config.obj apache2_io.obj apache2_util.obj \
re.obj re_operators.obj re_actions.obj re_tfns.obj re_variables.obj \
msc_logging.obj msc_xml.obj msc_multipart.obj modsecurity.obj \
msc_parsers.obj msc_util.obj msc_pcre.obj persist_dbm.obj \
msc_reqbody.obj pdf_protect.obj msc_geo.obj acmp.obj msc_lua.obj
all: $(DLL)
dll: $(DLL)
mod_security2_config.h: mod_security2_config.hw
@echo off
type mod_security2_config.hw > mod_security2_config.h
.c.obj:
$(CC) $(CFLAGS) -c $< -Fo$@
.cpp.obj:
$(CC) $(CFLAGS) -c $< -Fo$@
$(DLL): mod_security2_config.h $(OBJS)
$(CC) $(CFLAGS) -LD $(OBJS) -Fe$(DLL) $(LIBS) /link
install: $(DLL)
copy $(DLL) $(BASE)\modules
clean:
del $(OBJS) *.dll *.lib *.pdb *.idb *.ilk *.exp *.res *.rc *.bin mod_security2_config.h

View File

@ -205,12 +205,15 @@ static acmp_node_t *acmp_child_for_code(acmp_node_t *parent_node, acmp_utf8_char
* Adds node to parent node, if it is not already there
*/
static void acmp_add_node_to_parent(acmp_node_t *parent, acmp_node_t *child) {
acmp_node_t *node = NULL;
child->parent = parent;
if (parent->child == NULL) {
parent->child = child;
return;
}
acmp_node_t *node = parent->child;
node = parent->child;
for (;;) {
if (node == child) return;
if (node->sibling == NULL) {
@ -241,6 +244,7 @@ static void acmp_copy_nodes_recursive(acmp_node_t *from, acmp_node_t *to, apr_po
acmp_node_t *old_node = from->child, *new_node, *nn2;
if (old_node == NULL) return;
nn2 = apr_pcalloc(pool, sizeof(acmp_node_t));
/* ENH: Check alloc succeded */
acmp_clone_node_no_state(old_node, nn2);
nn2->parent = to;
to->child = nn2;
@ -250,6 +254,7 @@ static void acmp_copy_nodes_recursive(acmp_node_t *from, acmp_node_t *to, apr_po
old_node = old_node->sibling;
if (old_node == NULL) break;
new_node = apr_pcalloc(pool, sizeof(acmp_node_t));
/* ENH: Check alloc succeded */
acmp_clone_node_no_state(old_node, new_node);
new_node->parent = to;
nn2->sibling = new_node;
@ -310,6 +315,7 @@ static void acmp_add_btree_leaves(acmp_btree_node_t *node, acmp_node_t *nodes[],
if ((pos - lb) > 1) {
left = lb + (pos - lb) / 2;
node->left = apr_pcalloc(pool, sizeof(acmp_btree_node_t));
/* ENH: Check alloc succeded */
node->left->node = nodes[left];
node->left->letter = nodes[left]->letter;
#ifdef DEBUG_ACMP
@ -319,6 +325,7 @@ static void acmp_add_btree_leaves(acmp_btree_node_t *node, acmp_node_t *nodes[],
if ((rb - pos) > 1) {
right = pos + (rb - pos) / 2;
node->right = apr_pcalloc(pool, sizeof(acmp_btree_node_t));
/* ENH: Check alloc succeded */
node->right->node = nodes[right];
node->right->letter = nodes[right]->letter;
#ifdef DEBUG_ACMP
@ -339,25 +346,36 @@ static void acmp_add_btree_leaves(acmp_btree_node_t *node, acmp_node_t *nodes[],
static void acmp_build_binary_tree(ACMP *parser, acmp_node_t *node) {
apr_size_t count, i, j;
acmp_node_t *child = node->child;
acmp_node_t **nodes;
apr_size_t pos;
/* Build an array big enough */
for (count = 0; child != NULL; child = child->sibling) count++;
acmp_node_t *nodes[count];
nodes = apr_pcalloc(parser->pool, count * sizeof(acmp_node_t *));
/* ENH: Check alloc succeded */
/* ENH: Combine this in the loop below - we do not need two loops */
child = node->child;
for (i = 0; i < count; i++) {
nodes[i] = child;
child = child->sibling;
};
/* We have array with all children of the node and number of those children
*/
for (i = 0; i < count - 1; i++)
for (j = i + 1; j < count; j++) {
acmp_node_t *tmp;
if (nodes[i]->letter < nodes[j]->letter) continue;
acmp_node_t *tmp = nodes[i];
tmp = nodes[i];
nodes[i] = nodes[j];
nodes[j] = tmp;
}
node->btree = apr_pcalloc(parser->pool, sizeof(acmp_btree_node_t));
apr_size_t pos = count / 2;
/* ENH: Check alloc succeded */
pos = count / 2;
node->btree->node = nodes[pos];
node->btree->letter = nodes[pos]->letter;
acmp_add_btree_leaves(node->btree, nodes, pos, -1, count, parser->pool);
@ -371,10 +389,11 @@ static void acmp_build_binary_tree(ACMP *parser, acmp_node_t *node) {
*/
static apr_status_t acmp_connect_fail_branches(ACMP *parser) {
/* Already connected ? */
if (parser->is_failtree_done != 0) return APR_SUCCESS;
acmp_node_t *child, *node, *goto_node;
apr_array_header_t *arr, *arr2, *tmp;
if (parser->is_failtree_done != 0) return APR_SUCCESS;
parser->root_node->text = "";
arr = apr_array_make(parser->pool, 32, sizeof(acmp_node_t *));
arr2 = apr_array_make(parser->pool, 32, sizeof(acmp_node_t *));
@ -456,15 +475,19 @@ static void acmp_found(ACMP *parser, acmp_node_t *node) {
ACMP *acmp_create(int flags, apr_pool_t *pool) {
apr_status_t rc;
apr_pool_t *p;
ACMP *parser;
rc = apr_pool_create(&p, pool);
if (rc != APR_SUCCESS) return NULL;
ACMP *parser = apr_pcalloc(p, sizeof(ACMP));
parser = apr_pcalloc(p, sizeof(ACMP));
/* ENH: Check alloc succeded */
parser->pool = p;
parser->parent_pool = pool;
parser->is_utf8 = (flags & ACMP_FLAG_UTF8) == 0 ? 0 : 1;
parser->is_case_sensitive = (flags & ACMP_FLAG_CASE_SENSITIVE) == 0 ? 0 : 1;
parser->root_node = apr_pcalloc(p, sizeof(acmp_node_t));
/* ENH: Check alloc succeded */
return parser;
}
@ -487,17 +510,20 @@ void acmp_destroy(ACMP *parser) {
ACMP *acmp_duplicate(ACMP *parser, apr_pool_t *pool) {
apr_status_t rc;
apr_pool_t *p;
ACMP *new_parser;
if (pool == NULL) pool = parser->parent_pool;
rc = apr_pool_create(&p, pool);
if (rc != APR_SUCCESS) return NULL;
ACMP *new_parser = apr_pcalloc(p, sizeof(ACMP));
new_parser = apr_pcalloc(p, sizeof(ACMP));
/* ENH: Check alloc succeded */
new_parser->pool = p;
new_parser->parent_pool = pool;
new_parser->is_utf8 = parser->is_utf8;
new_parser->is_case_sensitive = parser->is_case_sensitive;
new_parser->root_node = apr_pcalloc(p, sizeof(acmp_node_t));
/* ENH: Check alloc succeded */
new_parser->dict_count = parser->dict_count;
new_parser->longest_entry = parser->longest_entry;
acmp_copy_nodes_recursive(parser->root_node, new_parser->root_node, new_parser->pool);
@ -509,11 +535,15 @@ ACMP *acmp_duplicate(ACMP *parser, apr_pool_t *pool) {
* Creates fail tree and initializes buffer
*/
apr_status_t acmp_prepare(ACMP *parser) {
apr_status_t st;
if (parser->bp_buff_len < parser->longest_entry) {
parser->bp_buff_len = parser->longest_entry * 2;
parser->bp_buffer = apr_pcalloc(parser->pool, sizeof(apr_size_t) * parser->bp_buff_len);
/* ENH: Check alloc succeded */
}
apr_status_t st = acmp_connect_fail_branches(parser);
st = acmp_connect_fail_branches(parser);
parser->active_node = parser->root_node;
if (st != APR_SUCCESS) return st;
parser->is_active = 1;
@ -532,12 +562,17 @@ apr_status_t acmp_prepare(ACMP *parser) {
apr_status_t acmp_add_pattern(ACMP *parser, const char *pattern,
acmp_callback_t callback, void *data, apr_size_t len)
{
if (parser->is_active != 0) return APR_EGENERAL;
size_t length = (len == 0) ? acmp_strlen(parser, pattern) : len;
size_t i, j;
acmp_utf8_char_t ucs_chars[length];
size_t length, i, j;
acmp_utf8_char_t *ucs_chars;
acmp_node_t *parent, *child;
acmp_node_t *parent = parser->root_node, *child;
if (parser->is_active != 0) return APR_EGENERAL;
length = (len == 0) ? acmp_strlen(parser, pattern) : len;
ucs_chars = apr_pcalloc(parser->pool, length * sizeof(acmp_utf8_char_t));
/* ENH: Check alloc succeded */
parent = parser->root_node;
acmp_strtoucs(parser, pattern, ucs_chars, length);
for (i = 0; i < length; i++) {
@ -548,10 +583,12 @@ apr_status_t acmp_add_pattern(ACMP *parser, const char *pattern,
child = acmp_child_for_code(parent, letter);
if (child == NULL) {
child = apr_pcalloc(parser->pool, sizeof(acmp_node_t));
/* ENH: Check alloc succeded */
child->pattern = "";
child->letter = letter;
child->depth = i;
child->text = apr_pcalloc(parser->pool, strlen(pattern) + 2);
/* ENH: Check alloc succeded */
for (j = 0; j <= i; j++) child->text[j] = pattern[j];
}
if (i == length - 1) {
@ -559,6 +596,7 @@ apr_status_t acmp_add_pattern(ACMP *parser, const char *pattern,
parser->dict_count++;
child->is_last = 1;
child->pattern = apr_pcalloc(parser->pool, strlen(pattern) + 2);
/* ENH: Check alloc succeded */
strcpy(child->pattern, pattern);
}
child->callback = callback;
@ -579,14 +617,19 @@ apr_status_t acmp_add_pattern(ACMP *parser, const char *pattern,
* len - size of data in bytes
*/
apr_status_t acmp_process(ACMP *parser, const char *data, apr_size_t len) {
if (parser->is_failtree_done == 0) acmp_prepare(parser);
acmp_node_t *node = parser->active_node, *go_to;
acmp_node_t *node, *go_to;
apr_size_t seq_length;
const char *end = (data + len);
const char *end;
if (parser->is_failtree_done == 0) acmp_prepare(parser);
node = parser->active_node;
end = data + len;
while (data < end) {
parser->bp_buffer[parser->char_pos % parser->bp_buff_len] = parser->byte_pos;
acmp_utf8_char_t letter;
parser->bp_buffer[parser->char_pos % parser->bp_buff_len] = parser->byte_pos;
if (parser->is_utf8) {
if (parser->u8buff_len > 0) {
/* Resuming partial utf-8 sequence */
@ -674,6 +717,7 @@ void acmp_reset(ACMP *parser) {
ACMPT *acmp_duplicate_quick(ACMP *parser, apr_pool_t *pool) {
apr_pool_t *p = (pool != NULL) ? pool : parser->pool;
ACMPT *dup = apr_pcalloc(p, sizeof(ACMPT));
/* ENH: Check alloc succeded */
dup->parser = parser;
return dup;
}
@ -682,13 +726,18 @@ ACMPT *acmp_duplicate_quick(ACMP *parser, apr_pool_t *pool) {
* Process the data using ACMPT to keep state, and ACMPT's parser to keep the tree
*/
apr_status_t acmp_process_quick(ACMPT *acmpt, const char **match, const char *data, apr_size_t len) {
ACMP *parser;
acmp_node_t *node, *go_to;
const char *end;
if (acmpt->parser->is_failtree_done == 0) {
acmp_prepare(acmpt->parser);
};
ACMP *parser = acmpt->parser;
parser = acmpt->parser;
if (acmpt->ptr == NULL) acmpt->ptr = parser->root_node;
acmp_node_t *node = acmpt->ptr, *go_to;
const char *end = (data + len);
node = acmpt->ptr;
end = data + len;
while (data < end) {
acmp_utf8_char_t letter = (unsigned char)*data++;

View File

@ -0,0 +1 @@
/* This file is left empty for building on Windows. */

View File

@ -64,7 +64,7 @@ extern DSOLOCAL modsec_build_type_rec modsec_build_type[];
#define MODSEC_VERSION_MINOR "5"
#define MODSEC_VERSION_MAINT "0"
#define MODSEC_VERSION_TYPE "rc"
#define MODSEC_VERSION_RELEASE "3"
#define MODSEC_VERSION_RELEASE "4"
#define MODULE_NAME "ModSecurity for Apache"
#define MODULE_RELEASE \

View File

@ -27,6 +27,7 @@ typedef struct {
*/
static const char* dump_reader(lua_State* L, void* user_data, size_t* size) {
msc_lua_dumpr_t *dumpr = (msc_lua_dumpr_t *)user_data;
msc_script_part *part;
/* Do we have more chunks to return? */
if (dumpr->index == dumpr->script->parts->nelts) {
@ -34,7 +35,7 @@ static const char* dump_reader(lua_State* L, void* user_data, size_t* size) {
}
/* Get one chunk. */
msc_script_part *part = ((msc_script_part **)dumpr->script->parts->elts)[dumpr->index];
part = ((msc_script_part **)dumpr->script->parts->elts)[dumpr->index];
*size = part->len;
dumpr->index++;
@ -47,9 +48,10 @@ static const char* dump_reader(lua_State* L, void* user_data, size_t* size) {
*/
static int dump_writer(lua_State *L, const void* data, size_t len, void* user_data) {
msc_lua_dumpw_t *dump = (msc_lua_dumpw_t *)user_data;
msc_script_part *part;
/* Allocate new part, copy the data into it. */
msc_script_part *part = apr_palloc(dump->pool, sizeof(msc_script_part));
part = apr_palloc(dump->pool, sizeof(msc_script_part));
part->data = apr_palloc(dump->pool, len);
part->len = len;
memcpy((void *)part->data, data, len);
@ -197,6 +199,7 @@ static int l_getvar(lua_State *L) {
char *p1 = NULL;
apr_array_header_t *tfn_arr = NULL;
msre_var *vx = NULL;
msre_var *var;
/* Retrieve parameters. */
p1 = (char *)luaL_checkstring(L, 1);
@ -218,7 +221,7 @@ static int l_getvar(lua_State *L) {
}
/* Resolve variable. */
msre_var *var = msre_create_var_ex(msr->msc_rule_mptmp, msr->modsecurity->msre,
var = msre_create_var_ex(msr->msc_rule_mptmp, msr->modsecurity->msre,
varname, param, msr, &my_error_msg);
if (var == NULL) {

View File

@ -194,16 +194,20 @@ static int msre_op_rx_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, c
/* pm */
static int msre_op_pm_param_init(msre_rule *rule, char **error_msg) {
ACMP *p;
const char *phrase;
const char *next;
if ((rule->op_param == NULL)||(strlen(rule->op_param) == 0)) {
*error_msg = apr_psprintf(rule->ruleset->mp, "Missing parameter for operator 'pm'.");
return 0; /* ERROR */
}
ACMP *p = acmp_create(0, rule->ruleset->mp);
p = acmp_create(0, rule->ruleset->mp);
if (p == NULL) return 0;
const char *phrase = apr_pstrdup(rule->ruleset->mp, rule->op_param);
const char *next = rule->op_param + strlen(rule->op_param);
phrase = apr_pstrdup(rule->ruleset->mp, rule->op_param);
next = rule->op_param + strlen(rule->op_param);
/* Loop through phrases */
/* ENH: Need to allow quoted phrases w/space */
@ -231,13 +235,14 @@ static int msre_op_pmFromFile_param_init(msre_rule *rule, char **error_msg) {
const char *rulefile_path;
apr_status_t rc;
apr_file_t *fd;
ACMP *p;
if ((rule->op_param == NULL)||(strlen(rule->op_param) == 0)) {
*error_msg = apr_psprintf(rule->ruleset->mp, "Missing parameter for operator 'pm'.");
return 0; /* ERROR */
}
ACMP *p = acmp_create(0, rule->ruleset->mp);
p = acmp_create(0, rule->ruleset->mp);
if (p == NULL) return 0;
fn = apr_pstrdup(rule->ruleset->mp, rule->op_param);
@ -321,6 +326,7 @@ static int msre_op_pm_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, c
const char *match = NULL;
apr_status_t rc = 0;
int capture;
ACMPT pt;
/* Nothing to read */
if ((var->value == NULL) || (var->value_len == 0)) return 0;
@ -328,7 +334,8 @@ static int msre_op_pm_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, c
/* Are we supposed to capture subexpressions? */
capture = apr_table_get(rule->actionset->actions, "capture") ? 1 : 0;
ACMPT pt = {(ACMP *)rule->op_param_data, NULL};
pt.parser = (ACMP *)rule->op_param_data;
pt.ptr = NULL;
rc = acmp_process_quick(&pt, &match, var->value, var->value_len);
if (rc) {

View File

@ -3,7 +3,7 @@
<title>ModSecurity Reference Manual</title>
<articleinfo>
<releaseinfo>Version 2.5.0-rc3 (February 11, 2008)</releaseinfo>
<releaseinfo>Version 2.5.0-rc4 (February 12, 2008)</releaseinfo>
<copyright>
<year>2004-2008</year>
@ -313,67 +313,100 @@
url="http://www.lua.org/download.html">http://www.lua.org/download.html</ulink></para>
</listitem>
<listitem>
<para>Unpack the ModSecurity archive</para>
</listitem>
<listitem>
<para>Run the configure script to generate a Makefile. Typically no
options are needed.</para>
<para><literal>./configure</literal></para>
<para>Options are available for more customization (use
<literal>./configure --help</literal> for a full list), but typically
you will only need to specify the location of the
<literal>apxs</literal> command installed by Apache httpd with the
<literal>--with-apxs</literal> option.</para>
<para><literal>./configure
--with-apxs=/path/to/httpd-2.x.y/bin/apxs</literal></para>
</listitem>
<listitem>
<para>Compile with: <literal>make</literal></para>
</listitem>
<listitem>
<para>Optionally test with: <literal>make test</literal></para>
</listitem>
<listitem>
<para>Optionally build the ModSecurity Log Collector with:
<literal>make mlogc</literal></para>
</listitem>
<listitem>
<para>Stop Apache httpd</para>
</listitem>
<listitem>
<para>Optionally install <literal>mlogc</literal>: Review the
<literal>INSTALL</literal> file included in the apache2/mlogc-src
directory in the distribution.</para>
<para>Unpack the ModSecurity archive</para>
</listitem>
<listitem>
<para>Install the ModSecurity module with: <literal>make
install</literal></para>
<para>Building differs for UNIX (or UNIX-like) operating systems and
Windows.</para>
<itemizedlist>
<listitem>
<para>UNIX</para>
<orderedlist>
<listitem>
<para>Run the configure script to generate a Makefile.
Typically no options are needed.</para>
<para><literal>./configure</literal></para>
<para>Options are available for more customization (use
<literal>./configure --help</literal> for a full list), but
typically you will only need to specify the location of the
<literal>apxs</literal> command installed by Apache httpd with
the <literal>--with-apxs</literal> option.</para>
<para><literal>./configure
--with-apxs=/path/to/httpd-2.x.y/bin/apxs</literal></para>
</listitem>
<listitem>
<para>Compile with: <literal>make</literal></para>
</listitem>
<listitem>
<para>Optionally test with: <literal>make
test</literal></para>
</listitem>
<listitem>
<para>Optionally build the ModSecurity Log Collector with:
<literal>make mlogc</literal></para>
</listitem>
<listitem>
<para>Optionally install <literal>mlogc</literal>: Review the
<literal>INSTALL</literal> file included in the
apache2/mlogc-src directory in the distribution.</para>
</listitem>
<listitem>
<para>Install the ModSecurity module with: <literal>make
install</literal></para>
</listitem>
</orderedlist>
</listitem>
<listitem>
<para>Windows (MS VC++ 8)</para>
<orderedlist>
<listitem>
<para>Edit <literal>Makefile.win</literal> to configure the
Apache base and library paths.</para>
</listitem>
<listitem>
<para>Compile with: <literal>nmake -f
Makefile.win</literal></para>
</listitem>
<listitem>
<para>Install the ModSecurity module with: <literal>nmake -f
Makefile.win install</literal></para>
</listitem>
</orderedlist>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para>Load libxml2 before ModSecurity: <literal>LoadFile
/usr/lib/libxml2.so</literal></para>
</listitem>
<para>Edit the main Apache httpd config file (usually
<literal>httpd.conf</literal>)</para>
<listitem>
<para>Load Lua before ModSecurity: <literal>LoadFile
/usr/lib/liblua5.1.so.</literal></para>
</listitem>
<para>On UNIX you must load libxml2 and lua before ModSecurity with
something like this:</para>
<listitem>
<para>Load ModSecurity itself: <literal>LoadModule security2_module
modules/mod_security2.so</literal></para>
<para><programlisting>LoadFile /usr/lib/libxml2.so
LoadFile /usr/lib/liblua5.1.so</programlisting></para>
<para>Load the ModSecurity module with:<programlisting>LoadModule security2_module modules/mod_security2.so</programlisting></para>
</listitem>
<listitem>
@ -385,7 +418,7 @@
</listitem>
<listitem>
<para>You now have ModSecurity 2.x up and running.</para>
<para>You should now have ModSecurity 2.x up and running.</para>
</listitem>
</orderedlist>
@ -5732,4 +5765,4 @@ Server: Apache/2.x.x
</section>
</section>
</section>
</article>
</article>