-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added Windows build scripts using Build Tools for Visual Studio 2022 …
…(MSVC compiler & CMake) and Conan package manager - Included Dockerfile to automate the setup process of prerequisites and build of libModSecurity binaries.
- Loading branch information
Showing
9 changed files
with
583 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,196 @@ | ||
cmake_minimum_required(VERSION 3.15) | ||
|
||
set(BASE_DIR ${CMAKE_CURRENT_LIST_DIR}/../..) | ||
|
||
set(USE_ASAN OFF CACHE BOOL "Build with Address Sanitizer") | ||
|
||
# common compiler settings | ||
|
||
# NOTE: MBEDTLS_CONFIG_FILE is not only required to compile the mbedtls subset in others, but also | ||
# when their headers are included while compiling libModSecurity | ||
add_compile_definitions(WIN32 _CRT_SECURE_NO_WARNINGS MBEDTLS_CONFIG_FILE="mbed-tls-config.h") | ||
|
||
# set standards conformance preprocessor & compiler to align with cross-compiled codebase | ||
# NOTE: otherwise visual c++'s default compiler/preprocessor behaviour generates C4067 warnings | ||
# (unexpected tokens following preprocessor directive - expected a newline) | ||
add_compile_options(/Zc:preprocessor /permissive-) | ||
|
||
if(USE_ASAN) | ||
add_compile_options(/fsanitize=address) | ||
add_link_options(/INFERASANLIBS /INCREMENTAL:no) | ||
endif() | ||
|
||
# libinjection | ||
|
||
project(libinjection C) | ||
|
||
add_library(libinjection STATIC ${BASE_DIR}/others/libinjection/src/libinjection_sqli.c ${BASE_DIR}/others/libinjection/src/libinjection_xss.c ${BASE_DIR}/others/libinjection/src/libinjection_html5.c) | ||
|
||
# mbedtls | ||
|
||
project(mbedtls C) | ||
|
||
add_library(mbedtls STATIC ${BASE_DIR}/others/mbedtls/base64.c ${BASE_DIR}/others/mbedtls/sha1.c ${BASE_DIR}/others/mbedtls/md5.c) | ||
|
||
target_include_directories(mbedtls PRIVATE ${BASE_DIR}/others) | ||
|
||
# | ||
# libModSecurity | ||
# | ||
|
||
project(libModSecurity | ||
VERSION | ||
3.0.12 | ||
LANGUAGES | ||
CXX | ||
) | ||
|
||
set(CMAKE_CXX_STANDARD 17) | ||
set(CMAKE_CXX_STANDARD_REQUIRED On) | ||
set(CMAKE_CXX_EXTENSIONS Off) | ||
|
||
set(PACKAGE_BUGREPORT "security@modsecurity.org") | ||
set(PACKAGE_NAME "modsecurity") | ||
set(PACKAGE_VERSION "${PROJECT_VERSION}") | ||
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") | ||
set(PACKAGE_TARNAME "${PACKAGE_NAME}") | ||
|
||
set(HAVE_GEOIP 0) # should always be zero, no conan package available | ||
set(HAVE_LMDB 1) | ||
set(HAVE_LUA 1) | ||
set(HAVE_LIBXML2 1) | ||
set(HAVE_MAXMIND 1) | ||
set(HAVE_SSDEEP 0) # should always be zero, no conan package available | ||
set(HAVE_YAJL 1) # should always be one, mandatory dependency | ||
set(HAVE_CURL 1) | ||
|
||
include(${CMAKE_CURRENT_LIST_DIR}/ConfigureChecks.cmake) | ||
|
||
configure_file(config.h.cmake ${BASE_DIR}/src/config.h) | ||
|
||
find_package(PCRE2 REQUIRED) | ||
find_package(PThreads4W REQUIRED) | ||
find_package(Poco REQUIRED) | ||
find_package(dirent REQUIRED) # used only by tests (check dirent::dirent refernces) | ||
|
||
macro(include_package package flag) | ||
if(${flag}) | ||
find_package(${package} REQUIRED) | ||
endif() | ||
endmacro() | ||
|
||
include_package(yajl HAVE_YAJL) | ||
include_package(libxml2 HAVE_LIBXML2) | ||
include_package(lua HAVE_LUA) | ||
include_package(CURL HAVE_CURL) | ||
include_package(lmdb HAVE_LMDB) | ||
include_package(maxminddb HAVE_MAXMIND) | ||
|
||
# library | ||
# | ||
|
||
# NOTE: required to generate libModSecurity's import library (libModSecurity.lib), used by tests to link with shared library | ||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) | ||
|
||
file(GLOB_RECURSE libModSecuritySources ${BASE_DIR}/src/*.cc) | ||
|
||
add_library(libModSecurity SHARED ${libModSecuritySources}) | ||
|
||
target_compile_definitions(libModSecurity PRIVATE WITH_PCRE2) | ||
target_include_directories(libModSecurity PRIVATE ${BASE_DIR} ${BASE_DIR}/headers ${BASE_DIR}/others) | ||
target_link_libraries(libModSecurity PRIVATE pcre2::pcre2 pthreads4w::pthreads4w libinjection mbedtls Poco::Poco Iphlpapi.lib) | ||
|
||
macro(add_package_dependency project compile_definition link_library flag) | ||
if(${flag}) | ||
target_compile_definitions(${project} PRIVATE ${compile_definition}) | ||
target_link_libraries(${project} PRIVATE ${link_library}) | ||
endif() | ||
endmacro() | ||
|
||
add_package_dependency(libModSecurity WITH_YAJL yajl::yajl HAVE_YAJL) | ||
add_package_dependency(libModSecurity WITH_LIBXML2 LibXml2::LibXml2 HAVE_LIBXML2) | ||
add_package_dependency(libModSecurity WITH_LUA lua::lua HAVE_LUA) | ||
if(HAVE_LUA) | ||
target_compile_definitions(libModSecurity PRIVATE WITH_LUA_5_4) | ||
endif() | ||
add_package_dependency(libModSecurity MSC_WITH_CURL CURL::libcurl HAVE_CURL) | ||
add_package_dependency(libModSecurity WITH_LMDB lmdb::lmdb HAVE_LMDB) | ||
add_package_dependency(libModSecurity WITH_MAXMIND maxminddb::maxminddb HAVE_MAXMIND) | ||
|
||
# tests | ||
# | ||
|
||
project(libModSecurityTests) | ||
|
||
function(setTestTargetProperties executable) | ||
target_compile_definitions(${executable} PRIVATE WITH_PCRE2) | ||
target_include_directories(${executable} PRIVATE ${BASE_DIR} ${BASE_DIR}/headers) | ||
target_link_libraries(${executable} PRIVATE libModSecurity pcre2::pcre2 dirent::dirent) | ||
add_package_dependency(${executable} WITH_YAJL yajl::yajl HAVE_YAJL) | ||
endfunction() | ||
|
||
# unit tests | ||
file(GLOB unitTestSources ${BASE_DIR}/test/unit/*.cc) | ||
add_executable(unit_tests ${unitTestSources}) | ||
setTestTargetProperties(unit_tests) | ||
target_compile_options(unit_tests PRIVATE /wd4805) | ||
|
||
# regression tests | ||
file(GLOB regressionTestsSources ${BASE_DIR}/test/regression/*.cc) | ||
add_executable(regression_tests ${regressionTestsSources}) | ||
setTestTargetProperties(regression_tests) | ||
|
||
macro(add_regression_test_capability compile_definition flag) | ||
if(${flag}) | ||
target_compile_definitions(regression_tests PRIVATE ${compile_definition}) | ||
endif() | ||
endmacro() | ||
|
||
add_regression_test_capability(WITH_LUA HAVE_LUA) | ||
add_regression_test_capability(WITH_CURL HAVE_CURL) | ||
add_regression_test_capability(WITH_LMDB HAVE_LMDB) | ||
add_regression_test_capability(WITH_MAXMIND HAVE_MAXMIND) | ||
|
||
# benchmark | ||
add_executable(benchmark ${BASE_DIR}/test/benchmark/benchmark.cc) | ||
setTestTargetProperties(benchmark) | ||
|
||
# rules_optimization | ||
add_executable(rules_optimization ${BASE_DIR}/test/optimization/optimization.cc) | ||
setTestTargetProperties(rules_optimization) | ||
|
||
|
||
# examples | ||
# | ||
|
||
project(libModSecurityExamples) | ||
|
||
function(setExampleTargetProperties executable) | ||
target_include_directories(${executable} PRIVATE ${BASE_DIR} ${BASE_DIR}/headers) | ||
target_link_libraries(${executable} PRIVATE libModSecurity) | ||
endfunction() | ||
|
||
# simple_example_using_c | ||
add_executable(simple_example_using_c ${BASE_DIR}/examples/simple_example_using_c/test.c) | ||
setExampleTargetProperties(simple_example_using_c) | ||
|
||
# using_bodies_in_chunks | ||
add_executable(using_bodies_in_chunks ${BASE_DIR}/examples/using_bodies_in_chunks/simple_request.cc) | ||
setExampleTargetProperties(using_bodies_in_chunks) | ||
|
||
# reading_logs_via_rule_message | ||
add_executable(reading_logs_via_rule_message ${BASE_DIR}/examples/reading_logs_via_rule_message/simple_request.cc) | ||
setExampleTargetProperties(reading_logs_via_rule_message) | ||
target_link_libraries(reading_logs_via_rule_message PRIVATE libModSecurity pthreads4w::pthreads4w) | ||
|
||
# reading_logs_with_offset | ||
add_executable(reading_logs_with_offset ${BASE_DIR}/examples/reading_logs_with_offset/read.cc) | ||
setExampleTargetProperties(reading_logs_with_offset) | ||
|
||
# tools | ||
# | ||
|
||
# rules_check | ||
add_executable(rules_check ${BASE_DIR}/tools/rules-check/rules-check.cc) | ||
target_include_directories(rules_check PRIVATE ${BASE_DIR} ${BASE_DIR}/headers) | ||
target_link_libraries(rules_check PRIVATE libModSecurity) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
include(CheckIncludeFile) | ||
include(CheckIncludeFiles) | ||
|
||
check_include_file("dlfcn.h" HAVE_DLFCN_H) | ||
check_include_file("inttypes.h" HAVE_INTTYPES_H) | ||
check_include_file("stdint.h" HAVE_STDINT_H) | ||
check_include_file("stdio.h" HAVE_STDIO_H) | ||
check_include_file("stdlib.h" HAVE_STDLIB_H) | ||
check_include_file("string" HAVE_STRING) | ||
check_include_file("strings.h" HAVE_STRINGS_H) | ||
check_include_file("string.h" HAVE_STRING_H) | ||
check_include_file("sys/stat.h" HAVE_SYS_STAT_H) | ||
check_include_file("sys/types.h" HAVE_SYS_TYPES_H) | ||
check_include_file("sys/utsname.h" HAVE_SYS_UTSNAME_H) | ||
check_include_file("unistd.h" HAVE_UNISTD_H) | ||
|
||
#/* Define to 1 if you have the ANSI C header files. */ | ||
check_include_files("stdlib.h;stdarg.h;string.h;float.h" STDC_HEADERS) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
# libModSecurity Windows build information <!-- omit from toc --> | ||
|
||
The Windows build of libModSecurity uses Build Tools for Visual Studio 2022 (for Visual C++ & CMake) and Conan package manager. | ||
|
||
## Contents <!-- omit from toc --> | ||
|
||
- [Prerequisites](#prerequisites) | ||
- [Build](#build) | ||
- [Optional features](#optional-features) | ||
- [Address Sanitizer](#address-sanitizer) | ||
- [Docker container](#docker-container) | ||
|
||
## Prerequisites | ||
|
||
* [Build Tools for Visual Studio 2022](https://aka.ms/vs/17/release/vs_buildtools.exe) | ||
* Install *Desktop development with C++* workload, which includes: | ||
* MSVC C++ compiler | ||
* Windows SDK | ||
* CMake | ||
* Address Sanitizer | ||
* [Conan package manager 2.2.2](https://github.com/conan-io/conan/releases/download/2.2.2/conan-2.2.2-windows-x86_64-installer.exe) | ||
* Install and then setup the default Conan profile to use the MSVC C++ compiler: | ||
1. Open a command-prompt and set the MSVC C++ compiler environment by executing: `C:\BuildTools\VC\Auxiliary\Build\vcvars64.bat` | ||
2. Execute: `conan profile detect --force` | ||
* [Git for Windows 2.44.0](https://github.com/git-for-windows/git/releases/download/v2.44.0.windows.1/Git-2.44.0-64-bit.exe) | ||
* To clone the libModSecurity repository. | ||
* NOTE: Make sure to initialize and update submodules (to get `libinjection` and regression tests) | ||
* `git submodule init` | ||
* `git submodule update` | ||
|
||
## Build | ||
|
||
Install the prerequisites listsed in the previous section, checkout libModSecurity and from the directory where it's located execute: | ||
|
||
``` | ||
vcbuild.bat [build_configuration] [arch] [USE_ASAN] | ||
``` | ||
|
||
where `[build_configuration]` can be: `Release` (default), `RelWithDebInfo`, `MinSizeRel` or `Debug`, and `[arch]` can be: `x86_64` (default) or `x86`. | ||
|
||
Built files will be located in the directory: `build\win32\build\[build_configuration]` and include: | ||
|
||
* `libModSecurity.dll` | ||
* Executable files for test projects | ||
* `unit_tests.exe` | ||
* `regression_tests.exe` | ||
* `benchmark.exe` | ||
* `rules_optimization.exe` | ||
* Executable files for examples | ||
* `simple_example_using_c.exe` | ||
* `using_bodies_in_chunks.exe` | ||
* `reading_logs_via_rule_message.exe` | ||
* `reading_logs_with_offset.exe` | ||
* Executable files for tools | ||
* `rules_check.exe` | ||
|
||
NOTE: When building a different configuration, it's recommended to reset: | ||
|
||
* the build directory: `build\win32\build` | ||
* previously built conan packages executing the command: | ||
* `conan remove * -c` | ||
|
||
### Optional features | ||
|
||
By default the following all the following features are enabled by including the associated third-party library through a Conan package: | ||
|
||
* libxml2 2.12.6 for XML processing support | ||
* libcurl 8.6.0 to support http requests from rules | ||
* libmaxminddb 1.9.1 to support reading MaxMind DB files. | ||
* LUA 5.4.6 to enable rules to run scripts in this language for extensibility | ||
* lmdb 0.9.31 in-memory database | ||
|
||
Each of these can be turned off by updating the associated `HAVE_xxx` variable (setting it to zero) in the beginning of the libModSecurity section of `CMakeLists.txt`. | ||
|
||
### Address Sanitizer | ||
|
||
[AddressSanitizer](https://github.com/google/sanitizers/wiki/AddressSanitizer) (aka ASan) is a memory error detector for C/C++. | ||
|
||
To generate a build with *Address Sanitizer*, add the `USE_ASAN` optional third argument to `vcbuild.bat`. For example: | ||
* `vcbuild.bat Debug x86_64 USE_ASAN` | ||
|
||
NOTE: `USE_ASAN` does not work with `Release` & `MinSizeRel` configurations because they do not include debug info (it is only compatible with `Debug` & `RelWithDebInfo` builds). | ||
|
||
* References | ||
* [AddressSanitizer | Microsoft Learn](https://learn.microsoft.com/en-us/cpp/sanitizers/asan?view=msvc-170) | ||
* [AddressSanitizer for Windows: x64 and Debug Build Support - C++ Team Blog (microsoft.com)](https://devblogs.microsoft.com/cppblog/asan-for-windows-x64-and-debug-build-support/) | ||
* [AddressSanitizer language, build, and debugging reference | Microsoft Learn](https://learn.microsoft.com/en-us/cpp/sanitizers/asan-building?view=msvc-170) | ||
|
||
### Docker container | ||
|
||
A `Dockerfile` configuration file is provided in the `docker` subdir that creates a Windows container image which installs the [prerequisites](#prerequisites) and builds libModSecurity and other binaries. | ||
|
||
NOTE: Windows containers are supported in Docker Desktop for Windows, using the *Switch to Windows containers...* option on the context menu of the system tray icon. | ||
|
||
To build the docker image, execute the following command (from the `build\win32\docker` directory): | ||
|
||
* `docker build -t buildtools_libmodsecurity:latest -m 4GB .` | ||
* Build type, architecture and build with Address Sanitizer can be configured through build arguments (`BUILD_TYPE`, `ARCH` & `USE_ASAN` respectively). For example, to generate a debug build, add the following argument: | ||
* `--build-arg BUILD_TYPE=Debug` | ||
|
||
Once the image is generated, the library and associated binaries (tests & examples) are located in the `C:\src\ModSecurity\build\win32\build\[build_type]` directory. | ||
|
||
To extract the library (`libModSecurity.dll`) from the image, you can execute the following commands: | ||
|
||
* `docker container create --name [container_name] buildtools_libmodsecurity` | ||
* `docker cp [container_name]:C:\src\ModSecurity\build\win32\build\[build_type]\libModSecurity.dll .` | ||
* NOTE: If you leave out the `libModSecurity.dll` filename out, you can copy all the built binaries (including examples & tests). | ||
|
||
Additionally, the image can be used interactively for additional development work by executing: | ||
|
||
* `docker run -it buildtools_libmodsecurity` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
[requires] | ||
yajl/2.1.0 | ||
pcre2/10.42 | ||
pthreads4w/3.0.0 | ||
libxml2/2.12.6 | ||
lua/5.4.6 | ||
libcurl/8.6.0 | ||
lmdb/0.9.31 | ||
libmaxminddb/1.9.1 | ||
dirent/1.24 | ||
poco/1.13.3 | ||
|
||
[generators] | ||
CMakeDeps | ||
CMakeToolchain |
Oops, something went wrong.