Compare commits

...

421 Commits

Author SHA1 Message Date
Ervin Hegedus
a07ed61e74
Merge pull request #3432 from szedenik-adam/auditlog-header
Add custom leading text to audit log lines
2025-08-13 20:45:19 +03:00
szedenik-adam
4e2788eb47 Merge branch 'v3/master' into auditlog-header 2025-08-13 09:26:21 +02:00
Ervin Hegedus
f9f4011a4b
Merge pull request #3434 from airween/v3/cppcheckfix2
chore: fix cppcheck warning
2025-08-13 10:04:20 +03:00
Ervin Hegedus
62cb73f31d
Add const modifier to variable 2025-08-12 21:36:52 +02:00
Ervin Hegedus
8b3269f4d1
Try to avoid any kind of type casting 2025-08-12 21:05:31 +02:00
Ervin Hegedus
e879711d87
Add extra SonarCloud supression msg; Change type to auto 2025-08-11 23:05:32 +02:00
Ervin Hegedus
9fea1ca454
Change cast type (fix SonarCloud issues) 2025-08-11 22:41:07 +02:00
Ervin Hegedus
47bc24a808
Decrease code nest level 2025-08-11 22:28:22 +02:00
Ervin Hegedus
12809656a6
Remove redundant parenthesis 2025-08-11 22:02:37 +02:00
Ervin Hegedus
ea51a663f1
Move seclang-parser.hh supression to the right place 2025-08-11 17:19:46 +02:00
Ervin Hegedus
d19d3b4785
Supress uninitMemberVar warning in seclang-parser.hh 2025-08-11 16:43:58 +02:00
Ervin Hegedus
67f32a4e63
Fix cppcheck 2.18.0 warnings 2025-08-11 15:51:49 +02:00
szedenik-adam
6c6d94fc66 Renamed SecAuditLogHeader to SecAuditLogPrefix 2025-08-11 10:30:01 +02:00
szedenik-adam
0f402f33fd Adapted AuditLog based on code check hints 2025-08-07 11:01:44 +02:00
szedenik-adam
01c427f6be Replaced initializer list with in-class initializer in AuditLog 2025-08-07 10:23:50 +02:00
szedenik-adam
31fb9390c2 Replaced string parameters with string_view in AuditLog 2025-08-07 10:22:42 +02:00
szedenik-adam
2ee45de2fc Added audit log header 2025-08-04 17:09:49 +02:00
Ervin Hegedus
0ac551b070
Merge pull request #3430 from airween/v3/confvaluepathfix
fix: add Windows specific characters to config value syntax
2025-08-03 11:06:00 +03:00
Ervin Hegedus
013c8c2c7b
Remove escape from meta characters again 2025-08-01 13:28:19 +02:00
Ervin Hegedus
d8574c8c08
Fix date format pattern in auditlog's regression test 2025-08-01 11:38:39 +02:00
Ervin Hegedus
37948704df
Revert "Remove escape from meta characters"
This reverts commit 28bc3a98df54e251861d26dbb9f1374f622b97ea.
2025-08-01 09:33:22 +02:00
Ervin Hegedus
28bc3a98df
Remove escape from meta characters
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-08-01 09:11:20 +02:00
Ervin Hegedus
72e3abdd12
Add Windows specific characters to config value syntax in config parser 2025-07-30 14:37:27 +02:00
Ervin Hegedus
f2170d8576
Merge pull request #3426 from wooffie/fix-rx-476
fix: rx operators better null checks
2025-07-29 15:48:47 +03:00
Burkov Egor
c60709a58c fix: rx operators better null checks 2025-07-29 13:18:48 +03:00
Ervin Hegedus
1ff9f2a943
Merge pull request #3421 from airween/v3/secreqbodylimit
fix: integer type limits, 2nd try
2025-07-28 22:44:47 +03:00
Ervin Hegedus
690355b297
Merge pull request #3424 from wooffie/patch-1
fix: confusing indentation at acmp.cc
2025-07-28 19:07:27 +03:00
Burkov Egor
78b9cb7b57 Add more brackets 2025-07-28 15:11:02 +03:00
Burkov Egor
5d05ba359c
fix: confusing indentation at acmp.cc 2025-07-28 14:23:11 +03:00
Ervin Hegedus
9fb75d2c9a
Reformat code block with brackets
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-07-28 10:38:01 +02:00
Ervin Hegedus
abed778b4a
Remove unused ConfigDouble class 2025-07-27 17:28:26 +02:00
Ervin Hegedus
8d15991fb4
Update comment
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-07-27 17:14:12 +02:00
Ervin Hegedus
b8a22bb67a
Update error message
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-07-27 17:09:11 +02:00
Ervin Hegedus
7e3c807c0d
Change syntax: add brackets to condition block 2025-07-27 17:07:12 +02:00
Ervin Hegedus
bb70ff06a4
Refactoring the cleaning of MATCHED_VAR* variables 2025-07-27 17:07:12 +02:00
Ervin Hegedus
08b70e006b
Merge pull request #3422 from airween/v3/matchedvarsfix2
Refactoring the cleaning of MATCHED_VAR* variables
2025-07-27 18:00:45 +03:00
Ervin Hegedus
79d55037c0
Refactoring the cleaning of MATCHED_VAR* variables 2025-07-25 14:33:24 +02:00
Ervin Hegedus
9a8ce8b5f5
Refactoring Config*Int types 2025-07-24 19:21:15 +02:00
Ervin Hegedus
cf24aeaead
Merge pull request #3405 from airween/v3/pmfromffix
fix: @pmFromFile with multiple files issue
2025-06-20 09:29:36 +02:00
Ervin Hegedus
6089b6b06b
Fix @pmFromFile with multiple files issue 2025-06-19 21:49:05 +02:00
Ervin Hegedus
31507404e6
Merge pull request #3392 from amezin/macaddr-resource-leak
Fix memory/socket leak in `UniqueId::ethernetMacAddress()`
2025-06-07 13:23:46 +02:00
Ervin Hegedus
f64ea2a708
Merge pull request #3390 from arvedarved/buildsystem-fixes
Buildsystem fixes
2025-06-07 09:06:04 +02:00
Ervin Hegedus
1362479d34
Merge pull request #3393 from JakubOnderka/json-log-hostname
Add hostname to JSON log
2025-05-28 22:55:57 +02:00
Jakub Onderka
8d3b2cacc4 Add hostname to JSON log 2025-05-28 16:24:09 +02:00
Aleksandr Mezin
a17193f7af Fix memory/socket leak in UniqueId::ethernetMacAddress()
Don't jump over `close()`/`free()`
2025-05-27 12:42:36 +03:00
Tilman Keskinöz
de624f9460
Attempt to fix bogus change.
Reported by: CI via Ervin Hegedus
2025-05-23 10:28:38 +02:00
Tilman Keskinöz
7660125da6
buildfix for srcdir != builddir
automake doesn't support wildcards.
See https://www.gnu.org/software/automake/manual/html_node/Wildcards.html
for details.

Use the GNU make $(wildcard ) extension.

Note: this breaks with non-GNU make
2025-05-22 18:59:56 +02:00
Tilman Keskinöz
0caf30679f
buildfix
If libxml2 is in a non-default directory, it needs to be added
to LDFLAGS
2025-05-22 18:59:55 +02:00
Tilman Keskinöz
0bcabf3208
buildfix for srcdir != builddir 2025-05-22 18:59:51 +02:00
Ervin Hegedus
aab47091b1
Merge pull request #3364 from JakubOnderka/json-logging
Simplify code for JSON audit log
2025-05-11 10:54:47 +02:00
Ervin Hegedus
990d99b1fb
Merge pull request #3365 from JakubOnderka/disable-expect
Disable Expect when sending audit logs to remote HTTP server
2025-05-11 10:50:10 +02:00
Ervin Hegedus
220caa5abc
Merge pull request #3363 from airween/v3/xmlargsfeat
feat: improved XMLArgs processing
2025-05-04 19:46:18 +02:00
Ervin Hegedus
a3876e3c99
Avoid unvanted content parse (whitespaces between tags) 2025-05-02 22:34:03 +02:00
Ervin Hegedus
d228ea6607
Update comment
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-05-01 22:28:27 +02:00
Ervin Hegedus
89442ede16
Change directives in tests; add multibyte test case 2025-04-28 22:35:22 +02:00
Ervin Hegedus
e8dc60ee06
Change node value's parsing to concatenate instead of copy it every time 2025-04-28 22:34:26 +02:00
Ervin Hegedus
bf707de08f
Change directive format to strict camel case 2025-04-28 21:58:18 +02:00
Ervin Hegedus
0b62b7eb85
Align debug messages to fix regression tests 2025-04-27 21:09:49 +02:00
Ervin Hegedus
91a45e79bd
Update error message
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:28:30 +02:00
Ervin Hegedus
2135c8934e
Update comment
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:28:07 +02:00
Ervin Hegedus
8947346cd4
Update comment
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:27:47 +02:00
Ervin Hegedus
67429307cc
Update comment
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:27:26 +02:00
Ervin Hegedus
0c7ea21a26
Update comment
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:27:04 +02:00
Ervin Hegedus
72de7e8400
Update comment
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:26:37 +02:00
Ervin Hegedus
0bf60208af
Add explanation
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:26:09 +02:00
Ervin Hegedus
2000f4c048
Update comment
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:25:20 +02:00
Ervin Hegedus
159f6120aa
Update comment
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:24:47 +02:00
Ervin Hegedus
bbe7eda693
Update explanation
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:23:02 +02:00
Ervin Hegedus
0fcd257fc4
Update comment
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:22:14 +02:00
Ervin Hegedus
fedc70983c
Update comment
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:21:45 +02:00
Ervin Hegedus
5b1c6fbf68
Update comment
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:21:24 +02:00
Ervin Hegedus
eedfed873e
Update error message
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:21:03 +02:00
Ervin Hegedus
f0aa0700fe
Update comment
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:20:49 +02:00
Ervin Hegedus
90be54e25e
Update error message
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:20:22 +02:00
Ervin Hegedus
3dc9fe990c
Update comment
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:19:11 +02:00
Ervin Hegedus
e3678764e5
Update comment
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:18:47 +02:00
Ervin Hegedus
22fee1296d
Change owner in legal text 2025-04-26 20:54:36 +02:00
Jakub Onderka
b82d600049 Disable Expect when sending audit logs to remote HTTP server
This will speed-up sending logs to remote server
2025-04-23 16:19:30 +02:00
Jakub Onderka
797f7dc4b2 Change http_version field in JSON audit log to string
Sometimes m_httpVersion variable can be empty and then invalid JSON is generated
2025-04-23 10:59:10 +02:00
Jakub Onderka
6408bf9237 Test for JSON audit log 2025-04-22 21:09:42 +02:00
Jakub Onderka
37c0de363e Simplify code for JSON audit log 2025-04-22 19:41:08 +02:00
Ervin Hegedus
029684c294
Add nullptr check conditions 2025-04-20 21:35:54 +02:00
Ervin Hegedus
3e95614699
Add nullptr check conditions 2025-04-20 21:10:43 +02:00
Ervin Hegedus
b42602f400
Fix more cppcheck warning 2025-04-20 19:31:20 +02:00
Ervin Hegedus
8ae8374be5
Fix cppcheck errors 2025-04-20 19:01:45 +02:00
Ervin Hegedus
f62de58632
Added new cc and h files 2025-04-20 18:29:59 +02:00
Ervin Hegedus
9e41a53760
Finish XMLArgs processing in v3 2025-04-20 18:21:28 +02:00
Ervin Hegedus
01a0615887
Merge pull request #3354 from cjihrig/patch-1
doc: update testing section of README
2025-03-23 20:31:29 +01:00
Colin Ihrig
80019da75e
doc: update testing section of README
The regression_tests and unit_tests scripts appear to
be named with underscores instead of hyphens. This
commit updates the README to reflect this.
2025-03-23 12:59:02 -04:00
Ervin Hegedus
7a986c7bae
Merge pull request #3350 from airween/v3/cppcheckfix
fix: align code to fix cppcheck errors
2025-03-14 09:06:27 +01:00
Ervin Hegedus
8f00f4700f
Make destructor default; remove impmelentation 2025-03-12 23:07:43 +01:00
Ervin Hegedus
42280d213d
Make function argument const pointer 2025-03-12 22:26:29 +01:00
Ervin Hegedus
c3c2c6f280
Make variable const pointer 2025-03-12 22:19:00 +01:00
Ervin Hegedus
dbdd6318ff
Replace C pointers by shared pointer in fuzzy_hash op code 2025-03-12 22:09:51 +01:00
Ervin Hegedus
d3c1ad7177
Make utf variable const pointer 2025-03-12 22:07:46 +01:00
Ervin Hegedus
dc40880663
Fix cppcheck error in example multi.c 2025-03-12 20:45:47 +01:00
Ervin Hegedus
1a2b13967f
Merge pull request #3321 from gberkes/refactor/default-pcre2
Refactor/default pcre2
2025-03-12 18:16:35 +01:00
Ervin Hegedus
a555e5a445
Merge commit from fork
fix: fixed htmlEntityDecode methods
2025-02-25 14:50:05 +01:00
Ervin Hegedus
646881085c
Change release version to v3.0.14 2025-02-25 10:52:04 +01:00
Ervin Hegedus
29c3cc32e1
doc: update CHANGES 2025-02-24 18:35:13 +01:00
Ervin Hegedus
c82e831b66
fix: fixed htmlEntityDecode methods 2025-02-24 16:44:17 +01:00
Ervin Hegedus
f96806cd28
Merge pull request #3342 from airween/v3/gcc15fix
fix: Added missing header to avoid build error with gcc-15
2025-02-21 08:07:24 +01:00
Ervin Hegedus
71037dc4d7
fix: Added missing header to avoid build error with gcc-15 2025-02-20 13:36:35 +01:00
Gabor Berkes
d68aef320c refactor: improve maintainability for SonarCloud compliance
- Marked the conversion operator in `Pcre2MatchContextPtr` as `explicit`
  to improve type safety and prevent unintended implicit conversions.
- Ensured consistent use of `nullptr` instead of `NULL` for better readability and modern C++ compliance.

These changes enhance code clarity, maintainability, and adherence to modern C++ best practices.
2025-02-20 12:25:53 +00:00
Gabor Berkes
b97b61b711
Merge branch 'owasp-modsecurity:v3/master' into refactor/default-pcre2 2025-02-20 09:56:01 +01:00
Ervin Hegedus
40af573759
Merge pull request #3335 from RooHTaylor/v3/master
Fix for issue #3334: build not finding YAJL
2025-01-30 14:20:59 +01:00
Andrew Taylor
199056b916 Fix for issue #3334: build not finding YAJL
When searching for YAJL during ./configure, pkg-config is checked first,
and then a list of directories is searched if pkg-config bears no fruit.
The previous version of yajl.m4 was looping over YAJL_POSSIBLE_LIB_NAMES
instead of YAJL_POSSIBLE_PATHS and passing the lib name to the
CHECK_FOR_YAJL_AT() function instead of the path. The would lead to YAJL
never being found if pkg-config could not find it.
2025-01-30 01:19:50 -05:00
Ervin Hegedus
9e685bf86d
Merge pull request #3322 from airween/v3/validatebyterange
fix: add value checking to @validateByteRange
2025-01-06 19:16:49 +01:00
Ervin Hegedus
9158477561
Add check after intervall parsing, spell fix 2025-01-06 17:36:49 +01:00
Ervin Hegedus
4c5bc45dfd
Add value checking to @validateByteRange 2025-01-06 16:36:36 +01:00
Ervin Hegedus
f260a75c14
Merge pull request #3314 from ElevationsRPG/v3/master
Update README.md
2025-01-06 11:49:41 +01:00
Gabor Berkes
6a2eee629c
Merge branch 'owasp-modsecurity:v3/master' into refactor/default-pcre2 2025-01-06 09:02:00 +01:00
Elevations
d9acf3d0cd
Merge branch 'owasp-modsecurity:v3/master' into v3/master 2025-01-06 13:28:23 +13:00
Ervin Hegedus
eb7e2b8a5f
Merge pull request #3319 from airween/v3/osxcifix
fix: build library on OSX without GeoIP brew package
2025-01-05 17:05:30 +01:00
Ervin Hegedus
a332567b85
Set correct order of commands 2025-01-05 16:41:05 +01:00
Ervin Hegedus
72bb873460
Use latest released version by commit id.
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-01-05 16:09:03 +01:00
Ervin Hegedus
849131c8cf
Change depth value to 1 2025-01-04 23:46:09 +01:00
Ervin Hegedus
d76f3e741e
Update .github/workflows/ci.yml
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-01-04 20:46:36 +01:00
Ervin Hegedus
900e7bcd06
Fix OSX build without GeoIP brew package 2025-01-04 13:48:39 +01:00
Gabor Berkes
10d1c2be74 Refactor: improve PCRE settings output in configure.ac
Enhanced the `configure.ac` script to provide clearer and more readable output for PCRE and PCRE2 settings during configuration. This change improves usability by ensuring that the configuration process displays relevant details in a structured and user-friendly format.

This update aligns with the broader PCRE to PCRE2 migration effort, making the build configuration process more transparent and consistent.
2024-12-20 08:12:06 +00:00
Gabor Berkes
e92507868e Fix macOS GitHub Actions build: add PCRE2_CFLAGS/LDADD/LDFLAGS
Introduced PCRE2_CFLAGS, PCRE2_LDADD, and PCRE2_LDFLAGS in all relevant Makefile.am files to align with the existing PCRE_* variable usage. This change addresses potential issues with linking and configuration for builds on macOS GitHub runners.

These modifications aim to resolve the build failure observed exclusively in the macOS environment while maintaining compatibility across other platforms. Testing will confirm if this adjustment corrects the issue.
2024-12-11 12:48:20 +00:00
Gabor Berkes
784cf0b64c Debug: increase verbosity in pcre2.m4 for macOS GitHub Actions
Added AC_MSG_NOTICE macros to pcre2.m4 to enhance debugging output. This change aims to identify the cause of build failures on macOS runners in GitHub Actions, which do not occur locally or on other platforms (Linux, Windows).

The added verbosity will help trace the build process and inspect variable values for inconsistencies in the macOS runner environment.
2024-12-11 08:57:43 +00:00
Elevations
c0681b6239
Update README.md
Remove conan center change
2024-12-11 19:29:32 +13:00
Elevations
7b4c3a2c0f
Update Dockerfile
Update Docker to latest conan version 2.10.2
2024-12-11 19:06:59 +13:00
Elevations
17700eca5b
Update README.md
Update Windows README to use latest conan version and conan center.
2024-12-11 17:45:37 +13:00
Gabor Berkes
a07d0c7d34 Fix missing libpcre2 dependency on macOS GitHub runner
Identified an issue where the macOS GitHub runner no longer includes the libpcre2 library by default. Updated the workflow configuration to explicitly add libpcre2 as a dependency, ensuring successful builds and compatibility with the updated build system.

This change prevents build failures on macOS environments and aligns the runner's setup with project requirements.
2024-12-10 21:40:09 +00:00
Gabor Berkes
106ed22b6d Fix typo in pcre.m4: corrected PCRE_CFLAGS assignment 2024-12-10 10:58:20 +00:00
Gabor Berkes
c6433df7b2 Refactor build system to use libpcre2 as the default
Updated the build system and related source files to use libpcre2 as the
default regex library instead of the deprecated libpcre. This change
ensures future compatibility and aligns with the library's maintenance status.

To build with the old libpcre, the `--with-pcre` configuration parameter
can be specified.
2024-12-10 10:16:14 +00:00
Gabor Berkes
4fb22466a0 Cleanup: Remove useless/nonfunctional AM_CONDITIONAL macros
- Deleted AM_CONDITIONAL macros from configure.ac that had no functional
  impact on the build system.
2024-12-10 07:32:13 +00:00
Ervin Hegedus
d9101a4fe1
Merge pull request #3306 from airween/v3/time_mon_fix
fix: align TIME_MON variable's behavior
2024-11-24 16:28:47 +00:00
Ervin Hegedus
daf550ef5f
Fix regex for test 2024-11-24 14:06:50 +01:00
Ervin Hegedus
db7e4cb67b
Align TIME_MON variable's behavior 2024-11-23 10:58:35 +01:00
Ervin Hegedus
fd4564131f
Merge pull request #3307 from gberkes/v3/cppcheck_v2_16_upgrade
Fix: Add false positive cppcheck-suppress for compatibility with upda…
2024-11-23 09:28:08 +00:00
Gabor Berkes
530919439b Fix: Add false positive cppcheck-suppress for compatibility with updated cppcheck version
- Added a cppcheck-suppress directive to handle a false positive detected
  by cppcheck 2.16.
- This change addresses an issue caused by the recent Homebrew update
  on macOS CI runner, which upgraded cppcheck from version 2.15 to 2.16.
2024-11-22 23:36:40 +00:00
Ervin Hegedus
41fd21b0fb
Merge pull request #3298 from airween/v3/sethostnamefix
Fix m_requestHostName variable behavior
2024-11-19 20:49:00 +00:00
Ervin Hegedus
d422b36966
Add condition before set hostname; move setRequestHostName() before processConnection() 2024-11-12 16:55:02 +01:00
Ervin Hegedus
4a720004dd
Merge pull request #3287 from hnakamur/fix_modsecurity-regression-test-secremoterules.txt_url_in_example
Fix modsecurity-regression-test-secremoterules.txt URL in example
2024-11-06 10:20:58 +00:00
Hiroaki Nakamura
42a401892b
Fix modsecurity-regression-test-secremoterules.txt URL in example 2024-11-06 14:33:28 +09:00
Ervin Hegedus
5bec188146
Merge pull request #3291 from hnakamur/add_test_regression_rules
Add regression rules for test
2024-11-05 11:03:04 +00:00
Hiroaki Nakamura
742f97ccc0
Add regression rules for test
Copied from:
- faa96c7838/modsecurity-regression-rules.txt
- b9321f190e/modsecurity-regression-ip-list.txt

diff --git a/test/test-cases/regression/operator-ipMatchFromFile.json b/test/test-cases/regression/operator-ipMatchFromFile.json
index 4a225954..1eb4d44a 100644
--- a/test/test-cases/regression/operator-ipMatchFromFile.json
+++ b/test/test-cases/regression/operator-ipMatchFromFile.json
@@ -129,7 +129,7 @@
     },
     "rules":[
       "SecRuleEngine On",
-      "SecRule REMOTE_ADDR \"@ipMatchFromFile b9321f190e/modsecurity-regression-ip-list.txt\" \"id:1
2024-11-02 20:17:24 +09:00
Ervin Hegedus
29a86b17df
Merge pull request #3283 from eduar-hte/cppcheck2142
Use latest version of cppcheck (2.15.0) to analyze codebase
2024-10-22 13:54:52 +02:00
Eduardo Arias
aca93f568e Remove no longer needed cppcheck inline suppressions. 2024-10-21 17:04:26 -03:00
Eduardo Arias
7ec50eb53f Make GeoLookup::debug function static (and non-member), as suggested by cppcheck. 2024-10-21 17:04:26 -03:00
Eduardo Arias
4e68edf0e5 Replace usage of sscanf with strtol to remove cppcheck inline suppression 2024-10-21 17:04:26 -03:00
Eduardo Arias
cdaf32f521 Remove cppcheck suppression by replacing use of local variable to alias this->m_variables
- The name of the local variable would clash with the namespace of the
  same name, which may have lead cppcheck to think the variable was not
  used.
2024-10-21 17:04:26 -03:00
Eduardo Arias
ce9a3167fa Use initialization list to initialize m_service
- This is correct because base class is initialized before members are
  initialized.
- Removes cppcheck suppression by addressing reported issue.
- Leverage C++11's 'default member initializer' to initialize m_provider
  & m_demandsPassword and address Sonarcloud issue.
2024-10-21 17:03:30 -03:00
Eduardo Arias
b0497d9cb9 Avoid this unnecessary copy by using a "const" reference.
- Reported by Sonarcloud
2024-10-19 15:27:39 -03:00
Eduardo Arias
d1e7e7b4f2 Refactor to remove duplicate code in ValidateSchema & ValidateDTD
- Reported by Sonarcloud
2024-10-19 15:27:39 -03:00
Eduardo Arias
2fb446ab2d Address cppcheck warnings generated after addressing Sonarcloud suggestions
- The following two warnings were generated after introducing the change
  to instantiate the DigestImpl template with the address of mbedtls_md5
  or mbedtls_sha1:
  - warning: src/utils/sha1.h,62,error,danglingTemporaryLifetime,Using
    pointer that is a temporary.
  - warning: src/utils/sha1.h,60,style,constVariablePointer,Variable
    'ret' can be declared as pointer to const
- See https://github.com/owasp-modsecurity/ModSecurity/pull/3231#issuecomment-2312511500
2024-10-19 11:48:05 -03:00
Eduardo Arias
bbef22b3b5 Added const reported by cppcheck 2.14 2024-10-19 11:48:05 -03:00
Eduardo Arias
d053ec6de6 Add cppcheck suppressions for false positives 2024-10-19 11:48:05 -03:00
Eduardo Arias
c2b86ddc49 Suppress warnings on seclang-parser.hh
warning: seclang-parser.hh,2116,warning,duplInheritedMember,The struct 'basic_symbol < by_kind >' defines member function with name 'clear' also defined in its parent struct 'by_kind'.
warning: seclang-parser.hh,2376,warning,duplInheritedMember,The struct 'basic_symbol < by_kind >' defines member function with name 'type_get' also defined in its parent struct 'by_kind'.
warning: seclang-parser.hh,2116,warning,duplInheritedMember,The struct 'basic_symbol < by_state >' defines member function with name 'clear' also defined in its parent struct 'by_state'.
warning: seclang-parser.hh,2120,style,constVariableReference,Variable 'yysym' can be declared as reference to const
2024-10-19 11:48:05 -03:00
Eduardo Arias
7d9c80dede Address cppcheck warnings: uselessOverride (The function '...' overrides a function in a base class but is identical to the overridden function) 2024-10-19 11:48:05 -03:00
Eduardo Arias
da38f20e19 Added missing override keyword as reported by cppcheck 2.14 2024-10-19 11:48:05 -03:00
Eduardo Arias
1eed8b9288 Ignore cppcheck warnings: normalCheckLevelMaxBranches (Limiting analysis of branches. Use --check-level=exhaustive to analyze all branches.) 2024-10-19 10:32:33 -03:00
Eduardo Arias
193a0002e4 Updated cppcheck config
- Do not scan third-party libraries (others dir)
- Use standard C++17 for checks (defaults to C++20)
2024-10-19 10:32:33 -03:00
Eduardo Arias
e0c58233ad Use latest version of cppcheck (2.14.2)
- Run cppcheck on MacOS to use a newer version of cppcheck
2024-10-19 10:32:33 -03:00
Ervin Hegedus
ec506daaef
Merge pull request #3280 from eduar-hte/range-checked-at
Replace usage of range-checked 'at' method when vector/string has already been size checked
2024-10-19 11:06:37 +02:00
Eduardo Arias
0613ceeb75 Replace usage of range-checked 'at' method when vector/string has already been size checked 2024-10-15 15:12:10 -03:00
Ervin Hegedus
99ce9779e6
Merge pull request #3253 from eduar-hte/rule-message
Simplified handling of RuleMessage by removing usage of std::shared_ptr
2024-10-15 18:13:31 +02:00
Eduardo Arias
75d31a4d1e Simplified lifetime management of tests
- Addresses Sonarcloud issues:
  - Rewrite the code so that you no longer need this "delete".
  - Make the type of this variable a reference-to-const.
2024-10-07 11:45:10 -03:00
Eduardo Arias
b7b2d9a40d Minor codebase improvements suggested by Sonarcloud
- src/modsecurity.cc
  - Replace the redundant type with "auto".
- src/transaction.cc
  - Avoid this unnecessary copy by using a "const" reference.
- test/common/custom_debug_log.cc
  - Use "=default" instead of the default implementation of this special
    member functions.
    - Removed the unnecessary destructor override instead.
  - Annotate this function with "override" or "final".
    - Removed the unnecessary destructor override instead.
  - Remove this "const" qualifier from the return type in all
    declarations.
- test/common/modsecurity_test_context.h
  - Replace the redundant type with "auto".
- test/regression/regression.cc
  - Use the "nullptr" literal.
  - Replace this declaration by a structured binding declaration.
  - Replace "reinterpret_cast" with a safer operation.
2024-10-07 11:45:10 -03:00
eduar-hte
4df297b596 Avoid passing RuleMessage by std::shared_ptr and use a reference instead.
- Avoids copying std::shared_ptr when lifetime of the RuleMessage
  is controlled by the caller.
  - The RuleMessage instance is created in RuleWithActions::evaluate and
    then used to call the overloaded version of this method that is
    specialized by subclasses.
  - Once the call to the overloaded method returns, the std::shared_ptr
    is destroyed as it's not stored by any of the callers, so it can
    be replaced with a stack variable and avoid paying the cost of
    copying the std::shared_ptr (and its control block that is
    guaranteed to be thread-safe and thus is not a straightforward
    pointer copy)
- Introduced RuleMessage::reset because this is required by
  RuleWithActions::performLogging when it's not the 'last log', the rule
  has multimatch and it's to be logged.
  - The current version is creating allocating another instance of
    RuleMessage on the heap to copy the Rule & Transaction related state
    while all the other members in the RuleMessage are set to their
    default values.
  - The new version leverages the existent, unused and incomplete
    function 'clean' (renamed as 'reset') to do this on the current
    instance.
    - Notice that the current code preserves the value of m_saveMessage,
      so 'reset' provides an argument for the caller to control whether
      this member should be reinitialized.
2024-10-07 11:45:00 -03:00
eduar-hte
e313ac7de7 Introduce ModSecurityTestContext to encapsulate setup of objects required to execute transactions
- Simplifies memory management on error conditions
- Context will be used in unit tests too, in order to provide
  Transaction related instances.
2024-10-07 11:45:00 -03:00
Ervin Hegedus
9a1155ca26
Merge pull request #3254 from eduar-hte/make_shared
Leverage std::make_unique & std::make_shared to create objects in the heap
2024-10-02 17:23:48 +02:00
Ervin Hegedus
373ddb8925
Merge pull request #3266 from airween/v3/modsecdefconf
chore: add 'log' action to rule 200005
2024-10-02 17:09:31 +02:00
Ervin Hegedus
63201ae39f
chore: add 'log' action to rule 200005 2024-10-02 16:33:56 +02:00
Ervin Hegedus
7737594edf
Merge pull request #3264 from xuruidong/logo2
docs: add a logo picture for github dark theme
2024-10-02 09:08:58 +02:00
xuruidong
9238b0ced0 docs: add a logo picture for github dark theme 2024-09-29 19:42:58 +08:00
Eduardo Arias
c6c06c4f33 leverage std::make_unique & std::make_shared
- Simpler code & more efficient because control block can be allocated
  with object.
2024-09-10 09:45:13 -03:00
Ervin Hegedus
9e02b3cf01
Merge pull request #3248 from eduar-hte/simplified-constructors
Simplified constructors, copy constructors & assignment operators
2024-09-09 16:14:09 +02:00
Eduardo Arias
6ecfee7ab7 Simplify and reduce code duplication in Transaction constructors
- Leverage delegating constructor to avoid code duplication between the
  two available Transaction constructors.
  - The constructor without 'id' argument delegates to the one that
    receives it by providing `nullptr` as a value, which is used to
    flag that an id needs to be generated.
- Simplified constructor by removing member initialization where the
  default constructor will be invoked.
2024-09-04 11:16:34 -03:00
Eduardo Arias
2c613fb77c Simplify initialization of fileName member of Rule instances 2024-09-04 10:51:21 -03:00
Eduardo Arias
2ad87f640f Reference RuleWithActions & Transaction object instead of copying values in RuleMessage
- Because the lifetime of the RuleMessage instances do not extend beyond
  the lifetime of the enclosing RuleWithActions & Transaction,
  RuleMessage can just reference it and simplify its definition.
- Additionally, make the references const to show that it doesn't modify it.
- Replace RuleMessage copy constructor with default implementations.
- Removed unused RuleMessage assignment operator (which cannot be implemented
  now that it has reference members).
- Removed constructor from RuleMessage pointer.
- Addressed Sonarcloud suggestions: Do not use the constructor's
  initializer list for data member "xxx". Use the in-class initializer
  instead.
2024-09-04 10:48:07 -03:00
Eduardo Arias
2ec640fd76 Delete unused copy constructor & assignment operator in Rule, RuleMarker & Action
- Declare other unsupported copy constructor & assignment operators as
  deleted too (RuleWithActions, RuleUnconditional & RuleScript)
2024-09-04 10:48:05 -03:00
Ervin Hegedus
580fe192df
Merge pull request #3247 from airween/v3/master
Release v3 version 3.0.13
2024-09-03 15:44:47 +02:00
Ervin Hegedus
24dbcfe637
Change release version to v3.0.13 2024-09-03 15:24:29 +02:00
Ervin Hegedus
1a8c96a1cd
Merge pull request #3206 from airween/v3/release2408
Add PR's to CHANGES
2024-09-03 15:20:34 +02:00
Ervin Hegedus
b489fd3562
Format fix
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2024-09-03 07:45:09 +02:00
Ervin Hegedus
2ab970be2e
Finalize CHANGES 2024-09-02 22:23:19 +02:00
Ervin Hegedus
865b75b8fa
Merge branch 'owasp-modsecurity:v3/master' into v3/release2408 2024-08-28 16:37:12 +02:00
Ervin Hegedus
542a5ea35c
Added PR #3243 2024-08-28 16:08:23 +02:00
Ervin Hegedus
f180e647a1
Merge pull request #3243 from eduar-hte/valid-hex-fix
Adjust reference to modsecurity::utils::string::VALID_HEX
2024-08-28 16:07:44 +02:00
Ervin Hegedus
a4604b66f7 Added new tests to op @pm 2024-08-28 10:45:59 -03:00
Eduardo Arias
27cc8edbfe Adjust reference to modsecurity::utils::string::VALID_HEX
- This function (previously a #define) was previously in the global
  namespace and was moved into modsecurity::utils::string in commit
  a6d64bf.
2024-08-28 10:14:53 -03:00
Ervin Hegedus
358618951a
Added PR #3240 2024-08-28 14:37:56 +02:00
Ervin Hegedus
9403cf6f5d
Merge pull request #3240 from frozenice/patch-1
Lua::run: Move logging of `str` parameter to higher log level.
2024-08-28 14:36:36 +02:00
Ervin Hegedus
07fb580415
Added PR's #3233 and #3231 2024-08-28 14:34:58 +02:00
Ervin Hegedus
9148668571
Merge pull request #3231 from eduar-hte/remove-copies-transformations
Remove unnecessary heap allocated copies in Transformation actions
2024-08-28 14:33:59 +02:00
Ervin Hegedus
4951702d45
Merge pull request #3233 from eduar-hte/remove-copies-pm-operator
Removed multiple heap-allocated copies in Pm::init & parse_pm_content
2024-08-28 13:31:02 +02:00
Eduardo Arias
3e9d8107a8 Removed multiple heap-allocated copies in parse_pm_content
- The previous version of this function was doing three strdup copies
  to parse the pm content. The updated version only copies the value
  once (in order not to modify the Operator's m_param member variable),
  and then performs the updates inline.
- Binary parsing was broken because digits were not compared as
  characters.
  - Fail parsing when an invalid hex character is found.
- Error message in parse_pm_content would reference freed memory if
  accessed by caller. Removed anyway because it was unused.
2024-08-27 10:43:07 -03:00
Eduardo Arias
a6d64bf615 Replaced VALID_HEX, ISODIGIT & NBSP macros in string.h
- Moved them into modsecurity::utils::string to avoid polluting the
  global namespace.
2024-08-27 10:00:54 -03:00
Eduardo Arias
2f5dac5c4c Simplified initialization of Transformation's action_kind
- Some of the Transformation classes would initialize their Action's
  action_kind using the default (using Transformation constructor
  without an action_kind parameter).
- Others, however, would use that constructor and initialize action_kind
  manually in their constructor, but setting the default value
  (RunTimeBeforeMatchAttemptKind = 1), which was redundant.
- Removed unused Transformation constructor to specify action_kind.
- Converted Action::Kind into an 'enum class' to require using the enum
  constants (instead of integer values, which are difficult to track in
  the codebase and change)
2024-08-27 10:00:54 -03:00
Eduardo Arias
7023c0a8b4 Refactored sha1 & md5 utils to share implementation and reduce code duplication. 2024-08-27 10:00:54 -03:00
Eduardo Arias
fedec96a7e Refactored base64 utils to share implementation and reduce code duplication. 2024-08-27 10:00:38 -03:00
Eduardo Arias
34da8eeeee Pass RuleWithActions::executeTransformation arguments by reference
- This function already expects these arguments not to be null pointers,
  doesn't validate them and just dereference them.
- In order to make this explicit and enforced by the compiler, they're
  now passed as references.
2024-08-27 10:00:38 -03:00
Eduardo Arias
b647dbd905 Remove unnecessary heap-allocation & copy in Transaction::extractArguments
- utils::urldecode_nonstrict_inplace decodes inplace so key & value,
  which are values returned by utils::string::ssplit_pair can be
  just be modified and do not need to be copied.
- Updated signature of utils::urldecode_nonstrict_inplace, as its
  two callers already have std::string values.
2024-08-27 10:00:18 -03:00
Eduardo Arias
021d0caa33 Perform NormalisePath & NormalisePathWin transformations in-place 2024-08-27 10:00:18 -03:00
Eduardo Arias
2c3c228725 Perform Utf8ToUnicode transformation in-place
- Removed inplace helper function from the class, as it's only
  referenced by the implementation.
2024-08-27 10:00:18 -03:00
Eduardo Arias
17a2cbd164 Perform UrlDecodeUni & UrlDecode transformations in-place
- Use std::string in UrlEncode transformation, instead of manually
  memory management. This avoids an additional copy after completing
  encoding by just swapping the encoded value and the input.
- Removed inplace helper function from the class, as it's only
  referenced by the implementation.
2024-08-27 10:00:18 -03:00
Eduardo Arias
8bf4d96e6b Perform HtmlEntityDecode transformation in-place
- Removed inplace helper function from the class, as it's only
  referenced by the implementation.
2024-08-27 10:00:18 -03:00
Eduardo Arias
7d5c9faa43 Perform JsDecode transformation in-place
- Removed inplace helper function from the class, as it's only
  referenced by the implementation.
2024-08-27 10:00:18 -03:00
Eduardo Arias
a520369da0 Perform EscapeSeqDecode transformation in-place
- Removed ansi_c_sequences_decode_inplace helper function from the
  class, as it's only referenced by the implementation.
2024-08-27 10:00:18 -03:00
Eduardo Arias
727f2bf840 Perform CssDecode transformation in-place
- Removed inplace helper function from the class, as it's only
  referenced by the implementation.
2024-08-27 10:00:17 -03:00
Eduardo Arias
e687140d05 Perform HexDecode transformation in-place
- Removed inplace helper function from the class, as it's only
  referenced by the implementation.
2024-08-27 10:00:17 -03:00
Eduardo Arias
4670710376 Perform LowerCase & UpperCase transformations in-place
- Refactored to share implementation and reduce code duplication.
2024-08-27 10:00:17 -03:00
Eduardo Arias
fd8a979463 Perform SqlHexDecode transformation in-place
- Validate buffer size before accessing data. The previous
  implementation would only check that there was a character available
  in the buffer but could continue processing/reading characters from
  an hex representation without checking bounds.
- Removed inplace & mytolower helper functions from the class, as
  they're only referenced by the implementation.
- Removed duplicate VALID_HEX & ISODIGIT macros, already in
  src/utils/string.h.
2024-08-27 10:00:17 -03:00
Eduardo Arias
2915ee60e2 Perform Trim, TrimLeft & TrimRight transformations in-place 2024-08-27 10:00:17 -03:00
Eduardo Arias
74d150c068 Perform RemoveCommentsChar, RemoveComments & ReplaceComments transformations in-place 2024-08-27 10:00:17 -03:00
Eduardo Arias
da775eca81 Perform ReplaceNulls transformation in-place 2024-08-27 10:00:17 -03:00
Eduardo Arias
1505025990 Perform RemoveNulls & RemoveWhitespace transformations in-place
- Refactored to share implementation.
2024-08-27 10:00:17 -03:00
Eduardo Arias
1236d9a7cd Perform CompressWhitespace transformation in-place 2024-08-27 10:00:17 -03:00
Eduardo Arias
13203ae5e7 Perform CmdLine transformation in-place 2024-08-27 10:00:17 -03:00
Eduardo Arias
3ff72fbbc5 Perform ParityEven7bit, ParityOdd7bit & ParityZero7bit transformations in-place
- Refactored to share implementations of ParityEven7bit & ParityOdd7bit.
2024-08-27 10:00:17 -03:00
Eduardo Arias
5d39890783 Updated Transformation::evaluate signature to allow for in-place updates, removing unnecessary heap allocated copies.
- Renamed Transformation::evaluate to Transformation::transform to avoid
  confusion with Action's overload methods.
- Updated Transformation::transform signature to receive the value by
  reference and perform the transformation inline, if possible.
  - Some transformations still need to use a temporary std::string to
    perform their work, and then copy the result back.
- Made Transformation::transform methods const and updated Transaction
  parameter to be const.
  - Transaction parameter could not be removed because it's used by just
    a single transformation, UrlDecodeUni.
- Removed std::string Action::evaluate(const std::string &exp,
  Transaction *transaction); which was only implemented by
  Transformation but was not used from the base class, but only after
  downcasting to Transformation, so it can just be declared there (and
  not pollute other actions with a default member implementation -that
  does nothing- which is never called).
2024-08-27 10:00:17 -03:00
Ervin Hegedus
094143801a
Added PR #3232 2024-08-26 21:48:46 +02:00
Ervin Hegedus
97c8766ef1
Merge pull request #3232 from eduar-hte/failed-unit-tests-automake-output
Unit tests results should not be displayed in 'automake output' mode
2024-08-26 21:47:32 +02:00
David Kirstein
315b3d6e77
Lua::run: Move logging of str parameter to higher log level. 2024-08-26 08:38:48 +02:00
Eduardo Arias
df081af870 Adjusted pthread LDFLAG in examples required for multithreading.
- Some versions of gcc/libc require setting the pthread flag when using
  std::thread, which to implement it.
- This was found compiling the library in a Debian (bullseye) container.
2024-08-18 19:19:29 +00:00
Eduardo Arias
a5f223cb52 Individual test result should not be printed for automake output
- Test results output escape characters to highlight whether the test
  passed or failed. Additionally, the input & output for each test can
  include non-ASCII characters. These characters break parsing of
  results (.log & .trs files) with grep, as the files are interpreted
  to be binary.
2024-08-18 19:19:23 +00:00
Ervin Hegedus
752ab76238
Merge pull request #3229 from eduar-hte/pthread-makefile
Restore pthread LDFLAG in examples
2024-08-14 22:07:24 +02:00
Eduardo Arias
2cb1d032e3 Restore pthread LDFLAG. 2024-08-14 08:46:30 -07:00
Ervin Hegedus
71bea86e91
Added PR #3228 2024-08-14 14:56:42 +02:00
Ervin Hegedus
b4f52325bd
Merge pull request #3228 from eduar-hte/asctime-multithread
Replace usage of std::ctime, which is not safe in multithread contexts
2024-08-14 14:55:53 +02:00
Ervin Hegedus
746f4d7e80
Added PR #3227 2024-08-14 12:37:33 +02:00
Ervin Hegedus
554bd30e74
Merge pull request #3227 from eduar-hte/pm-operator-multithreading
Removed unnecessary lock to call acmp_process_quick in Pm::evaluate
2024-08-14 12:36:54 +02:00
Ervin Hegedus
c9af0c747e
Merge pull request #3221 from eduar-hte/unittest-multithreaded
Add support to run unit tests in a multithreaded context
2024-08-14 12:18:07 +02:00
Ervin Hegedus
c4b2723a4f
Added PR #3225 2024-08-14 09:07:33 +02:00
Ervin Hegedus
a6b287e120
Merge pull request #3225 from airween/v3/mpinvcharreqbody
feat: Check if the MP header contains invalid character
2024-08-14 09:06:14 +02:00
Eduardo Arias
ee5f95eb04 Added support to run unit tests in a multithreaded context
- This is controlled by specifying the 'mtstress' argument when running
  `unit_test`.
- The goal is to detect if the operator/transformation  fails in this
  context.
- In this mode, the test will be executed 5'000 times in 50 threads
  concurrently.
- Allocation & initialization of the operator/transformation is
  performed once in the main thread, while the evaluation is executed in
  the threads.
  - This is consistent with the library's support for multithreading,
    where initialization and loading of rules is expected to run once.
    See issue #3215.
2024-08-13 14:06:23 -07:00
Eduardo Arias
23a341eb6a Calculate sizes of strftime buffers based on format strings
- Leverage std::size to determine buffer size at compile time.
- Simplified 'TimeMon::evaluate' implementation as it was using strftime
  to get the month, convert the string to int, and then decrement it by
  one to make it zero based. This same value is already available in
  the 'struct tm' previously generated with the call to localtime_r (and
  where the month is already zero-based)
2024-08-13 13:36:03 -07:00
Eduardo Arias
5e6fcbc60b Replace usage of std::ctime, which is not safe for use in multithreaded contexts
- std::ctime returns a pointer to a string that "may be shared between
  std::asctime and std::ctime, and may be overwritten on each invocation
  of any of those functions.".
  - https://en.cppreference.com/w/cpp/chrono/c/ctime
- Replaced with call to strftime to generate the same string
  representation (using the format string: %c)
- Leveraged localtime_r (which is thread-safe) to convert time_t to
  struct tm, as required by strftime.
2024-08-13 10:54:06 -07:00
Eduardo Arias
8d6b185856 Removed unnecessary lock to call acmp_process_quick in Pm::evaluate
- This was introduced in commit 119a6fc & 7d786b3 because of a potential
  issue reported in #1573.
- The ACMP tree structure is initialized when the operator is
  initialized.
- During transaction execution the ACMP tree structure is only 'read'
  while traversing the tree (in acmp_process_quick) so this is safe for
  use in a multi-threaded environment.
2024-08-13 10:53:15 -07:00
Ervin Hegedus
f42bc38f4c
Update CHANGES 2024-08-13 19:35:14 +02:00
Ervin Hegedus
718d121ee3
Merge pull request #3216 from eduar-hte/inmemory-collection-shared-mutex
Prevent concurrent access to data in InMemoryPerProcess' resolveXXX methods
2024-08-13 19:30:14 +02:00
Ervin Hegedus
32f6f78e78
Merge pull request #3222 from eduar-hte/remove-copies
Remove several string copies and unnecessary heap allocations
2024-08-13 19:25:11 +02:00
Ervin Hegedus
6388d88f38
Check if the MP header contains invalid character 2024-08-13 18:26:18 +02:00
Eduardo Arias
77adb57524 Avoid std::string copy in ssplit argument
- Other minor changes reported by sonarcloud
2024-08-12 12:59:28 -07:00
Ervin Hegedus
305f33fea1
Merge pull request #3224 from airween/v3/sethostnametestfix
fix: Fix regression test result; Add test to main test-suite list
2024-08-12 20:39:30 +02:00
Ervin Hegedus
eb26b7960c
Fix regression test result; Add test to main test-suite list 2024-08-12 18:46:19 +02:00
Eduardo Arias
cc0f893854 Removed unused overload of dash_if_empty that sonarcloud flags as potential buffer overflow 2024-08-09 14:07:39 -07:00
Eduardo Arias
8b17f3691f Inline string functions 2024-08-09 13:21:46 -07:00
Eduardo Arias
1534ee2448 Removed unnecessary copies 2024-08-09 12:52:25 -07:00
eduar-hte
f8dd09f7c9 Avoid creating a new std::string on the heap to create VariableValue
- Introduced helper method addVariableOrigin to reduce code duplication.
2024-08-09 12:52:25 -07:00
Eduardo Arias
bb07de9ad7 toupper/tolower is already receiving a copy, so it doesn't need to create a new one to transform it
- Make functions inline to improve performance
- Introduced helper method toCaseHelper to remove code duplication
2024-08-09 12:52:25 -07:00
Eduardo Arias
4bf9616f9e Adding multithreaded example from issue #3054 (by airween)
- Rewritten to use C++ libModSecurity API and std::thread (instead of
  pthreads)
2024-08-09 11:34:41 -07:00
Eduardo Arias
293cd214c7 Removed usage of pthreads and replaced with std C++ features
- Replaced pthread_mutex_t in modsecurity::operators::Pm with std::mutex
- Replaced pthread's thread usage in reading_logs_via_rule_message
  example with std::thread.
  - Simplified and modernized C++ code.
- Removed unnecessary includes of pthread.h
2024-08-09 11:34:40 -07:00
Eduardo Arias
4e15f9ef71 Turn off LMDB by default in Windows build to align with defaults for other platforms
- Replaced WITHOUT_XXX build options with WITH_XXX to make it easier to
  understand and configure.
- Updated GitHub workflow to align with these changes and include a
  build 'with lmdb' (again, analogous to non-Windows configurations)
2024-08-09 11:34:40 -07:00
Eduardo Arias
e2b3c9594f Prevent concurrent access to data structure in resolve methods
- As reported in #3054, the resolve methods in InMemoryPerProcess are
  not acquiring a lock/mutex to prevent concurrent access to the data
  structures that may be modified at the same time from other threads,
  and thus triggering undefined behaviour.
- Replace inheritance of std::unordered_multimap data structure with
  data member to prevent potential clients to use it without acquiring
  the mutex to protect concurrent access.
- Replace pthreads lock with std C++11 std::shared_mutex
  - Provides exclusive/shared lock access so that multiple readers can
    access the data at the same time, but only one writer. this is used
    to favor query performance by allowing more concurrent access to the
    data until an update needs to be performed.
  - Simplifies acquisition and disposal of lock/mutex with
    std::lock_guard, which has RAII semantics.
  - NOTE: Because std::shared_mutex is not recursive, calls to another
    function that tries to acquire the lock will fail. Introduced
    __store & __updateFirst helper methods to workaround this.
- Updates to InMemoryPerProcess::resolveFirst
  - Updated the code to store the expired var in 'expiredVars' to delete
    them after iterating over the range (and releasing the read lock, as
    'delIfExpired' needs to acquire it for exclusive access), as the
    current call to 'delIfExpired' would invalidate the range triggering
    undefined behaviour on the following iteration.
  - Noticed that in commit 118e1b3 the call to 'delIfExpired' in this
    function is done using 'it->second.getValue()'' instead of
    'it->first', which seems incorrect (based on similar code in other
    resolveXXX functions).
- Updated InMemoryPerProcess::delIfExpired to use 'std::find_if' (with a
  lambda that matches both the key and the 'isExpired' condition)
  because the data structure is a multimap. The version introduced in
  commit 118e1b3 could find an entry (not necessarily the first, because
  the map is unordered) where 'isExpired' is 'false' and exit, while
  another entry could be expired.
2024-08-09 11:34:40 -07:00
Ervin Hegedus
c575dce3d3
Added PR 3218, 3219, 3220 2024-08-09 17:40:33 +02:00
Ervin Hegedus
7bdc3c825c
Merge pull request #3220 from eduar-hte/string-null
Creating a std::string with a null pointer is undefined behaviour
2024-08-09 17:37:47 +02:00
Ervin Hegedus
3a83196a71
Merge pull request #3219 from eduar-hte/cpp17
Simplifiy configuration to build using std C++17
2024-08-09 17:34:02 +02:00
Ervin Hegedus
6f0e566f98
Merge pull request #3218 from eduar-hte/remove-dynamic-casts
Remove unnecessary dynamic casts
2024-08-09 17:24:55 +02:00
Eduardo Arias
c917d6a2dc Initialize variable in if statement to avoid doing dynamic_cast twice
- Refactored duplicate code in RuleWithOperator::getVariablesExceptions
- Leveraged auto to simplify declaration of dynamic_cast pointers.
2024-08-08 13:37:23 -07:00
Eduardo Arias
18378c10f8 Removed unnecessary dynamic_casts 2024-08-08 13:04:29 -07:00
Ervin Hegedus
09980324a7
Added PR #3114 2024-08-08 21:03:10 +02:00
Ervin Hegedus
a23e88f79f
Merge pull request #3114 from airween/v3/sonarmemleakfix
fix: Sonarcloud memleak fixes
2024-08-08 21:02:15 +02:00
Eduardo Arias
30a68de92d Creating a std::string with a null pointer is undefined behaviour.
- cppreference mentions this about the constructor that receives a
  const char *:
  - Constructs the string with the contents initialized with a copy of
    the null-terminated character string pointed to by s. The length of
    the string is determined by the first null character. The behavior
    is undefined if [s, s + Traits::length(s)) is not a valid range
    (for example, if s is a null pointer).
- C++23 introduces a deleted constructor to prevent this in static
  scenarios, which is how this issue was detected.
2024-08-08 11:39:37 -07:00
Eduardo Arias
59254fe3bd Simplifiy configuration to build libModSecurity with std C++17
- Leveraged autoconf again to check whether the C++ compiler supports
  the required standard version and build using it.
- Replaced the outdaded `ax_cxx_compile_stdcxx_11.m4` macro with the
  latest version of `ax_cxx_compile_stdcxx` which supports C++17.
  - https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html
  - https://raw.githubusercontent.com/autoconf-archive/autoconf-archive/e4e5269db2764b9f53d759c24750ac6ca38e02ea/m4/ax_cxx_compile_stdcxx.m4
- This should also streamline updating to C++20 in the future.
2024-08-08 11:23:35 -07:00
Ervin Hegedus
546ec8fe9a
Added PR #3217 2024-08-08 17:56:14 +02:00
Ervin Hegedus
a519c65902
Merge pull request #3217 from gberkes/v3/sonarcloud_Replace_this_declaration_by_a_structured_binding_declaration
V3/sonarcloud replace this declaration by a structured binding declaration
2024-08-08 17:55:09 +02:00
Ervin Hegedus
13cce62b0b
Added PR #3212 2024-08-08 17:52:14 +02:00
Ervin Hegedus
1d6e72e8e2
Merge pull request #3212 from eduar-hte/defensive-intervention
Do not assume ModSecurityIntervention argument to transaction::intervention has been initialized/cleaned
2024-08-08 17:45:34 +02:00
Eduardo Arias
cf643d6072 Avoid duplicate definition of --enable-assertions=yes configure flag on Unix builds
- This configuration flag was introduced in commit d47185d in the
  context of PR #3207.
- Moved to the configure step's 'run' command in order to be shared
  across configurations.
- For the sake of reference, matrix.platform.configure should be used
  for configuration flags that are needed for a specific
  platform/architecture (which was the reason it was introduced in
  commit d9255d8, PR #3144).
2024-08-08 08:16:14 -07:00
gberkes
c50a397a87 Suppress cppcheck false positive unassignedVariable warning. 2024-08-07 21:05:47 +02:00
gberkes
35e825d643 Refactor: replaced 3 declarations with 3 structured binding declarations.
This syntax is far more expressive and easier to understand than the old one.

Refactor: flipped the conditions in "if (contains[Tag|Msg|Id]( ... " statements
for clearer code.

Refactor: moved "Variable *b" as an init-statement inside "if()" statements for
stricter scope.

Reference: https://sonarcloud.io/project/issues?open=AY8-ff1vm_fzkWiCOtCt&id=owasp-modsecurity_ModSecurity
2024-08-07 17:55:30 +02:00
Ervin Hegedus
5403b3d01c
Update CHANGES; added newest PR's 2024-08-07 14:40:56 +02:00
Ervin Hegedus
e8db92ebb0
Merge pull request #3214 from gberkes/v3/Use_the_init-statement_to_declare_pos_inside_the_if_statement
Refactor: used the init-statement to declare "pos" inside the if statement
2024-08-07 14:33:02 +02:00
Ervin Hegedus
a3ffc5a0d2
Merge pull request #3213 from gberkes/v3/sonar_move_these_3_includes_to_the_top_of_the_file
Refactor: moved 3 #include directives to the top of the file.
2024-08-07 14:29:34 +02:00
gberkes
ab78d4af79 Refactor: used the init-statement to declare "pos" inside the if statement.
C++17 introduced a construct to create and initialize a variable within the
condition of if and switch statements, and C++20 added this construct to
range-based for loops. Using this new feature simplifies common code patterns
and helps in giving variables the right scope.

Reference: https://sonarcloud.io/project/issues?open=AZDCieK2zGtqRpL2rnl-&id=owasp-modsecurity_ModSecurity
2024-08-07 13:05:02 +02:00
gberkes
c46f470d6b Refactor: moved 3 #include directives to the top of the file.
To aid code readability, all #include directives in a code file
should be grouped together near the top. The only items that may
precede an #include in a file are other preprocessor directives or comments.

Reference: https://sonarcloud.io/project/issues?sinceLeakPeriod=true&issueStatuses=OPEN%2CCONFIRMED&id=owasp-modsecurity_ModSecurity&open=AY8-ffgqm_fzkWiCOtCs&tab=code

Deleted some unnecessary trailing spaces as well.
2024-08-07 10:39:06 +02:00
Ervin Hegedus
0feaeacce5
Merge pull request #3211 from eduar-hte/secremoterules-regression
Fix SecRemoteRules regression test not to depend on a specific error message
2024-08-07 09:56:08 +02:00
Eduardo Arias
c802b46b7e Simplify parser error detection in testcase
- After the GitHub macOS runner images were upgraded to macOS 14.6
  (Sonoma), the test 'Include remote rules - failed download (Abort)'
  started failing because the error message reported by curl/OS is no
  longer 'HTTP response code said error'.
2024-08-06 14:40:59 -07:00
Eduardo Arias
0b5493d4e7 Minor performance improvements setting up intervention's log
- Initialize `log` temporary value on construction instead of doing
  default initialization and then calling `append`.
- Leverage `std::string_view` to replace `const std::string&` parameters
  in `utils::string::replaceAll` to avoid creating a `std::string`
  object (and associated allocation and copy) for the string literal`%d`
2024-08-06 14:40:45 -07:00
Eduardo Arias
c947f5e40d Do not assume ModSecurityIntervention argument to transaction::intervention has been initialized/cleaned
- Keep m_it->disruptive value and use it as return value to guarantee
  that the value is correct.
  - If m_it->disruptive is false and the 'it' argument has not been
    initialized/cleaned, the function may incorrectly return a non-zero
    value.
- When a disruptive intervention is being reported by the function,
  defensively initialize log & url to NULL if there's no such data to
  provide to the caller.
  - If the caller has not initialized/cleaned those fields in the 'it'
    argument, after returning from transaction::intervention, the user
    can safely read the log & url fields and in all scenarios they'll
    have valid values.
2024-08-06 14:40:45 -07:00
Ervin Hegedus
80dd45703b
Update CHANGES - added PR 3210 2024-08-06 17:37:52 +02:00
Ervin Hegedus
68d551c5f9
Merge pull request #3210 from eduar-hte/shared-files-deadlock
Fixed shared files deadlock in a multi-threaded Windows application
2024-08-06 17:35:41 +02:00
Ervin Hegedus
ff303c761f
Add newest changes 2024-08-06 15:43:39 +02:00
Ervin Hegedus
630751eee6
Merge pull request #3209 from eduar-hte/cleanup_api
Add cleanup methods to complete C based ABI
2024-08-06 15:40:48 +02:00
Ervin Hegedus
8ec69bedd0
Merge pull request #3208 from eduar-hte/macos-apple-silicon
Build on macOS with Apple silicon (arm64)
2024-08-06 14:40:34 +02:00
Eduardo Arias
4b5f719906 Fixed shared files deadlock in a multi-threaded Windows application
- The shared files Windows implementation introduced in PR #3132 works
  in multi-process single-threaded contexts but it doesn't work
  correctly in single-process multi-threaded contexts.
- The issue is that the LockFileEx Win32 function works on a per-handle
  basis.
  - In a multi-process context, each process will have called
    SharedFiles::add_new_handler when initializing the SharedFile and
    obtained a handle, and thus locking will work.
  - When running ModSecurity in a single process using multiple threads,
    the initialization of the SharedFile will happen once and the handle
    will be shared by all threads. Then, if two threads try to write to
    the same shared file concurrently, they may deadlock as one of them
    will lock the file (by calling LockFileEx) and then proceed to write
    to the file. If before writing to the file and unlocking it, another
    thread calls LockFileEx on the same handle, the attempt to write to
    the file will lock generating a deadlock.
- The new implementation replaces usage of LockFileEx/UnlockFileEx with
  a named mutex to lock access to the shared file.
  - A named mutex is used to support multi-process scenarios.
  - The mutex name is generated using the filename to support multiple
    shared files (such as that for the debug and audit logs).
    - This assumes that both process will initialize the SharedFile
      instance using the same filename (which is expected as they'd be
      using the same configuration file)
2024-08-05 13:04:09 -07:00
Eduardo Arias
0dce46062b Fixed potential memory leak when there is an intervention and log or url is set. 2024-08-05 12:18:11 -07:00
Eduardo Arias
dab9bb6a11 Added methods to free buffers allocated by ModSecurity APIs
- The following methods are introduced to allow clients of
  libModSecurity that are not able to link and call the C/C++ standard
  library to be able to free the buffers allocated by libModSecurity.
- msc_intervention_cleanup: Frees the buffers in a
  ModSecurityIntervention structure that have been allocated by calls to
  msc_intervention.
- msc_rules_error_cleanup: Frees an error message buffer allocated by
  the msc_rules_xxx functions to detail the condition that triggered
  the error.
2024-08-05 12:18:11 -07:00
Eduardo Arias
e31ff7e60b Build on macOS 14 arm64 2024-08-05 11:49:58 -07:00
Ervin Hegedus
6cffa8f904
Add _putenv() in case of WIN32 port instead of setenv() 2024-08-05 14:30:26 +02:00
Ervin Hegedus
82801752d4
Merge branch 'v3/master' into v3/sonarmemleakfix 2024-08-05 14:04:04 +02:00
Ervin Hegedus
2048730012
Update CHANGES 2024-08-05 09:32:40 +02:00
Ervin Hegedus
f04dcc0262
Merge pull request #3207 from gberkes/v3/remove_this_throw_call_transaction_h_mk2
V3/remove this throw call transaction h mk2
2024-08-05 09:30:08 +02:00
gberkes
b4cb24327c Fixed extra whitespace. 2024-08-04 23:00:39 +02:00
gberkes
dc3f80a155 Fixed missing whitespace. 2024-08-04 22:55:42 +02:00
gberkes
d47185d771 Build System: Introduce Configurable Assertion Handling
Implemented a new configuration option --enable-assertions=[yes|no] within config.ac, enabling controlled inclusion of -DNDEBUG in CPPFLAGS. The default setting suppresses assertions (by adding -DNDEBUG to CPPFLAGS), preserving the original behavior. This enhancement allows for the optional enabling of assertions during development or debugging by setting --enable-assertions=yes, thereby excluding -DNDEBUG from CPPFLAGS.
2024-08-04 22:47:15 +02:00
gberkes
053e3b5266 Document the usage and the importance of assertions. 2024-08-04 22:13:58 +02:00
gberkes
b4659959cd Refactor: Ensure safe error handling by removing isolated throw; statements.
- SonarCloud analysis identified standalone `throw;` calls without accompanying `try-catch` blocks, used inconsistently as placeholders or for premature termination under specific conditions.
- Removed these `throw;` instances to prevent potential runtime issues in future development phases, where such configurations might inadvertently be created.
- Introduced `assert` statements as a more appropriate mechanism for asserting preconditions in the affected class member functions, ensuring clearer intent and safer code behavior during development.
- Refactor action_kind processing to use switch() instead of if-else chains; add assertion in default case.
- Fix SonarCloud issue: Make this variable a const reference.
https://sonarcloud.io/project/issues?resolved=false&pullRequest=3104&id=owasp-modsecurity_ModSecurity&open=AY8Vpgy4f6U6E7VKL4Cn
2024-08-04 22:04:07 +02:00
Ervin Hegedus
5fa470189b
Add PR's to CHANGES 2024-08-03 16:23:26 +02:00
Ervin Hegedus
b6d218f72d
Merge pull request #3116 from gberkes/v3/remove_this_conditional_structure
Deleted redundant code in 'ModSecurity::serverLog(...)'.
2024-08-02 16:33:07 +02:00
Ervin Hegedus
97c3d15f31
Merge pull request #3203 from airween/v3/sethostname
feat(api) new function: set hostname
2024-08-02 09:44:13 +02:00
Ervin Hegedus
c7efeb6d06
Merge branch 'owasp-modsecurity:v3/master' into v3/sethostname 2024-08-01 22:35:44 +02:00
Ervin Hegedus
a14cdc4ff5
Merge pull request #3182 from airween/v3/readmeupdate
Update README.md: use submodule and use benchmark tool
2024-07-31 16:41:55 +02:00
Ervin Hegedus
4b38435a6e
Merge pull request #3117 from airween/v3/eualrangebyfind
fix: Changed 'equal_range()' + loop by 'find()' in resolveFirst() methods
2024-07-31 15:46:54 +02:00
Ervin Hegedus
6449310831
Fix typos 2024-07-31 14:23:52 +02:00
Ervin Hegedus
937fc5ae59
Provide a function to set 'hostname' field in log 2024-07-29 22:07:26 +02:00
Ervin Hegedus
adba86e2bd
Merge pull request #3185 from eduar-hte/git-describe
Simplify checkout of submodules in GitHub workflows (with support for git describe)
2024-07-25 18:10:52 +02:00
Ervin Hegedus
de8646e383
Merge pull request #3189 from bitbehz/fix/typo-build-win32-dockerfile
Fixing typo in Dockerfile
2024-07-25 18:08:08 +02:00
Behzad Eslami Tehrani
4fce2e3c1d Fixing typo in Dockerfile
Fixing typo in environment variable SRC_DIR.
SCR_DIR -> SRC_DIR
2024-07-22 10:09:27 +03:30
Eduardo Arias
f4d35383e9 fixed typo 2024-07-17 23:22:09 +00:00
Eduardo Arias
5fe777aeb8 simplify submodules checkout (but fetch tags for git describe to work) 2024-07-17 23:19:10 +00:00
Ervin Hegedus
3dda900ee9
Merge pull request #3164 from eduar-hte/variable-origin
Improve performance of VariableOrigin instances
2024-07-17 23:08:30 +02:00
Eduardo Arias
eb62cac7fa Add script to download OWASP CRS v4 to run benchmark
- Simplified clone & checkout of CRS repository
- Removed no longer maintained OWASP Core Ruleset v2
2024-07-17 00:49:27 +00:00
Eduardo Arias
6faf6d7ec0 Removed unnecessary usage of heap-allocated VariableValue (m_var)
- Removed unused methods
2024-07-17 00:49:27 +00:00
Eduardo Arias
dc0a06fc70 Improve performance of VariableOrigin instances
- The previous approach would create a std::unique_ptr and store it in
  a std::list in VariableValue (Origins)
- The new approach now stores Origins in a std::vector and constructs
  VariableOrigin elements in-place on insertion.
- Instead of having two heap-allocations for every added VariableOrigin
  instance, this performs only one.
- If multiple origins are added, std::vector's growth strategy may even
  prevent a heap-allocation. There's a cost on growing the size of the
  vector, because a copy of current elements will be necessary.
  - Introduced reserveOrigin method to notify that multiple insertions
    will be made, so that we can use std::vector's reserve and do a
    single allocation (and copy of previous elements), and then just
    initialize the new elements in-place.
2024-07-17 00:49:27 +00:00
Ervin Hegedus
8d06e4c47b
Typo fixes 2024-07-12 18:09:33 +02:00
Ervin Hegedus
baa7e694f9
Typo fixes 2024-07-12 11:28:52 +02:00
Ervin Hegedus
714e531134
Content improve 2024-07-12 09:15:19 +02:00
Ervin Hegedus
30ddc32c6f
Update README.md: use submodule and use benchmark tool 2024-07-11 22:07:16 +02:00
Ervin Hegedus
7c174e95fa
Merge pull request #3161 from eduar-hte/others-update
Update libinjection & Mbed TLS
2024-07-10 16:35:40 +02:00
Eduardo Arias
a3f40ef03c Replace Mbed TLS source code in repository with a submodule
- Updated to latest Mbed TLS version (v3.6.0)
2024-05-31 00:41:10 +00:00
Eduardo Arias
7732b5e8f3 Update libinjection to version v3.9.2-92-gb9fcaaf 2024-05-31 00:41:10 +00:00
Ervin Hegedus
dc8af8f23d
Merge pull request #3160 from fzipi/v3/add-pull-request-template
chore: add PR template (v3)
2024-05-30 15:36:53 +02:00
Felipe Zipitria
98c672ddb4
chore: add PR template
Signed-off-by: Felipe Zipitria <felipe.zipitria@owasp.org>
2024-05-30 09:51:06 -03:00
Ervin Hegedus
2fd45f870b
Merge pull request #3146 from eduar-hte/seclang-scanner-nounistd
Update to seclang-scanner changes introduced by Windows support
2024-05-23 14:56:26 +02:00
Ervin Hegedus
37776fd262
Merge pull request #3144 from eduar-hte/gh-workflow-updates
GitHub build & quality assurance workflow updates
2024-05-23 14:53:09 +02:00
Eduardo Arias
d9255d85ca Updated GH Unix build configurations
- Added support to build 32-bit versions of libModSecurity on Linux
- Added support to build libModSecurity using clang on Linux (both
  64-bit and 32-bit versions)
- Fixed macOS dependencies to include yajl, not only because it is
  a required dependency, but because tests were not being run on
  macOS builds without it.
- Added build 'without libxml' to Linux & macOS configurations.
- Added build 'without ssdeep' to Linux configurations (already in macOS
  configuration)
- Added build 'with lmdb' to Linux & macOS configurations, replacing the
  existing one 'without lmdb' because by default LMDB is disabled if not
  explicitly turn on in configure.
- Removed 'without yajl' build because it's a required 3rd party
  dependency.
- Added bison & flex dependencies to enable parser generation.
2024-05-23 01:53:47 +00:00
Eduardo Arias
5a543d9c0b Updated .gitignore to ignore files generated in builds
- build/win32/* files from Windows builds, other files from Unix builds
2024-05-23 01:38:15 +00:00
Eduardo Arias
9e44964dc7 Use SRC_DIR argument 2024-05-19 21:12:34 +00:00
Eduardo Arias
fbaf052a0a Update Windows build information after PR #3132 2024-05-19 21:10:25 +00:00
Eduardo Arias
d0108efbc3 Update actions/checkout version to avoid deprecation warnings on GH workflow 2024-05-19 18:56:36 +00:00
Eduardo Arias
636cf43d5e Separate workflow to run check-static (cppcheck) build step 2024-05-19 18:56:36 +00:00
Eduardo Arias
7267c1dc21 Added support to run regression tests without libxml2
- Annotated regression tests that depend on libxml2 support
- Added Windows build without libxml2
2024-05-19 18:55:34 +00:00
Eduardo Arias
2c488386c4 Add options nounistd & never-interactive to seclang-scanner.ll
- The parser is not used interactively so we can avoid including
  unistd.h, which is not available on Windows MSVC C++ compiler.
- The #ifdef WIN32 introduced in PR #3132 would probably be overwritten
  when the parser is updated.
2024-05-19 16:38:03 +00:00
Ervin Hegedus
124a434439
Merge pull request #3141 from rkrishn7/v3/master
Add link to Rust bindings in README
2024-05-15 15:22:15 +02:00
Ervin Hegedus
71a786b1e5
Merge pull request #3132 from eduar-hte/windows-port
Add support to build libModSecurity v3 on Windows
2024-05-15 15:00:16 +02:00
Eduardo Arias
1b2de5a5d3 Add support to turn 3rd party dependencies off
- By default, all the 3rd party dependencies are enabled.
- A dependency can be turned off by adding the "-DWITHOUT_xxx=ON" to
  the call of vcbuild.bat
- List of 3rd party dependencies and associated option to turn them off:
  - LMDB: WITHOUT_LMDB
  - LUA: WITHOUT_LUA
  - LibXML2: WITHOUT_LIBXML2
  - MaxMind: WITHOUT_MAXMIND
  - cURL: WITHOUT_CURL
2024-05-14 21:53:52 +00:00
Eduardo Arias
6bf78f2560 Added GitHub workflow to build libModSecurity on Windows. 2024-05-13 13:37:24 -07:00
Eduardo Arias
e6e2989bd5 Configure test fixture using CTest for Windows build
- Added new test/test_suite.in with list of regression and unit tests
  previously in Makefile.am, to be shared between Unix and Windows
  builds.
- Updated regression.cc & unit.cc to return the number of failed tests
  to indicate to CTest that the test failed. Similarly, a crash or
  unhandled exception terminates the process with a non-zero exit code.
  - This change doesn't affect running the tests with autotest in Unix
    builds because this processes test output from custom-test-driver &
    test-suite.sh, and ignores the exit code of the test runner.
- Removed comment in test/test-cases/regression-offset-variable.json as
  this is not supported by JSON and prevents strict parsers to read and
  process the file.
- Minor change in regression.cc's clearAuditLog to replace std::ifstream
  with std::ofstream as the mode to open the flag applies to an output
  stream.
- Minor change in unit.cc to simplify code that deletes tests.
- Minor changes to test/custom-test-driver to correct usage information.
2024-05-13 10:22:12 -07:00
Rohan Krishnaswamy
4b8c3679b9
Add link to Rust bindings in README (#1) 2024-05-12 18:49:02 -07:00
Eduardo Arias
a8e132f3a1 Replaced the use of "new" in find_resource
- Addresses SonarCloud issue cpp:S5025 (Memory should not be managed manually)
- This function was not changed for the Windows port, but a similar
change to the one suggested was done in expandEnv in the same file.
- The first stream is not destructed at the exact same point it was in
the previous code (but rather when the second stream replaces it on
assignment to the same variable). An arbitrary scope could have been
introduced to destruct the object at the same place, but it doesn't
seem to be necessary and would make the code a bit strange.
2024-05-10 02:28:13 +00:00
Eduardo Arias
b69405a372 Use default keyword to implement constructor/destructor
- Addresses SonarCloud cpp:S3490 issue (Special member function should
not be defined unless a non standard behavior is required)
2024-05-10 02:28:13 +00:00
Eduardo Arias
411bbb2d36 Updated case of winsock header files
- Address SonarCloud cpp:S3806 issues ("#include" paths should be portable)
- This is not an actual issue in this case, because WinSock2.h and
WS2tcpip.h are Windows only.
2024-05-10 02:28:13 +00:00
Eduardo Arias
faae58eed7 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.
2024-05-10 02:28:13 +00:00
Eduardo Arias
d7c49ed590 Added support to lock files on Windows and major rewrite to reintroduce reference counting and remove unused code.
- In Windows build, replaced usage of fcntl with cmd F_SETLKW with
  Win32 APIs to do file locking (LockFileEx & UnlockFileEx).
- Reintroduced the reference counting initially present in the class
  which is necessary to correctly handle merging of rules. This allows
  for correctly closing the file and removing the associated entry from
  m_handlers when the file is no longer used.
  - The need for reference counting can be seen in the example
  simple_example_using_c, where rules are initially loaded locally and
  then further rules are loaded remotely. This will initially open a
  shared file for a log, then in order to merge rules, the shared file
  is opened again for the new configuration. Then, the previous
  configuration closes the shared file on destruction. That is, two
  consecutive opens are done on a shared file, which is followed by
  a close. If the shared file is not reference counted, the shared file
  will be closed while there is still a reference active. The current
  version works because closing of the file has been disabled after
  reference counting was removed.
- Replaced `std::vector` data structure with `std::unordered_map` to
  improve lookup/update times, and simplify code.
- Removed unused code
  - Shared memory to store msc_file_handler structure
    - Initially SharedFiles used shared memory to store information
    about each shared file, including its file pointer and a mutex to
    synchronize access to the file on write. See code at commit 01c13da,
    in particular, usage of lock & fp fields in the msc_file_handler_t
    structure.
    - At that time, msc_file_handler_t included reference counting too
    with the using_it field, which was incremented when a file was
    opened and decremented on close. If the reference count reached
    zero, the shared file would be closed, the lock destroyed and the
    file handler entry removed from m_handlers.
    - Reference counting was removed in commit 7f9cd76, which
    introduced the following issues in SharedFiles::close:
      - No longer closes the file pointer.
        - The file pointer appears to be reset when a.second = 0, but
	this is a local copy of the data pair obtained from m_handlers,
	so this is essentially a nop (updating a local variable that is
	not referenced later in the function).
        - NOTE: The file pointer was moved out of the shared memory in
	this commit too, and stored alongside the msc_file_handler_t
	instance in the m_handlers entry associated to the shared file.
      - The lock is no longer destroyed.
      - The shared memory is marked to be destroyed in the call to:
      shmctl(a.first->shm_id_structure, IPC_RMID, NULL);
      - The shared file entry is not removed from m_handlers, so:
        - the file pointer is still valid, which is how writing to the
	file continues to work,
        - the reference to the shared memory is also present and will
	be marked to be destroyed whenever close is called again on the
	shared file.
    - File locking using the mutex in msc_file_handler_t was replaced in
    commit 3d20304 with usage of fcntl with cmd F_SETLKW.
    - At this time, it appears that the shared memory is no longer used,
    as the file pointer and locking no longer depend on it.
  - MODSEC_USE_GENERAL_LOCK
    - This code is introduced commit 7f9cd76 and is enabled if
    MODSEC_USE_GENERAL_LOCK` is defined.
    - The define is commented out in the source code since the original
    commit and is not present in the build configuration either.
    - In commit ff9152e, in the SharedFiles constructor, the
    initialization of the local variable toBeCreated is removed. This
    means that in this version, if MODSEC_USE_GENERAL_LOCK is enabled,
    execution of the code that checks on toBeCreated is undefined.
    - Then, in commit 9b40a04, the variable toBeCreated is initialized
    again, but is now set to false, which means that if
    MODSEC_USE_GENERAL_LOCK is enabled, the shared memory and lock it
    uses will *not* be initialized and thus doesn't work (execution of
    the current version will result in trying to acquire a lock that
    will be null).
    - I conclude that the feature is not used and can be removed.
      - Additionally, if it were working, I think the lock should be
      used in SharedFiles::write as well, which is a reader of the
      underlying data structures protected by this lock when they're
      modified in SharedFiles::open & SharedFiles::close.
2024-05-10 02:28:13 +00:00
Eduardo Arias
50e78331b1 Updated Env::evaluate to support case-insensitive environment variable names in Windows
- Env::evaluate
  - Environment variable names in Windows are case-insensitive, so in
  the Windows build we use strcasecmp to ignore case when matching
  variables in transaction->m_variableEnvs.
  - If the variable is found, we use the expected variable name to
  create the VariableValue instance, as further rule processing will
  look for the variable using case-sensitive comparisons.
    - This code is not limited to Windows to avoid another #ifdef block
    because for other platforms, because the env variable names are
    case-sensitive the value from either x.first and m_name will be the
    same.
- In Windows build, avoid redefining environ, already defined by
  including stdlib.h.
2024-05-10 02:28:13 +00:00
Eduardo Arias
50c35345ed Fixed use after free in ModSecurity::processContentOffset
- Use after free issue detected with Address Sanitizer while running
  the reading_logs_with_offset example.
- Keeps reference to last element in vars vector with vars.back(). Then
  it removes the element from vars calling vars.pop_back() which
  invalidates the reference, but it's accessed later in the function.
2024-05-10 02:28:13 +00:00
Eduardo Arias
7bff2f77aa Updated references to coreruleset repository
- For OWASP v2 rules, switch to a v2 tag for the paths referenced in
  the rest of the script to apply.
2024-05-03 23:05:34 -03:00
Eduardo Arias
fef419f986 Minor changes related to std::shared_ptr usage in RuleWithActions
- RuleWithActions::evaluate(Transaction *transaction)
  - Removed temporary rm local variable used to immediately create
  std::shared_ptr<RuleMessage>.
- Leverage std::make_shared & auto to simplify code.
2024-05-03 23:05:34 -03:00
Eduardo Arias
10c6ee726f Added support for expandEnv, createDir & cpu_seconds on Windows
- expandEnv on Windows uses POCO C++ Libraries implementation of Glob
  - Paths of matched files are adjusted to preserve UNIX path
  separators for consistency with the rest of the code.
  - Minor change to code shared with other platforms that removes
  allocation of std::ifstream on the heap to check whether the file can
  be opened, which can be done with local stack variable that closes
  the file when out of scope.
- createDir uses _mkdir on Windows, which doesn't support configuring
  the new directory's mode.
- added public domain implementation of clock_gettime for clock_id
  CLOCK_PROCESS_CPUTIME_ID from mingw-w64's winpthreads to support
  cpu_seconds on Windows.
- Updated included headers to support compilation on Windows (using
  Visual C++)
2024-05-03 23:05:34 -03:00
Eduardo Arias
ebf1f8fd28 On Windows use the operating system's native CA store for certificate verification of https requests.
- Updated included headers to support compilation on Windows (using
  Visual C++)
2024-05-03 23:05:34 -03:00
Eduardo Arias
91a736692a Minor changes to debug_log_writer
- Removed unused m_first data member.
- Explicitly delete copy constructor and assignment operator.
- Removed unused included headers.
2024-05-03 23:05:34 -03:00
Eduardo Arias
373633ffe2 mkstemp is not available in Windows build, replaced with _mktemp_s plus _open.
- Updated included headers to support compilation on Windows (using
  Visual C++)
- Minor change to use C++ default (zero) initialization instead of
  calling memset.
2024-05-03 23:05:34 -03:00
Eduardo Arias
35949179a4 setenv is not available in Windows build, replaced with _putenv_s 2024-05-03 23:05:34 -03:00
Eduardo Arias
abbd7b2f42 Replaced usage of apr_snprintf with snprintf (already in Windows exclusive code block)
- updated included headers to support compilation on Windows (using
  Visual C++)
2024-05-03 23:05:34 -03:00
Eduardo Arias
942c8ba606 Replaced usage of usleep (not available in Visual C++) with C++11's std::this_thread::sleep_for & std::chrono::microseconds.
- disabled build error from warning C4716 because process_request does
  not return a value and Visual C++ doesn't support [[noreturn]]
2024-05-03 23:05:34 -03:00
Eduardo Arias
a48856822c Updated included headers to support compilation on Windows (using Visual C++)
- most of posix related functions and constants in unistd.h can be
  found in io.h in Visual C++
- introduced src/compat/msvc.h to adjust for compiler differences (and
  avoid updating code with #ifdef blocks for Windows support)
- removed some included headers that are not needed (both on Unix and
  Windows builds)
2024-05-03 23:05:34 -03:00
Ervin Hegedus
c8056483f7
Merge pull request #3134 from eduar-hte/inline-cppcheck-suppressions
Remove cppcheck suppressions with line numbers in test/cppcheck_suppressions.txt
2024-05-03 14:43:51 +02:00
Eduardo Arias
1f419bba8f Implement sonarcloud suggestions 2024-05-02 17:18:31 -03:00
Eduardo Arias
9f5dc200ba Replace final three suppressions entries with line numbers
- These were initially not included in these changes, as they were
other PRs (#3104 & #3132) that address them.
2024-04-29 22:28:42 -03:00
Eduardo Arias
95ce3a7db4 Removed unused suppressions 2024-04-28 14:56:47 -03:00
Eduardo Arias
7a9c0ab15f Removed unused suppresion and avoid copy of logPath 2024-04-28 14:56:37 -03:00
Eduardo Arias
4aad8e0d06 Inline cppcheck suppressions 2024-04-28 14:56:23 -03:00
Eduardo Arias
0c38023b21 Removed unmatchedSuppression entries 2024-04-28 14:56:11 -03:00
Eduardo Arias
cd2dded659 Removed unnecessary break after return 2024-04-28 14:56:00 -03:00
Eduardo Arias
0cd2f459f3 Address cppcheck suppressions in lmdb 2024-04-28 14:55:49 -03:00
Eduardo Arias
94b68b2514 Minor updates to simplify code and remove cppcheck suppressions 2024-04-28 14:55:38 -03:00
Eduardo Arias
fde9d279b0 Removed unnecessary cppcheck suppression and r-value reference as copy should be avoidded by RVO 2024-04-28 14:55:18 -03:00
Eduardo Arias
b872f11f68 Fixed memory leak in examples/reading_logs_via_rule_message 2024-04-28 14:55:06 -03:00
Eduardo Arias
4288f5a009 Enable inline suppressions in cppcheck 2024-04-28 14:54:46 -03:00
Ervin Hegedus
07e5a7058b
Merge pull request #3128 from fzipi/update-submodules
fix: update submodule url - thanks for maintaining!
2024-04-23 10:54:30 +02:00
Felipe Zipitria
7e085ffb6e
fix: update submodule url
Signed-off-by: Felipe Zipitria <felipe.zipitria@owasp.org>
2024-04-22 15:56:40 -03:00
Ervin Hegedus
6217b4ec1e
Merge pull request #3127 from fzipi/fix-rbl-check
fix(rbl): typo in rbl check selector
2024-04-22 15:56:25 +02:00
Felipe Zipitria
30fe6f935b
fix(rbl): typo in rbl check selector
Signed-off-by: Felipe Zipitria <felipe.zipitria@owasp.org>
2024-04-22 10:23:28 -03:00
Ervin Hegedus
16d0df0ff9
Optimized variable handling 2024-03-31 14:14:45 +02:00
Ervin Hegedus
7c4dcdfa4b
Changed 'euqal_range()' + loop by 'find()' in resolveFirst() methods 2024-03-29 16:32:34 +01:00
gberkes
5802626437 Deleted redundant code in 'ModSecurity::serverLog(...)'. 2024-03-28 20:12:30 +01:00
Ervin Hegedus
cdb6b839e1
Replaced variable type to 'auto' 2024-03-27 16:39:32 +01:00
Ervin Hegedus
1b6b631617
Use make_unique to create unique ptr 2024-03-27 16:33:05 +01:00
Ervin Hegedus
ca7c0ae0b9
Code refactorization 2024-03-27 16:19:38 +01:00
Ervin Hegedus
4085ff5536
Replace putenv by setenv 2024-03-27 13:14:11 +01:00
Ervin Hegedus
5b2404e44d
Fix memleak in rules-check.cc 2024-03-27 11:45:36 +01:00
Ervin Hegedus
39848e5564
Fix memleak in regression.cc 2024-03-27 11:45:05 +01:00
Ervin Hegedus
625f9a5300
Merge pull request #2898 from brandonpayton/add-editorconfig
Add editorconfig to help OSS contributors
2024-03-05 16:13:07 +01:00
Ervin Hegedus
6d719bee5b
Merge pull request #3016 from M4tteoP/uri_decode_invalid
fix: makes uri decode platform independent
2024-03-05 16:11:01 +01:00
Christian Folini
5a6a53859a
Merge pull request #3101 from airween/v3/updatechanges
doc: Update CHANGES
2024-03-02 10:41:37 +01:00
Ervin Hegedus
387c4727f5
Update CHANGES 2024-03-01 22:25:55 +01:00
Ervin Hegedus
3fe51179ee
Update CHANGES 2024-03-01 21:55:21 +01:00
Ervin Hegedus
97687496e9
Merge pull request #3098 from devzero2000/ep/scoped-for
Ep/scoped for: second pr
2024-03-01 21:43:00 +01:00
Elia Pinto
2daebc090f src/utils/acmp.cc: reduce the scope of variable in a for () loop
In general, it is always preferable to reduce
the scope of a variable in a for loop
2024-02-29 20:20:41 +01:00
Elia Pinto
7fed599fdb src/request_body_processor/multipart.cc: reduce the scope of variable in a for () loop
In general, it is always preferable to reduce
the scope of a variable in a for loop
2024-02-29 20:20:41 +01:00
Elia Pinto
b23abf440a src/operators/verify_cc.cc: reduce the scope of variable in a for () loop
In general, it is always preferable to reduce
the scope of a variable in a for loop
2024-02-29 20:20:41 +01:00
Elia Pinto
9842b92bd1 src/actions/transformations/hex_decode.cc: reduce the scope of variable in a for () loop
In general, it is always preferable to reduce
the scope of a variable in a for loop
2024-02-29 20:20:41 +01:00
Ervin Hegedus
734646dbf1
Merge pull request #3096 from gberkes/v3/sonar_return_never_will_be_executed
Clean up 'return' never will be executed.
2024-02-27 22:25:05 +01:00
gberkes
64dfe41cec Refactor: Use pthread_exit(nullptr) instead of pthread_exit(NULL) for type safety. 2024-02-27 19:21:58 +00:00
Ervin Hegedus
f474cc59b8
Merge pull request #3079 from MirkoDziadzka/mirko-bump-c++-version
No other remark was added, merging. Thanks @MirkoDziadzka.
2024-02-27 19:34:48 +01:00
Marc Stern
b3a267d506
Merge pull request #3095 from airween/v3/buildmacros
fix: Replace obsolete macros
2024-02-27 15:47:48 +01:00
gberkes
bf6042dd16 Marked the process_request() function with the [[noreturn]] attribute, as pthread_exit() does not return. 2024-02-26 15:38:39 +00:00
gberkes
7b56db1811 Clean up 'return' never will be executed. 2024-02-26 08:49:05 +00:00
Ervin Hegedus
d0f3cf1389
Replace obsolete macros 2024-02-25 22:01:07 +01:00
Christian Folini
985cb946cc
Merge pull request #3092 from airween/v3/secstatusengoff
fix: Change 'SecEngineStatus' to Off by default
2024-02-22 18:47:21 +01:00
Ervin Hegedus
d7ef620e8b
docs: Add info about modification 2024-02-22 14:04:49 +01:00
Ervin Hegedus
f850932f83
fix: Change 'SecEngineStatus' to Off by default 2024-02-22 14:03:04 +01:00
Ervin Hegedus
d0e6c163fc
Merge pull request #3087 from fzipi/patch-2
chore: update bug-report-for-version-2-x.md
2024-02-20 16:09:33 +01:00
Ervin Hegedus
626c12f1d4
Merge pull request #3086 from fzipi/patch-1
chore: update bug-report-for-version-3-x.md
2024-02-20 15:42:19 +01:00
Felipe Zipitría
c63a9d6341
chore: update bug-report-for-version-2-x.md
- add label so it is properly classified
2024-02-20 11:02:28 -03:00
Felipe Zipitría
9502b4980a
chore: update bug-report-for-version-3-x.md
- add label `3.x` to it is properly classified
2024-02-20 11:01:32 -03:00
Marc Stern
4e4f3291ad
Merge pull request #3080 from airween/v3/testfixes
test: Logical, syntax and cosmetic fixes on test cases
2024-02-14 09:05:55 +01:00
Ervin Hegedus
16c899fb3b
Revert "Add new condition to test case"
This reverts commit 80e244388438b729e7cba4d8a6e48ac81be2b1d8.
2024-02-12 16:54:48 +01:00
Ervin Hegedus
80e2443884
Add new condition to test case 2024-02-12 11:55:17 +01:00
Ervin Hegedus
ed811f1062
Logical, syntax and cosmetic fixes on test cases 2024-02-11 10:14:40 +01:00
Mirko Dziadzka
367a871f30 Bump the C++ version from C++11 to C++17
This will allow the usage of more modern features in the future.
2024-02-09 21:57:31 +01:00
Marc Stern
ca5f5163b4
Merge pull request #3027 from StarryVae/comment-spell-fix
Fix a small comment spell
2024-02-01 10:50:38 +01:00
Ervin Hegedus
5f44383236
Change release version to v3.0.12 2024-01-30 16:43:48 +01:00
Ervin Hegedus
d648a44ff5
Merge pull request #3048 from airween/v3/encodedqm
Change REQUEST_FILENAME behavior
2024-01-30 16:30:25 +01:00
Ervin Hegedus
5f28c2bb21
Change REQUEST_FILENAME behavior 2024-01-30 12:21:45 +01:00
Marc Stern
a859574bf2
Merge pull request #3041 from airween/v3/remoterulestls
Set the minimum security protocol version for SecRemoteRules
2024-01-30 11:16:05 +01:00
Ervin Hegedus
9040893c04
Merge pull request #3042 from airween/v3/docsecurity_updates
docs: Fix organization name in references and security e-mail
2024-01-28 12:50:31 +01:00
Ervin Hegedus
de4d97ea4e
Replaced the organization name in references; changed the security e-mail 2024-01-28 09:29:23 +01:00
Ervin Hegedus
ec8e800a6a
Set the minimum security protocol version for SecRemoteRules 2024-01-27 17:27:00 +01:00
Ervin Hegedus
7aae94b286
Update README.md
Changed Sonarcloud references
2024-01-27 00:18:30 +01:00
wangkai19
3f8de775f9 Fix small comment spell 2023-12-14 17:30:11 +08:00
Martin Vierula
3e7227bfa1
github workflow: update macos version to macos-12 2023-12-08 10:31:45 -08:00
Martin Vierula
1ced1047cc
CHANGES: Preparing for next version 2023-12-08 09:45:13 -08:00
Matteo Pace
fcf205d599 fix: makes uri decode platform independent 2023-11-08 17:32:41 +01:00
Brandon Payton
6ad665f6bb Add editorconfig to help OSS contributors
When switching between many different open source code bases, it can be
cumbersome to constantly change editor settings in order to respect a
given project's basic style preferences. EditorConfig is a popular
format for representing those preferences so editors can automatically
respect them.

Many editors support EditorConfig out of the box, and many others have
EditorConfig plugins:
https://editorconfig.org/#pre-installed

This commit adds an EditorConfig to the ModSecurity project. It is most
likely not perfect because the chosen indentation varies a bit
throughout the project, but hopefully it provides a good basis for most
ModSecurity editing.
2023-05-05 09:18:03 -04:00
414 changed files with 16891 additions and 19348 deletions

26
.editorconfig Normal file
View File

@ -0,0 +1,26 @@
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
indent_style = space
# Scripts without suffixes in the project root tend to indent by two spaces
indent_size = 2
# Most of the project files indent by four spaces
[*/**]
indent_size = 4
# Test files indent by two spaces
[test/**]
indent_size = 2
# The config parser file indents by both two and four spaces,
# so we choose to indent by two spaces as a common denominator.
[*.yy]
indent_size = 2
[{Makefile,Makefile.am}]
indent_style = tab

View File

@ -2,7 +2,7 @@
name: Bug report for version 2.x
about: Create a report to help us improve
title: ''
labels: ''
labels: '2.x'
assignees: ''
---

View File

@ -3,7 +3,7 @@ name: Bug report for version 3.x
about: Create a report to help us improve. If you don't know a specific detail or
piece of information leave it blank, if necessary we will help you to figure out.
title: ''
labels: ''
labels: '3.x'
assignees: ''
---

24
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1,24 @@
<!-- Thank you for contributing to OWASP ModSecurity, your effort is greatly appreciated -->
<!-- Please help us by adding the information below in this PR so it aids reviewers -->
## what
<!--
- Describe high-level what changed as a result of these commits (i.e. in plain-english, what do these changes mean?)
- Use bullet points to be concise and to the point.
-->
## why
<!--
- Provide the justifications for the changes (e.g. business case).
- Describe why these changes were made (e.g. why do these commits fix the problem?)
- Use bullet points to be concise and to the point.
-->
## references
<!--
- Link to any supporting github issues or helpful documentation to add some context (e.g. stackoverflow).
- Use `closes #123`, if this PR closes a GitHub issue `#123`
-->

View File

@ -6,69 +6,202 @@ on:
jobs:
build-linux:
name: Linux (${{ matrix.platform.label }}, ${{ matrix.compiler.label }}, ${{ matrix.configure.label }})
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-22.04]
platform: [x32, x64]
compiler: [gcc, clang]
platform:
- {label: "x64", arch: "amd64", configure: ""}
- {label: "x32", arch: "i386", configure: "PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig CFLAGS=-m32 CXXFLAGS=-m32 LDFLAGS=-m32"}
compiler:
- {label: "gcc", cc: "gcc", cxx: "g++"}
- {label: "clang", cc: "clang", cxx: "clang++"}
configure:
- {label: "with parser generation", opt: "--enable-parser-generation" }
- {label: "wo curl", opt: "--without-curl" }
- {label: "wo yajl", opt: "--without-yajl" }
- {label: "wo geoip", opt: "--without-geoip" }
- {label: "wo lmdb", opt: "--without-lmdb" }
- {label: "with pcre2", opt: "--with-pcre2" }
- {label: "wo lua", opt: "--without-lua" }
- {label: "without maxmind", opt: "--without-maxmind" }
- {label: "wo maxmind", opt: "--without-maxmind" }
- {label: "wo libxml", opt: "--without-libxml" }
- {label: "wo geoip", opt: "--without-geoip" }
- {label: "wo ssdeep", opt: "--without-ssdeep" }
- {label: "with lmdb", opt: "--with-lmdb" }
- {label: "with pcre", opt: "--with-pcre" }
exclude:
- platform: {label: "x32"}
configure: {label: "wo geoip"}
- platform: {label: "x32"}
configure: {label: "wo ssdeep"}
steps:
- name: Setup Dependencies
- name: Setup Dependencies (common)
run: |
sudo dpkg --add-architecture ${{ matrix.platform.arch }}
sudo apt-get update -y -qq
sudo apt-get install -y libfuzzy-dev libyajl-dev libgeoip-dev liblua5.2-dev liblmdb-dev cppcheck libmaxminddb-dev libcurl4-openssl-dev libpcre2-dev pcre2-utils
- uses: actions/checkout@v2
sudo apt-get install -y libyajl-dev:${{ matrix.platform.arch }} \
libcurl4-openssl-dev:${{ matrix.platform.arch }} \
liblmdb-dev:${{ matrix.platform.arch }} \
liblua5.2-dev:${{ matrix.platform.arch }} \
libmaxminddb-dev:${{ matrix.platform.arch }} \
libpcre2-dev:${{ matrix.platform.arch }} \
pcre2-utils:${{ matrix.platform.arch }} \
bison flex
- name: Setup Dependencies (x32)
if: ${{ matrix.platform.label == 'x32' }}
run: |
sudo apt-get install g++-multilib
sudo apt-get install -y libxml2-dev:${{ matrix.platform.arch }} \
libpcre3-dev:${{ matrix.platform.arch }}
- name: Setup Dependencies (x64)
if: ${{ matrix.platform.label == 'x64' }}
run: |
sudo apt-get install -y libgeoip-dev:${{ matrix.platform.arch }} \
libfuzzy-dev:${{ matrix.platform.arch }}
- uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
- name: build.sh
run: ./build.sh
- name: configure ${{ matrix.configure.label }}
run: ./configure ${{ matrix.configure.opt }}
- name: configure
env:
CC: ${{ matrix.compiler.cc }}
CXX: ${{ matrix.compiler.cxx }}
run: ./configure ${{ matrix.platform.configure }} ${{ matrix.configure.opt }} --enable-assertions=yes
- uses: ammaraskar/gcc-problem-matcher@master
- name: make
run: make -j `nproc`
- name: check
run: make check
- name: check-static
run: make check-static
build-macos:
name: macOS (${{ matrix.configure.label }})
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-11]
compiler: [clang]
os: [macos-14]
configure:
- {label: "with parser generation", opt: "--enable-parser-generation" }
- {label: "wo curl", opt: "--without-curl" }
- {label: "wo yajl", opt: "--without-yajl" }
- {label: "wo geoip", opt: "--without-geoip" }
- {label: "wo lmdb", opt: "--without-lmdb" }
- {label: "wo ssdeep", opt: "--without-ssdeep" }
- {label: "wo lua", opt: "--without-lua" }
- {label: "wo maxmind", opt: "--without-maxmind" }
- {label: "wo libxml", opt: "--without-libxml" }
- {label: "wo geoip", opt: "--without-geoip" }
- {label: "wo ssdeep", opt: "--without-ssdeep" }
- {label: "with lmdb", opt: "--with-lmdb" }
- {label: "with pcre", opt: "--with-pcre" }
steps:
- name: Setup Dependencies
# curl, pcre2 not installed because they're already
# included in the image
run: |
brew install autoconf automake cppcheck lmdb libyaml lua ssdeep libmaxminddb bison
- uses: actions/checkout@v2
brew install autoconf \
automake \
libtool \
yajl \
lmdb \
lua \
libmaxminddb \
libxml2 \
ssdeep \
pcre \
bison \
flex
- uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
- name: Build GeoIP
run: |
git clone --depth 1 --no-checkout https://github.com/maxmind/geoip-api-c.git
cd geoip-api-c
git fetch --tags
# Check out the last release, v1.6.12
git checkout 4b526e7331ca1d692b74a0509ddcc725622ed31a
autoreconf --install
./configure --disable-dependency-tracking --disable-silent-rules --prefix=/opt/homebrew
make install
- name: build.sh
run: ./build.sh
- name: configure ${{ matrix.configure.label }}
run: ./configure ${{ matrix.configure.opt }}
- name: configure
run: ./configure ${{ matrix.configure.opt }} --enable-assertions=yes
- uses: ammaraskar/gcc-problem-matcher@master
- name: make
run: make -j `sysctl -n hw.logicalcpu`
- name: check
run: make check
build-windows:
name: Windows (${{ matrix.platform.label }}, ${{ matrix.configure.label }})
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [windows-2022]
platform:
- {label: "x64", arch: "x86_64"}
configuration: [Release]
configure:
- {label: "full", opt: "" }
- {label: "wo curl", opt: "-DWITH_CURL=OFF" }
- {label: "wo lua", opt: "-DWITH_LUA=OFF" }
- {label: "wo maxmind", opt: "-DWITH_MAXMIND=OFF" }
- {label: "wo libxml", opt: "-DWITH_LIBXML2=OFF" }
- {label: "with lmdb", opt: "-DWITH_LMDB=ON" }
steps:
- uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
- name: Install Conan
run: |
pip3 install conan --upgrade
conan profile detect
- uses: ammaraskar/msvc-problem-matcher@master
- name: Build ${{ matrix.configuration }} ${{ matrix.platform.arch }} ${{ matrix.configure.label }}
shell: cmd
run: vcbuild.bat ${{ matrix.configuration }} ${{ matrix.platform.arch }} NO_ASAN "${{ matrix.configure.opt }}"
- name: Set up test environment
working-directory: build\win32\build\${{ matrix.configuration }}
env:
BASE_DIR: ..\..\..\..
shell: cmd
run: |
copy unit_tests.exe %BASE_DIR%\test
copy regression_tests.exe %BASE_DIR%\test
copy libModSecurity.dll %BASE_DIR%\test
copy %BASE_DIR%\unicode.mapping %BASE_DIR%\test
md \tmp
md \bin
copy "C:\Program Files\Git\usr\bin\echo.exe" \bin
copy "C:\Program Files\Git\usr\bin\echo.exe" \bin\echo
- name: Disable tests that don't work on Windows
working-directory: test\test-cases\regression
shell: cmd
run: |
jq "map(if .title == \"Test match variable (1/n)\" then .enabled = 0 else . end)" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json
jq "map(if .title == \"Test match variable (2/n)\" then .enabled = 0 else . end)" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json
jq "map(if .title == \"Test match variable (3/n)\" then .enabled = 0 else . end)" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json
jq "map(if .title == \"Variable offset - FILES_NAMES\" then .enabled = 0 else . end)" offset-variable.json > tmp.json && move /Y tmp.json offset-variable.json
- name: Run tests
working-directory: build\win32\build
run: |
ctest -C ${{ matrix.configuration }} --output-on-failure
cppcheck:
runs-on: [macos-14]
steps:
- name: Setup Dependencies
run: |
brew install autoconf \
automake \
libtool \
cppcheck
- uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
- name: configure
run: |
./build.sh
./configure
- name: cppcheck
run: make check-static

6
.gitignore vendored
View File

@ -11,13 +11,18 @@ build/ltoptions.m4
build/ltsugar.m4
build/ltversion.m4
build/lt~obsolete.m4
build/win32/build
build/win32/CMakeUserPresets.json
compile
config.guess
config.log
config.status
config.sub
config.h.in~
configure
configure~
depcomp
modsecurity.pc
.deps
.libs
.dirstamp
@ -45,6 +50,7 @@ ltmain.sh
examples/simple_example_using_c/test
/tools/rules-check/modsec-rules-check
examples/multiprocess_c/multi
examples/multithread/multithread
examples/reading_logs_via_rule_message/simple_request
examples/reading_logs_with_offset/read
examples/using_bodies_in_chunks/simple_request

7
.gitmodules vendored
View File

@ -1,9 +1,12 @@
[submodule "test/test-cases/secrules-language-tests"]
path = test/test-cases/secrules-language-tests
url = https://github.com/SpiderLabs/secrules-language-tests
url = https://github.com/owasp-modsecurity/secrules-language-tests
[submodule "others/libinjection"]
path = others/libinjection
url = https://github.com/libinjection/libinjection.git
[submodule "bindings/python"]
path = bindings/python
url = https://github.com/SpiderLabs/ModSecurity-Python-bindings.git
url = https://github.com/owasp-modsecurity/ModSecurity-Python-bindings.git
[submodule "others/mbedtls"]
path = others/mbedtls
url = https://github.com/Mbed-TLS/mbedtls.git

155
CHANGES
View File

@ -1,3 +1,158 @@
v3.0.14 - 2025-Feb-25
---------------------
- [fix: fixed htmlEntityDecode methods]
[PR from private repo - @theseion,@airween; fixed CVE-2025-27110]
- fix: Added missing header to avoid build error with gcc-15
[PR #3342 - @airween]
- Fix for issue #3334: build not finding YAJL
[PR #3335 - @RooHTaylor]
- fix: add value checking to @validateByteRange
[PR #3322 - @airween]
- fix: build library on OSX without GeoIP brew package
[PR #3319 - @theseion,@airween]
- Update README.md
[PR #3314 - @ElevationsRPG]
- Fix: Add false positive cppcheck-suppress for compatibility with upda…
[PR #3307 - @gberkes]
- fix: align TIME_MON variable's behavior
[PR #3306 - @M4tteoP,@theseion,@airween]
- Fix m_requestHostName variable behavior
[PR #3298 - @airween]
- Add regression rules for test
[PR #3291 - @hnakamur]
- Fix modsecurity-regression-test-secremoterules.txt URL in example
[PR #3287 - @hnakamur]
- Use latest version of cppcheck (2.15.0) to analyze codebase
[PR #3283 - @eduar-hte]
- Replace usage of range-checked 'at' method when vector/string has already been size checked
[PR #3280 - @eduar-hte]
- chore: add 'log' action to rule 200005
[PR #3266 - @airween]
- docs: add a logo picture for github dark theme
[PR #3264 - @xuruidong]
- Leverage std::make_unique & std::make_shared to create objects in the heap
[PR #3254 - @eduar-hte]
- Simplified handling of RuleMessage by removing usage of std::shared_ptr
[PR #3253 - @eduar-hte]
- Simplified constructors, copy constructors & assignment operators
[PR #3248 - @eduar-hte]
v3.0.13 - 2024-Sep-03
---------------------
- Adjust reference to modsecurity::utils::string::VALID_HEX
[PR #3243 - @eduar-hte]
- Lua::run: Move logging of str parameter to higher log level.
[PR #3240 - @frozenice]
- Remove unnecessary heap allocated copies in Transformation actions
[PR #3231 - @eduar-hte]
- Removed multiple heap-allocated copies in Pm::init & parse_pm_content
[PR #3233 - @eduar-hte]
- Unit tests results should not be displayed in 'automake output' mode
[PR #3232 - @eduar-hte]
- Replace usage of std::ctime, which is not safe in
multithread contexts
[PR #3228 - @eduar-hte]
- Removed unnecessary lock to call acmp_process_quick in Pm::evaluate
[PR #3227 - @eduar-hte]
- feat: Check if the MP header contains invalid character
[PR #3225 - @airween]
- Prevent concurrent access to data in InMemoryPerProcess'
resolveXXX methods
[PR #3216 - @eduar-hte]
- Remove several string copies and unnecessary heap allocations
[PR #3222 - @eduar-hte]
- Creating a std::string with a null pointer
is undefined behaviour
[PR #3220 - @eduar-hte]
- Simplifiy configuration to build using std C++17
[PR #3219 - @eduar-hte]
- Remove unnecessary dynamic casts
[PR #3218 - @eduar-hte]
- fix: Sonarcloud reported memleak fixes
[PR #3114 - @airween]
- V3/sonarcloud replace this declaration by a structured
binding declaration
[PR #3217 - @gberkes]
- Do not assume ModSecurityIntervention argument to
transaction::intervention has been initialized/cleaned
[PR #3212 - @eduar-hte]
- Refactor: used the init-statement to declare "pos" inside the
if statement
[PR #3214 - @gberkes]
- Refactor: moved 3 #include directives to the top of the file.
[PR #3213 - @gberkes]
- Fix SecRemoteRules regression test not to depend on a
specific error message
[PR #3211 - @eduar-hte]
- Fixed shared files deadlock in a multi-threaded Windows application
[PR #3210 - @eduar-hte]
- Add cleanup methods to complete C based ABI
[PR #3209 - @eduar-hte]
- Build on macOS with Apple silicon (arm64)
[PR #3208 - @eduar-hte]
- remove 'this throw' call in transaction
[PR #3207 - @gberkes]
- New API function: set hostname for log
[PR #3203 - @airween]
- Fixing typo in Dockerfile
[PR #3189 - @bitbehz]
- Simplify checkout of submodules in GitHub workflows (with support for git describe)
[PR #3185 - @eduar-hte]
- Update README.md: use submodule and use benchmark tool
[PR #3182 - @airween]
- Improve performance of VariableOrigin instances
[PR #3164 - @eduar-hte]
- Update libinjection & Mbed TLS
[PR #3161 - @eduar-hte]
- chore: add PR template (v3)
[PR #3160 - @fzipi]
- Update to seclang-scanner changes introduced by Windows support
[PR #3146 - @eduar-hte]
- GitHub build & quality assurance workflow updates
[PR #3144 - @eduar-hte]
- Add link to Rust bindings in README
[PR #3141 - @rkrishn7]
- Remove cppcheck suppressions with line numbers in test/cppcheck_suppressions.txt
[PR #3134 - @eduar-hte]
- Add support to build libModSecurity v3 on Windows
[PR #3132 - @eduar-hte]
- fix: update submodule url
[PR #3128 - @fzipi]
- fix(rbl): typo in rbl check selector
[PR #3127 - @fzipi]
- fix: Changed 'equal_range()' + loop by 'find()' in resolveFirst() methods
[PR #3117 - @airween]
- Deleted redundant code in 'ModSecurity::serverLog(...)'.
[PR #3116 - @gberkes]
- doc: Update CHANGES
[PR #3101 - @airween]
- Reduce the scope of variables in a for loop
[PR #3098 - @devzero2000]
- Clean up 'return' never will be executed.
[PR #3096 - @gberkes]
- fix: Replace obsolete macros
[PR #3095 - @airween]
- fix: Change 'SecEngineStatus' to Off by default
[PR #3092 - @airween]
- chore: update bug-report-for-version-3-x.md
[PR #3086 - @fzipi]
- test: Logical, syntax and cosmetic fixes on test cases
[PR #3080 - @MirkoDziadzka, @airween]
- Bump the C++ version from C++11 to C++17
[PR #3079 - @MirkoDziadzka]
- fix: makes uri decode platform independent
[PR #3016 - @M4tteoP]
v3.0.12 - 2024-Jan-30
---------------------
- Change REQUEST_FILENAME and REQUEST_BASENAME behavior
[Issue #3048 - @martinhsv, @theMiddleBlue, @theseion, @M4tteoP, @airween]
- Set the minimum security protocol version for SecRemoteRules
[Issue security/code-scanning/2 - @airween]
v3.0.11 - 2023-Dec-06
---------------------

View File

@ -59,12 +59,15 @@ cppcheck:
@cppcheck -U YYSTYPE -U MBEDTLS_MD5_ALT -U MBEDTLS_SHA1_ALT \
-D MS_CPPCHECK_DISABLED_FOR_PARSER -U YY_USER_INIT \
--suppressions-list=./test/cppcheck_suppressions.txt \
--inline-suppr \
--enable=warning,style,performance,portability,unusedFunction,missingInclude \
--inconclusive \
--template="warning: {file},{line},{severity},{id},{message}" \
-I headers -I . -I others -I src -I others/mbedtls -I src/parser \
-I headers -I . -I $(top_srcdir)/others -I $(top_srcdir)/src -I $(top_srcdir)/others/mbedtls/include \
--error-exitcode=1 \
-i "src/parser/seclang-parser.cc" -i "src/parser/seclang-scanner.cc" \
-i others \
--std=c++17 \
--force --verbose .
@ -88,263 +91,8 @@ LOG_DRIVER = env $(SHELL) $(top_srcdir)/test/custom-test-driver
AM_TESTS_ENVIRONMENT=AUTOMAKE_TESTS=true; export AUTOMAKE_TESTS;
LOG_COMPILER=test/test-suite.sh
# for i in `find test/test-cases -iname *.json`; do echo TESTS+=$i; done
TESTS=
TESTS+=test/test-cases/regression/action-allow.json
TESTS+=test/test-cases/regression/action-block.json
TESTS+=test/test-cases/regression/action-ctl_request_body_access.json
TESTS+=test/test-cases/regression/action-ctl_request_body_processor.json
TESTS+=test/test-cases/regression/action-ctl_request_body_processor_urlencoded.json
TESTS+=test/test-cases/regression/action-ctl_rule_engine.json
TESTS+=test/test-cases/regression/action-ctl_audit_engine.json
TESTS+=test/test-cases/regression/action-ctl_rule_remove_by_id.json
TESTS+=test/test-cases/regression/action-ctl_rule_remove_by_tag.json
TESTS+=test/test-cases/regression/action-ctl_rule_remove_target_by_id.json
TESTS+=test/test-cases/regression/action-ctl_rule_remove_target_by_tag.json
TESTS+=test/test-cases/regression/action-disruptive.json
TESTS+=test/test-cases/regression/action-exec.json
TESTS+=test/test-cases/regression/action-expirevar.json
TESTS+=test/test-cases/regression/action-id.json
TESTS+=test/test-cases/regression/action-initcol.json
TESTS+=test/test-cases/regression/action-msg.json
TESTS+=test/test-cases/regression/action-setenv.json
TESTS+=test/test-cases/regression/action-setrsc.json
TESTS+=test/test-cases/regression/action-setsid.json
TESTS+=test/test-cases/regression/action-setuid.json
TESTS+=test/test-cases/regression/actions.json
TESTS+=test/test-cases/regression/action-skip.json
TESTS+=test/test-cases/regression/action-tag.json
TESTS+=test/test-cases/regression/action-tnf-base64.json
TESTS+=test/test-cases/regression/action-xmlns.json
TESTS+=test/test-cases/regression/auditlog.json
TESTS+=test/test-cases/regression/collection-case-insensitive.json
TESTS+=test/test-cases/regression/collection-lua.json
TESTS+=test/test-cases/regression/collection-regular_expression_selection.json
TESTS+=test/test-cases/regression/collection-resource.json
TESTS+=test/test-cases/regression/collection-tx.json
TESTS+=test/test-cases/regression/collection-tx-with-macro.json
TESTS+=test/test-cases/regression/config-body_limits.json
TESTS+=test/test-cases/regression/config-calling_phases_by_name.json
TESTS+=test/test-cases/regression/config-include-bad.json
TESTS+=test/test-cases/regression/config-include.json
TESTS+=test/test-cases/regression/config-remove_by_id.json
TESTS+=test/test-cases/regression/config-remove_by_msg.json
TESTS+=test/test-cases/regression/config-remove_by_tag.json
TESTS+=test/test-cases/regression/config-response_type.json
TESTS+=test/test-cases/regression/config-secdefaultaction.json
TESTS+=test/test-cases/regression/config-secremoterules.json
TESTS+=test/test-cases/regression/config-update-action-by-id.json
TESTS+=test/test-cases/regression/config-update-target-by-id.json
TESTS+=test/test-cases/regression/config-update-target-by-msg.json
TESTS+=test/test-cases/regression/config-update-target-by-tag.json
TESTS+=test/test-cases/regression/config-xml_external_entity.json
TESTS+=test/test-cases/regression/debug_log.json
TESTS+=test/test-cases/regression/directive-sec_rule_script.json
TESTS+=test/test-cases/regression/issue-1152.json
TESTS+=test/test-cases/regression/issue-1528.json
TESTS+=test/test-cases/regression/issue-1565.json
TESTS+=test/test-cases/regression/issue-1576.json
TESTS+=test/test-cases/regression/issue-1591.json
TESTS+=test/test-cases/regression/issue-1725.json
TESTS+=test/test-cases/regression/issue-1743.json
TESTS+=test/test-cases/regression/issue-1785.json
TESTS+=test/test-cases/regression/issue-1812.json
TESTS+=test/test-cases/regression/issue-1831.json
TESTS+=test/test-cases/regression/issue-1844.json
TESTS+=test/test-cases/regression/issue-1850.json
TESTS+=test/test-cases/regression/issue-1941.json
TESTS+=test/test-cases/regression/issue-1943.json
TESTS+=test/test-cases/regression/issue-1956.json
TESTS+=test/test-cases/regression/issue-1960.json
TESTS+=test/test-cases/regression/issue-2099.json
TESTS+=test/test-cases/regression/issue-2000.json
TESTS+=test/test-cases/regression/issue-2111.json
TESTS+=test/test-cases/regression/issue-2196.json
TESTS+=test/test-cases/regression/issue-2423-msg-in-chain.json
TESTS+=test/test-cases/regression/issue-2427.json
TESTS+=test/test-cases/regression/issue-2296.json
TESTS+=test/test-cases/regression/issue-394.json
TESTS+=test/test-cases/regression/issue-849.json
TESTS+=test/test-cases/regression/issue-960.json
TESTS+=test/test-cases/regression/misc.json
TESTS+=test/test-cases/regression/misc-variable-under-quotes.json
TESTS+=test/test-cases/regression/offset-variable.json
TESTS+=test/test-cases/regression/operator-detectsqli.json
TESTS+=test/test-cases/regression/operator-detectxss.json
TESTS+=test/test-cases/regression/operator-fuzzyhash.json
TESTS+=test/test-cases/regression/operator-inpectFile.json
TESTS+=test/test-cases/regression/operator-ipMatchFromFile.json
TESTS+=test/test-cases/regression/operator-pm.json
TESTS+=test/test-cases/regression/operator-rx.json
TESTS+=test/test-cases/regression/operator-rxGlobal.json
TESTS+=test/test-cases/regression/operator-UnconditionalMatch.json
TESTS+=test/test-cases/regression/operator-validate-byte-range.json
TESTS+=test/test-cases/regression/operator-verifycc.json
TESTS+=test/test-cases/regression/operator-verifycpf.json
TESTS+=test/test-cases/regression/operator-verifyssn.json
TESTS+=test/test-cases/regression/operator-verifysvnr.json
TESTS+=test/test-cases/regression/request-body-parser-json.json
TESTS+=test/test-cases/regression/request-body-parser-multipart-crlf.json
TESTS+=test/test-cases/regression/request-body-parser-multipart.json
TESTS+=test/test-cases/regression/request-body-parser-xml.json
TESTS+=test/test-cases/regression/request-body-parser-xml-validade-dtd.json
TESTS+=test/test-cases/regression/rule-920120.json
TESTS+=test/test-cases/regression/rule-920200.json
TESTS+=test/test-cases/regression/rule-920274.json
TESTS+=test/test-cases/regression/secaction.json
TESTS+=test/test-cases/regression/secargumentslimit.json
TESTS+=test/test-cases/regression/sec_component_signature.json
TESTS+=test/test-cases/regression/secmarker.json
TESTS+=test/test-cases/regression/secruleengine.json
TESTS+=test/test-cases/regression/transformation-none.json
TESTS+=test/test-cases/regression/transformations.json
TESTS+=test/test-cases/regression/variable-ARGS_COMBINED_SIZE.json
TESTS+=test/test-cases/regression/variable-ARGS_GET.json
TESTS+=test/test-cases/regression/variable-ARGS_GET_NAMES.json
TESTS+=test/test-cases/regression/variable-ARGS.json
TESTS+=test/test-cases/regression/variable-ARGS_NAMES.json
TESTS+=test/test-cases/regression/variable-ARGS_POST.json
TESTS+=test/test-cases/regression/variable-ARGS_POST_NAMES.json
TESTS+=test/test-cases/regression/variable-AUTH_TYPE.json
TESTS+=test/test-cases/regression/variable-DURATION.json
TESTS+=test/test-cases/regression/variable-ENV.json
TESTS+=test/test-cases/regression/variable-FILES_COMBINED_SIZE.json
TESTS+=test/test-cases/regression/variable-FILES.json
TESTS+=test/test-cases/regression/variable-FILES_NAMES.json
TESTS+=test/test-cases/regression/variable-FILES_SIZES.json
TESTS+=test/test-cases/regression/variable-FULL_REQUEST.json
TESTS+=test/test-cases/regression/variable-FULL_REQUEST_LENGTH.json
TESTS+=test/test-cases/regression/variable-GEO.json
TESTS+=test/test-cases/regression/variable-HIGHEST_SEVERITY.json
TESTS+=test/test-cases/regression/variable-INBOUND_DATA_ERROR.json
TESTS+=test/test-cases/regression/variable-MATCHED_VAR.json
TESTS+=test/test-cases/regression/variable-MATCHED_VAR_NAME.json
TESTS+=test/test-cases/regression/variable-MATCHED_VARS.json
TESTS+=test/test-cases/regression/variable-MATCHED_VARS_NAMES.json
TESTS+=test/test-cases/regression/variable-MODSEC_BUILD.json
TESTS+=test/test-cases/regression/variable-MULTIPART_CRLF_LF_LINES.json
TESTS+=test/test-cases/regression/variable-MULTIPART_FILENAME.json
TESTS+=test/test-cases/regression/variable-MULTIPART_INVALID_HEADER_FOLDING.json
TESTS+=test/test-cases/regression/variable-MULTIPART_NAME.json
TESTS+=test/test-cases/regression/variable-MULTIPART_PART_HEADERS.json
TESTS+=test/test-cases/regression/variable-MULTIPART_STRICT_ERROR.json
TESTS+=test/test-cases/regression/variable-MULTIPART_UNMATCHED_BOUNDARY.json
TESTS+=test/test-cases/regression/variable-OUTBOUND_DATA_ERROR.json
TESTS+=test/test-cases/regression/variable-PATH_INFO.json
TESTS+=test/test-cases/regression/variable-QUERY_STRING.json
TESTS+=test/test-cases/regression/variable-REMOTE_ADDR.json
TESTS+=test/test-cases/regression/variable-REMOTE_HOST.json
TESTS+=test/test-cases/regression/variable-REMOTE_PORT.json
TESTS+=test/test-cases/regression/variable-REMOTE_USER.json
TESTS+=test/test-cases/regression/variable-REQBODY_PROCESSOR_ERROR.json
TESTS+=test/test-cases/regression/variable-REQBODY_PROCESSOR.json
TESTS+=test/test-cases/regression/variable-REQUEST_BASENAME.json
TESTS+=test/test-cases/regression/variable-REQUEST_BODY.json
TESTS+=test/test-cases/regression/variable-REQUEST_BODY_LENGTH.json
TESTS+=test/test-cases/regression/variable-REQUEST_COOKIES.json
TESTS+=test/test-cases/regression/variable-REQUEST_COOKIES_NAMES.json
TESTS+=test/test-cases/regression/variable-REQUEST_FILENAME.json
TESTS+=test/test-cases/regression/variable-REQUEST_HEADERS.json
TESTS+=test/test-cases/regression/variable-REQUEST_HEADERS_NAMES.json
TESTS+=test/test-cases/regression/variable-REQUEST_LINE.json
TESTS+=test/test-cases/regression/variable-REQUEST_METHOD.json
TESTS+=test/test-cases/regression/variable-REQUEST_PROTOCOL.json
TESTS+=test/test-cases/regression/variable-REQUEST_URI.json
TESTS+=test/test-cases/regression/variable-REQUEST_URI_RAW.json
TESTS+=test/test-cases/regression/variable-RESPONSE_BODY.json
TESTS+=test/test-cases/regression/variable-RESPONSE_CONTENT_LENGTH.json
TESTS+=test/test-cases/regression/variable-RESPONSE_CONTENT_TYPE.json
TESTS+=test/test-cases/regression/variable-RESPONSE_HEADERS.json
TESTS+=test/test-cases/regression/variable-RESPONSE_HEADERS_NAMES.json
TESTS+=test/test-cases/regression/variable-RESPONSE_PROTOCOL.json
TESTS+=test/test-cases/regression/variable-RULE.json
TESTS+=test/test-cases/regression/variable-SERVER_ADDR.json
TESTS+=test/test-cases/regression/variable-SERVER_NAME.json
TESTS+=test/test-cases/regression/variable-SERVER_PORT.json
TESTS+=test/test-cases/regression/variable-SESSIONID.json
TESTS+=test/test-cases/regression/variable-STATUS.json
TESTS+=test/test-cases/regression/variable-TIME_DAY.json
TESTS+=test/test-cases/regression/variable-TIME_EPOCH.json
TESTS+=test/test-cases/regression/variable-TIME_HOUR.json
TESTS+=test/test-cases/regression/variable-TIME.json
TESTS+=test/test-cases/regression/variable-TIME_MIN.json
TESTS+=test/test-cases/regression/variable-TIME_MON.json
TESTS+=test/test-cases/regression/variable-TIME_SEC.json
TESTS+=test/test-cases/regression/variable-TIME_WDAY.json
TESTS+=test/test-cases/regression/variable-TIME_YEAR.json
TESTS+=test/test-cases/regression/variable-TX.json
TESTS+=test/test-cases/regression/variable-UNIQUE_ID.json
TESTS+=test/test-cases/regression/variable-URLENCODED_ERROR.json
TESTS+=test/test-cases/regression/variable-USERID.json
TESTS+=test/test-cases/regression/variable-variation-count.json
TESTS+=test/test-cases/regression/variable-variation-exclusion.json
TESTS+=test/test-cases/regression/variable-WEBAPPID.json
TESTS+=test/test-cases/regression/variable-WEBSERVER_ERROR_LOG.json
TESTS+=test/test-cases/regression/variable-XML.json
TESTS+=test/test-cases/secrules-language-tests/operators/beginsWith.json
TESTS+=test/test-cases/secrules-language-tests/operators/contains.json
TESTS+=test/test-cases/secrules-language-tests/operators/containsWord.json
TESTS+=test/test-cases/secrules-language-tests/operators/detectSQLi.json
TESTS+=test/test-cases/secrules-language-tests/operators/detectXSS.json
TESTS+=test/test-cases/secrules-language-tests/operators/endsWith.json
TESTS+=test/test-cases/secrules-language-tests/operators/eq.json
TESTS+=test/test-cases/secrules-language-tests/operators/ge.json
TESTS+=test/test-cases/secrules-language-tests/operators/geoLookup.json
TESTS+=test/test-cases/secrules-language-tests/operators/gt.json
TESTS+=test/test-cases/secrules-language-tests/operators/ipMatch.json
TESTS+=test/test-cases/secrules-language-tests/operators/le.json
TESTS+=test/test-cases/secrules-language-tests/operators/lt.json
TESTS+=test/test-cases/secrules-language-tests/operators/noMatch.json
TESTS+=test/test-cases/secrules-language-tests/operators/pmFromFile.json
TESTS+=test/test-cases/secrules-language-tests/operators/pm.json
TESTS+=test/test-cases/secrules-language-tests/operators/rx.json
TESTS+=test/test-cases/secrules-language-tests/operators/rxGlobal.json
TESTS+=test/test-cases/secrules-language-tests/operators/streq.json
TESTS+=test/test-cases/secrules-language-tests/operators/strmatch.json
TESTS+=test/test-cases/secrules-language-tests/operators/unconditionalMatch.json
TESTS+=test/test-cases/secrules-language-tests/operators/validateByteRange.json
TESTS+=test/test-cases/secrules-language-tests/operators/validateUrlEncoding.json
TESTS+=test/test-cases/secrules-language-tests/operators/validateUtf8Encoding.json
TESTS+=test/test-cases/secrules-language-tests/operators/verifyCC.json
TESTS+=test/test-cases/secrules-language-tests/operators/verifycpf.json
TESTS+=test/test-cases/secrules-language-tests/operators/verifyssn.json
TESTS+=test/test-cases/secrules-language-tests/operators/verifysvnr.json
TESTS+=test/test-cases/secrules-language-tests/operators/within.json
TESTS+=test/test-cases/secrules-language-tests/transformations/base64DecodeExt.json
TESTS+=test/test-cases/secrules-language-tests/transformations/base64Decode.json
TESTS+=test/test-cases/secrules-language-tests/transformations/base64Encode.json
TESTS+=test/test-cases/secrules-language-tests/transformations/cmdLine.json
TESTS+=test/test-cases/secrules-language-tests/transformations/compressWhitespace.json
TESTS+=test/test-cases/secrules-language-tests/transformations/cssDecode.json
TESTS+=test/test-cases/secrules-language-tests/transformations/escapeSeqDecode.json
TESTS+=test/test-cases/secrules-language-tests/transformations/hexDecode.json
TESTS+=test/test-cases/secrules-language-tests/transformations/hexEncode.json
TESTS+=test/test-cases/secrules-language-tests/transformations/htmlEntityDecode.json
TESTS+=test/test-cases/secrules-language-tests/transformations/jsDecode.json
TESTS+=test/test-cases/secrules-language-tests/transformations/length.json
TESTS+=test/test-cases/secrules-language-tests/transformations/lowercase.json
TESTS+=test/test-cases/secrules-language-tests/transformations/md5.json
TESTS+=test/test-cases/secrules-language-tests/transformations/normalisePath.json
TESTS+=test/test-cases/secrules-language-tests/transformations/normalisePathWin.json
TESTS+=test/test-cases/secrules-language-tests/transformations/parityEven7bit.json
TESTS+=test/test-cases/secrules-language-tests/transformations/parityOdd7bit.json
TESTS+=test/test-cases/secrules-language-tests/transformations/parityZero7bit.json
TESTS+=test/test-cases/secrules-language-tests/transformations/removeCommentsChar.json
TESTS+=test/test-cases/secrules-language-tests/transformations/removeComments.json
TESTS+=test/test-cases/secrules-language-tests/transformations/removeNulls.json
TESTS+=test/test-cases/secrules-language-tests/transformations/removeWhitespace.json
TESTS+=test/test-cases/secrules-language-tests/transformations/replaceComments.json
TESTS+=test/test-cases/secrules-language-tests/transformations/replaceNulls.json
TESTS+=test/test-cases/secrules-language-tests/transformations/sha1.json
TESTS+=test/test-cases/secrules-language-tests/transformations/sqlHexDecode.json
TESTS+=test/test-cases/secrules-language-tests/transformations/trim.json
TESTS+=test/test-cases/secrules-language-tests/transformations/trimLeft.json
TESTS+=test/test-cases/secrules-language-tests/transformations/trimRight.json
TESTS+=test/test-cases/secrules-language-tests/transformations/urlDecode.json
TESTS+=test/test-cases/secrules-language-tests/transformations/urlDecodeUni.json
TESTS+=test/test-cases/secrules-language-tests/transformations/urlEncode.json
TESTS+=test/test-cases/secrules-language-tests/transformations/utf8toUnicode.json
include test/test-suite.in
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = modsecurity.pc

135
README.md
View File

@ -1,16 +1,20 @@
<img src="https://github.com/SpiderLabs/ModSecurity/raw/v3/master/others/modsec.png" width="50%">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="./others/modsec_white_bg.png">
<source media="(prefers-color-scheme: light)" srcset="./others/modsec.png">
<img src="./others/modsec.png" width="50%">
</picture>
![Quality Assurance](https://github.com/SpiderLabs/ModSecurity/workflows/Quality%20Assurance/badge.svg)
[![Build Status](https://sonarcloud.io/api/project_badges/measure?project=USHvY32Uy62L&metric=alert_status)](https://sonarcloud.io/dashboard?id=USHvY32Uy62L)
[![](https://sonarcloud.io/api/project_badges/measure?project=USHvY32Uy62L&metric=sqale_rating
)](https://sonarcloud.io/dashboard?id=USHvY32Uy62L)
[![](https://sonarcloud.io/api/project_badges/measure?project=USHvY32Uy62L&metric=reliability_rating
)](https://sonarcloud.io/dashboard?id=USHvY32Uy62L)
[![](https://sonarcloud.io/api/project_badges/measure?project=USHvY32Uy62L&metric=security_rating
)](https://sonarcloud.io/dashboard?id=USHvY32Uy62L)
[![](https://sonarcloud.io/api/project_badges/measure?project=USHvY32Uy62L&metric=vulnerabilities
)](https://sonarcloud.io/dashboard?id=USHvY32Uy62L)
![Quality Assurance](https://github.com/owasp-modsecurity/ModSecurity/workflows/Quality%20Assurance/badge.svg)
[![Build Status](https://sonarcloud.io/api/project_badges/measure?project=owasp-modsecurity_ModSecurity&metric=alert_status)](https://sonarcloud.io/dashboard?id=owasp-modsecurity_ModSecurity)
[![](https://sonarcloud.io/api/project_badges/measure?project=owasp-modsecurity_ModSecurity&metric=sqale_rating
)](https://sonarcloud.io/dashboard?id=owasp-modsecurity_ModSecurity)
[![](https://sonarcloud.io/api/project_badges/measure?project=owasp-modsecurity_ModSecurity&metric=reliability_rating
)](https://sonarcloud.io/dashboard?id=owasp-modsecurity_ModSecurity)
[![](https://sonarcloud.io/api/project_badges/measure?project=owasp-modsecurity_ModSecurity&metric=security_rating
)](https://sonarcloud.io/dashboard?id=owasp-modsecurity_ModSecurity)
[![](https://sonarcloud.io/api/project_badges/measure?project=owasp-modsecurity_ModSecurity&metric=vulnerabilities
)](https://sonarcloud.io/dashboard?id=owasp-modsecurity_ModSecurity)
@ -21,7 +25,7 @@ capability to load/interpret rules written in the ModSecurity SecRules format
and apply them to HTTP content provided by your application via Connectors.
If you are looking for ModSecurity for Apache (aka ModSecurity v2.x), it is still under maintenance and available:
[here](https://github.com/SpiderLabs/ModSecurity/tree/v2/master).
[here](https://github.com/owasp-modsecurity/ModSecurity/tree/v2/master).
### What is the difference between this project and the old ModSecurity (v2.x.x)?
@ -37,7 +41,7 @@ As a result of this goal we have rearchitected Libmodsecurity such that it is no
### It is no longer just a module.
The 'ModSecurity' branch no longer contains the traditional module logic (for Nginx, Apache, and IIS) that has traditionally been packaged all together. Instead, this branch only contains the library portion (libmodsecurity) for this project. This library is consumed by what we have termed 'Connectors' these connectors will interface with your webserver and provide the library with a common format that it understands. Each of these connectors is maintained as a separate GitHub project. For instance, the Nginx connector is supplied by the ModSecurity-nginx project (https://github.com/SpiderLabs/ModSecurity-nginx).
The 'ModSecurity' branch no longer contains the traditional module logic (for Nginx, Apache, and IIS) that has traditionally been packaged all together. Instead, this branch only contains the library portion (libmodsecurity) for this project. This library is consumed by what we have termed 'Connectors' these connectors will interface with your webserver and provide the library with a common format that it understands. Each of these connectors is maintained as a separate GitHub project. For instance, the Nginx connector is supplied by the ModSecurity-nginx project (https://github.com/owasp-modsecurity/ModSecurity-nginx).
Keeping these connectors separated allows each project to have different release cycles, issues and development trees. Additionally, it means that when you install ModSecurity v3 you only get exactly what you need, no extras you won't be using.
@ -57,7 +61,13 @@ As a dynamic library, dont forget that libmodsecurity must be installed to a
### Unix (Linux, MacOS, FreeBSD, …)
On unix the project uses autotools to help the compilation process.
On unix the project uses autotools to help the compilation process. Please note that if you are working with `git`, don't forget to initialize and update the submodules. Here's a quick how-to:
```shell
$ git clone --recursive https://github.com/owasp-modsecurity/ModSecurity ModSecurity
$ cd ModSecurity
```
You can then start the build process:
```shell
$ ./build.sh
@ -67,16 +77,15 @@ $ sudo make install
```
Details on distribution specific builds can be found in our Wiki:
[Compilation Recipes](https://github.com/SpiderLabs/ModSecurity/wiki/Compilation-recipes)
[Compilation Recipes](https://github.com/owasp-modsecurity/ModSecurity/wiki/Compilation-recipes)
### Windows
Windows build is not ready yet.
Windows build information can be found [here](build/win32/README.md).
## Dependencies
This library is written in C++ using the C++11 standards. It also uses Flex
This library is written in C++ using the C++17 standards. It also uses Flex
and Yacc to produce the “Sec Rules Language” parser. Other, mandatory dependencies include YAJL, as ModSecurity uses JSON for producing logs and its testing framework, libpcre (not yet mandatory) for processing regular expressions in SecRules, and libXML2 (not yet mandatory) which is used for parsing XML requests.
All others dependencies are related to operators specified within SecRules or configuration directives and may not be required for compilation. A short list of such dependencies is as follows:
@ -210,8 +219,8 @@ the utilities, follow the commands listed below:
$ cd /path/to/your/ModSecurity
$ git submodule foreach git pull
$ cd test
$ ./regression-tests
$ ./unit-tests
$ ./regression_tests
$ ./unit_tests
```
### Debugging
@ -231,11 +240,90 @@ CFLAGS to disable the compilation optimization parameters:
```shell
$ export CFLAGS="-g -O0"
$ ./build.sh
$ ./configure
$ ./configure --enable-assertions=yes
$ make
$ sudo make install
```
"Assertions allow us to document assumptions and to spot violations early in the
development process. What is more, assertions allow us to spot violations with a
minimum of effort." https://dl.acm.org/doi/pdf/10.1145/240964.240969
It is recommended to use assertions where applicable, and to enable them with
'--enable-assertions=yes' during the testing and debugging workflow.
### Benchmarking
The source tree includes a Benchmark tool that can help measure library performance. The tool is located in the `test/benchmark/` directory. The build process also creates the binary here, so you will have the tool after the compilation is finished.
To run, just type:
```shell
cd test/benchmark
$ ./benchmark
Doing 1000000 transactions...
```
You can also pass a lower value:
```shell
$ ./benchmark 1000
Doing 1000 transactions...
```
To measure the time:
```shell
$ time ./benchmark 1000
Doing 1000 transactions...
real 0m0.351s
user 0m0.337s
sys 0m0.022s
```
This is very fast because the benchmark uses the minimal `modsecurity.conf.default` configuration, which doesn't include too many rules:
```shell
$ cat basic_rules.conf
Include "../../modsecurity.conf-recommended"
```
To measure with real rules, run one of the download scripts in the same directory:
```shell
$ ./download-owasp-v3-rules.sh
Cloning into 'owasp-v3'...
remote: Enumerating objects: 33007, done.
remote: Counting objects: 100% (2581/2581), done.
remote: Compressing objects: 100% (907/907), done.
remote: Total 33007 (delta 2151), reused 2004 (delta 1638), pack-reused 30426
Receiving objects: 100% (33007/33007), 9.02 MiB | 16.21 MiB/s, done.
Resolving deltas: 100% (25927/25927), done.
Switched to a new branch 'tag3.0.2'
/path/to/ModSecurity/test/benchmark
Done.
$ cat basic_rules.conf
Include "../../modsecurity.conf-recommended"
Include "owasp-v3/crs-setup.conf.example"
Include "owasp-v3/rules/*.conf"
```
Now the command will give much higher value.
#### How the benchmark works
The tool is a straightforward wrapper application that utilizes the library. It creates a ModSecurity instance and a RuleSet instance, then runs a loop based on the specified number. Within this loop, it creates a Transaction object to emulate real HTTP transactions.
Each transaction is an HTTP/1.1 GET request with some GET parameters. Common headers are added, followed by the response headers and an XML body. Between phases, the tool checks whether an intervention has occurred. All transactions are created with the same data.
Note that the tool does not call the last phase (logging).
Please remember to reset `basic_rules.conf` if you want to try with a different ruleset.
## Reporting Issues
@ -251,7 +339,7 @@ is one.
### Security issue
Please do not make public any security issue. Contact us at:
security@modsecurity.org reporting the issue. Once the problem is fixed your
modsecurity@owasp.org reporting the issue. Once the problem is fixed your
credit will be given.
## Feature request
@ -262,8 +350,9 @@ new issue, please check if there is one already opened on the same topic.
## Bindings
The libModSecurity design allows the integration with bindings. There is an effort to avoid breaking API [binary] compatibility to make an easy integration with possible bindings. Currently, there are two notable projects maintained by the community:
The libModSecurity design allows the integration with bindings. There is an effort to avoid breaking API [binary] compatibility to make an easy integration with possible bindings. Currently, there are a few notable projects maintained by the community:
* Python - https://github.com/actions-security/pymodsecurity
* Rust - https://github.com/rkrishn7/rust-modsecurity
* Varnish - https://github.com/xdecock/vmod-modsecurity
## Packaging

View File

@ -6,4 +6,4 @@ The latest versions of both v2.9.x and v3.0.x are supported.
## Reporting a Vulnerability
For information on how to report a security issue, please see https://github.com/SpiderLabs/ModSecurity#security-issue
For information on how to report a security issue, please see https://github.com/owasp-modsecurity/ModSecurity#security-issue

File diff suppressed because it is too large Load Diff

View File

@ -1,171 +0,0 @@
# ============================================================================
# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html
# ============================================================================
#
# SYNOPSIS
#
# AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional])
#
# DESCRIPTION
#
# Check for baseline language coverage in the compiler for the C++11
# standard; if necessary, add switches to CXXFLAGS to enable support.
#
# The first argument, if specified, indicates whether you insist on an
# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
# -std=c++11). If neither is specified, you get whatever works, with
# preference for an extended mode.
#
# The second argument, if specified 'mandatory' or if left unspecified,
# indicates that baseline C++11 support is required and that the macro
# should error out if no mode with that support is found. If specified
# 'optional', then configuration proceeds regardless, after defining
# HAVE_CXX11 if and only if a supporting mode is found.
#
# LICENSE
#
# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com>
# Copyright (c) 2015 Paul Norman <penorman@mac.com>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 12
m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [[
template <typename T>
struct check
{
static_assert(sizeof(int) <= sizeof(T), "not big enough");
};
struct Base {
virtual void f() {}
};
struct Child : public Base {
virtual void f() override {}
};
typedef check<check<bool>> right_angle_brackets;
int a;
decltype(a) b;
typedef check<int> check_type;
check_type c;
check_type&& cr = static_cast<check_type&&>(c);
auto d = a;
auto l = [](){};
// Prevent Clang error: unused variable 'l' [-Werror,-Wunused-variable]
struct use_l { use_l() { l(); } };
// http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
// Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function because of this
namespace test_template_alias_sfinae {
struct foo {};
template<typename T>
using member = typename T::member_type;
template<typename T>
void func(...) {}
template<typename T>
void func(member<T>*) {}
void test();
void test() {
func<foo>(0);
}
}
// Check for C++11 attribute support
void noret [[noreturn]] () { throw 0; }
]])
AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl
m4_if([$1], [], [],
[$1], [ext], [],
[$1], [noext], [],
[m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl
m4_if([$2], [], [ax_cxx_compile_cxx11_required=true],
[$2], [mandatory], [ax_cxx_compile_cxx11_required=true],
[$2], [optional], [ax_cxx_compile_cxx11_required=false],
[m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])])
AC_LANG_PUSH([C++])dnl
ac_success=no
AC_CACHE_CHECK(whether $CXX supports C++11 features by default,
ax_cv_cxx_compile_cxx11,
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
[ax_cv_cxx_compile_cxx11=yes],
[ax_cv_cxx_compile_cxx11=no])])
if test x$ax_cv_cxx_compile_cxx11 = xyes; then
ac_success=yes
fi
m4_if([$1], [noext], [], [dnl
if test x$ac_success = xno; then
for switch in -std=gnu++11 -std=gnu++0x; do
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
$cachevar,
[ac_save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS $switch"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
[eval $cachevar=yes],
[eval $cachevar=no])
CXXFLAGS="$ac_save_CXXFLAGS"])
if eval test x\$$cachevar = xyes; then
CXXFLAGS="$CXXFLAGS $switch"
ac_success=yes
break
fi
done
fi])
m4_if([$1], [ext], [], [dnl
if test x$ac_success = xno; then
dnl HP's aCC needs +std=c++11 according to:
dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf
for switch in -std=c++11 -std=c++0x +std=c++11; do
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
$cachevar,
[ac_save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS $switch"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
[eval $cachevar=yes],
[eval $cachevar=no])
CXXFLAGS="$ac_save_CXXFLAGS"])
if eval test x\$$cachevar = xyes; then
CXXFLAGS="$CXXFLAGS $switch"
ac_success=yes
break
fi
done
fi])
AC_LANG_POP([C++])
if test x$ax_cxx_compile_cxx11_required = xtrue; then
if test x$ac_success = xno; then
AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.])
fi
else
if test x$ac_success = xno; then
HAVE_CXX11=0
AC_MSG_NOTICE([No compiler with C++11 support was found])
else
HAVE_CXX11=1
AC_DEFINE(HAVE_CXX11,1,
[define if the compiler supports basic C++11 syntax])
fi
AC_SUBST(HAVE_CXX11)
fi
])

View File

@ -192,29 +192,30 @@ AC_DEFUN([CHECK_FOR_LUA_AT], [
LUA_DISPLAY="${lua_lib_file}, ${lua_inc_path}"
# Double checking version from lua.h...
AC_TRY_COMPILE([ #include <lua.h>> ],
[ #if (LUA_VERSION_NUM < 502)
return 0;
#else
#error Lua 5.1 not detected
#endif ],
[ LUA_VERSION=501 ], [ lua_5_1=0 ]
)
AC_TRY_COMPILE([ #include <lua.h> ],
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <lua.h> ],
[ #if (LUA_VERSION_NUM == 502)
return 0;
#else
#error Lua 5.2 not detected
#endif ],
#endif ]])],
[ LUA_VERSION=502 ], [ lua_5_2=0 ]
)
AC_TRY_COMPILE([ #include <lua.h> ],
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <lua.h> ],
[ #if (LUA_VERSION_NUM == 502)
return 0;
#else
#error Lua 5.2 not detected
#endif ]])],
[ LUA_VERSION=502 ], [ lua_5_2=0 ]
)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <lua.h> ],
[ #if (LUA_VERSION_NUM == 504)
return 0;
#else
#error Lua 5.4 not detected
#endif ],
#endif ]])],
[ LUA_VERSION=504 ], [ lua_5_4=0 ]
)

View File

@ -21,36 +21,47 @@ AC_ARG_WITH(
[test_paths="${with_pcre}"],
[test_paths="/usr/local/libpcre /usr/local/pcre /usr/local /opt/libpcre /opt/pcre /opt /usr /opt/local"])
if test "x${with_pcre2}" != "x" && test "x${with_pcre2}" != "xno"; then
AC_MSG_NOTICE([pcre2 specified; omitting check for pcre])
if test "x${with_pcre}" == "x" && test "x${with_pcre}" != "xno"; then
AC_MSG_NOTICE([Support for pcre not requested; omitting check for pcre])
else
AC_MSG_CHECKING([for libpcre config script])
for x in ${test_paths}; do
dnl # Determine if the script was specified and use it directly
if test ! -d "$x" -a -e "$x"; then
PCRE_CONFIG=$x
pcre_path="no"
break
fi
AC_CHECK_PROG([PCRE_CONFIG_IN_ENV], [pcre-config], [yes], [no])
dnl # Try known config script names/locations
for PCRE_CONFIG in pcre-config; do
if test -e "${x}/bin/${PCRE_CONFIG}"; then
pcre_path="${x}/bin"
if test "$PCRE_CONFIG_IN_ENV" = "yes"; then
AC_MSG_NOTICE([pcre-config found in envinronment])
PCRE_CONFIG=pcre-config
pcre_path="no"
else
AC_MSG_NOTICE([pcre-config not found in environment. checking known paths])
for x in ${test_paths}; do
dnl # Determine if the script was specified and use it directly
if test ! -d "$x" -a -e "$x"; then
PCRE_CONFIG=$x
pcre_path="no"
break
elif test -e "${x}/${PCRE_CONFIG}"; then
pcre_path="${x}"
fi
dnl # Try known config script names/locations
for PCRE_CONFIG in pcre-config; do
if test -e "${x}/bin/${PCRE_CONFIG}"; then
pcre_path="${x}/bin"
break
elif test -e "${x}/${PCRE_CONFIG}"; then
pcre_path="${x}"
break
else
pcre_path=""
fi
done
if test -n "$pcre_path"; then
break
else
pcre_path=""
fi
done
if test -n "$pcre_path"; then
break
fi
done
fi
if test -n "${pcre_path}"; then
if test "${pcre_path}" != "no"; then
@ -77,9 +88,11 @@ else
CFLAGS="${PCRE_CFLAGS} ${CFLAGS}"
LDFLAGS="${PCRE_LDADD} ${LDFLAGS}"
LIBS="${PCRE_LDADD} ${LIBS}"
AC_TRY_LINK([ #include <pcre.h> ],
[ pcre_jit_exec(NULL, NULL, NULL, 0, 0, 0, NULL, 0, NULL); ],
[ pcre_jit_available=yes ], [:]
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([[ #include <pcre.h> ]],
[[ pcre_jit_exec(NULL, NULL, NULL, 0, 0, 0, NULL, 0, NULL); ]])],
[ pcre_jit_available=yes ],
[:]
)
if test "x$pcre_jit_available" = "xyes"; then
@ -93,6 +106,7 @@ else
LIBS=$save_LIBS
fi
PCRE_CFLAGS="-DWITH_PCRE ${PCRE_CFLAGS}"
AC_SUBST(PCRE_CONFIG)
AC_SUBST(PCRE_VERSION)
AC_SUBST(PCRE_CPPFLAGS)

View File

@ -29,10 +29,12 @@ if test "x${with_pcre2}" == "xno"; then
AC_MSG_NOTICE([Support for PCRE2 was disabled by the utilization of --without-pcre2 or --with-pcre2=no])
PCRE2_DISABLED=yes
else
if test "x${with_pcre2}" == "xyes"; then
PCRE2_MANDATORY=yes
AC_MSG_NOTICE([PCRE2 support was marked as mandatory by the utilization of --with-pcre2=yes])
fi
PCRE2_MANDATORY=yes
AC_MSG_NOTICE([PCRE2 is enabled by default.])
# if test "x${with_pcre2}" == "xyes"; then
# PCRE2_MANDATORY=yes
# AC_MSG_NOTICE([PCRE2 support was marked as mandatory by the utilization of --with-pcre2=yes])
# fi
# for x in ${PCRE2_POSSIBLE_LIB_NAMES}; do
# CHECK_FOR_PCRE2_AT(${x})
# if test -n "${PCRE2_VERSION}"; then
@ -96,9 +98,14 @@ else
AC_MSG_NOTICE([PCRE2 is disabled by default.])
else
PCRE2_FOUND=1
AC_MSG_NOTICE([using PCRE2 v${PCRE2_VERSION}])
PCRE2_CFLAGS="-DWITH_PCRE2 ${PCRE2_CFLAGS}"
PCRE2_CFLAGS="${PCRE2_CFLAGS}"
PCRE2_DISPLAY="${PCRE2_LDADD}, ${PCRE2_CFLAGS}"
AC_MSG_NOTICE([using PCRE2_VERSION ${PCRE2_VERSION}])
AC_MSG_NOTICE([using PCRE2_LDADD ${PCRE2_LDADD}])
AC_MSG_NOTICE([using PCRE2_LIBS ${PCRE2_LIBS}])
AC_MSG_NOTICE([using PCRE2_LDFLAGS ${PCRE2_LDFLAGS}])
AC_MSG_NOTICE([using PCRE2_CFLAGS ${PCRE2_CFLAGS}])
AC_MSG_NOTICE([using PCRE2_DISPLAY ${PCRE2_DISPLAY}])
AC_SUBST(PCRE2_VERSION)
AC_SUBST(PCRE2_LDADD)
AC_SUBST(PCRE2_LIBS)

272
build/win32/CMakeLists.txt Normal file
View File

@ -0,0 +1,272 @@
cmake_minimum_required(VERSION 3.24)
set(BASE_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
option(WITH_LMDB "Include LMDB support" OFF)
option(WITH_LUA "Include LUA support" ON)
option(WITH_LIBXML2 "Include LibXML2 support" ON)
option(WITH_MAXMIND "Include MaxMind support" ON)
option(WITH_CURL "Include CURL support" ON)
option(USE_ASAN "Build with Address Sanitizer" OFF)
# 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="mbedtls/mbedtls_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)
set(LIBINJECTION_DIR ${BASE_DIR}/others/libinjection)
add_library(libinjection STATIC ${LIBINJECTION_DIR}/src/libinjection_sqli.c ${LIBINJECTION_DIR}/src/libinjection_xss.c ${LIBINJECTION_DIR}/src/libinjection_html5.c)
# get libinjection version with git describe
execute_process(
COMMAND git describe
WORKING_DIRECTORY ${LIBINJECTION_DIR}
OUTPUT_VARIABLE LIBINJECTION_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
message("-- Detecting libinjection version - ${LIBINJECTION_VERSION}")
target_compile_definitions(libinjection PRIVATE LIBINJECTION_VERSION="${LIBINJECTION_VERSION}")
# mbedtls (mbedcrypto)
project(mbedcrypto C)
set(MBEDTLS_DIR ${BASE_DIR}/others/mbedtls)
add_library(mbedcrypto STATIC ${MBEDTLS_DIR}/library/base64.c ${MBEDTLS_DIR}/library/sha1.c ${MBEDTLS_DIR}/library/md5.c ${MBEDTLS_DIR}/library/platform_util.c ${MBEDTLS_DIR}/library/constant_time.c)
target_include_directories(mbedcrypto PRIVATE ${MBEDTLS_DIR}/include)
# get mbedtls version with git describe
execute_process(
COMMAND git describe
WORKING_DIRECTORY ${MBEDTLS_DIR}
OUTPUT_VARIABLE MBEDTLS_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
message("-- Detecting Mbed TLS version - ${MBEDTLS_VERSION}")
#
# 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_YAJL 1) # should always be one, mandatory dependency
set(HAVE_GEOIP 0) # should always be zero, no conan package available
set(HAVE_SSDEEP 0) # should always be zero, no conan package available
macro(enable_feature flag option)
if(${option})
set(${flag} 1) # ON
else()
set(${flag} 0) # OFF
endif()
endmacro()
enable_feature(HAVE_LMDB ${WITH_LMDB})
enable_feature(HAVE_LUA ${WITH_LUA})
enable_feature(HAVE_LIBXML2 ${WITH_LIBXML2})
enable_feature(HAVE_MAXMIND ${WITH_MAXMIND})
enable_feature(HAVE_CURL ${WITH_CURL})
include(${CMAKE_CURRENT_LIST_DIR}/ConfigureChecks.cmake)
configure_file(config.h.cmake ${BASE_DIR}/src/config.h)
find_package(PCRE2 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 ${MBEDTLS_DIR}/include)
target_link_libraries(libModSecurity PRIVATE pcre2::pcre2 libinjection mbedcrypto 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} ${BASE_DIR}/test/common/custom_debug_log.cc)
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} ${BASE_DIR}/test/common/custom_debug_log.cc)
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)
enable_testing()
file(READ ${BASE_DIR}/test/test-suite.in TEST_FILES_RAW)
string(REPLACE "\n" ";" TEST_FILES ${TEST_FILES_RAW})
foreach(TEST_FILE ${TEST_FILES})
# ignore comment lines
string(FIND ${TEST_FILE} "#" is_comment)
if(NOT is_comment EQUAL 0)
string(FIND ${TEST_FILE} "TESTS+=" is_valid_prefix)
if(NOT is_valid_prefix EQUAL 0)
message(FATAL_ERROR "Invalid prefix in line: ${TEST_FILE}")
endif()
# remove 'TESTS+=' prefix and 'test/' too because tests are launched
# from that directory
string(SUBSTRING ${TEST_FILE} 12 -1 TEST_FILE)
# test name
get_filename_component(TEST_NAME ${TEST_FILE} NAME_WE)
# determine test runner based on test path prefix
string(FIND ${TEST_FILE} "test-cases/regression/" is_regression_test)
if(is_regression_test EQUAL 0)
set(TEST_RUNNER "regression_tests")
else()
set(TEST_RUNNER "unit_tests")
endif()
add_test(NAME ${TEST_NAME} COMMAND ${TEST_RUNNER} ${TEST_FILE} WORKING_DIRECTORY ${BASE_DIR}/test)
endif()
endforeach()
# 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)
# reading_logs_with_offset
add_executable(reading_logs_with_offset ${BASE_DIR}/examples/reading_logs_with_offset/read.cc)
setExampleTargetProperties(reading_logs_with_offset)
# multithread
add_executable(multithread ${BASE_DIR}/examples/multithread/multithread.cc)
setExampleTargetProperties(multithread)
# 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)

View File

@ -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)

112
build/win32/README.md Normal file
View File

@ -0,0 +1,112 @@
# 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.10.2](https://github.com/conan-io/conan/releases/download/2.10.2/conan-2.10.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 listed 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`
* `multithread.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 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] 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 libmodsecurity`

14
build/win32/conanfile.txt Normal file
View File

@ -0,0 +1,14 @@
[requires]
yajl/2.1.0
pcre2/10.42
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

View File

@ -0,0 +1,92 @@
/* config.h.cmake. Based upon generated config.h.in. */
#ifndef MODSECURITY_CONFIG_H
#define MODSECURITY_CONFIG_H 1
/* Define to 1 if you have the <dlfcn.h> header file. */
#cmakedefine HAVE_DLFCN_H
/* Define to 1 if you have the <inttypes.h> header file. */
#cmakedefine HAVE_INTTYPES_H
/* Define to 1 if you have the <iostream> header file. */
#cmakedefine HAVE_IOSTREAM
/* Define to 1 if you have the <stdint.h> header file. */
#cmakedefine HAVE_STDINT_H
/* Define to 1 if you have the <stdio.h> header file. */
#cmakedefine HAVE_STDIO_H
/* Define to 1 if you have the <stdlib.h> header file. */
#cmakedefine HAVE_STDLIB_H
/* Define to 1 if you have the <string> header file. */
#cmakedefine HAVE_STRING
/* Define to 1 if you have the <strings.h> header file. */
#cmakedefine HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#cmakedefine HAVE_STRING_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#cmakedefine HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#cmakedefine HAVE_SYS_TYPES_H
/* Define to 1 if you have the <sys/utsname.h> header file. */
#cmakedefine HAVE_SYS_UTSNAME_H
/* Define to 1 if you have the <unistd.h> header file. */
#cmakedefine HAVE_UNISTD_H
/* Define if GeoIP is available */
#cmakedefine HAVE_GEOIP
/* Define if LMDB is available */
#cmakedefine HAVE_LMDB
/* Define if LUA is available */
#cmakedefine HAVE_LUA
/* Define if MaxMind is available */
#cmakedefine HAVE_MAXMIND
/* Define if SSDEEP is available */
#cmakedefine HAVE_SSDEEP
/* Define if YAJL is available */
#cmakedefine HAVE_YAJL
/* Define if libcurl is available */
#cmakedefine HAVE_CURL
/* Name of package */
#define PACKAGE "@PACKAGE_NAME@"
/* Define to the address where bug reports for this package should be sent. */
#cmakedefine PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@"
/* Define to the full name of this package. */
#cmakedefine PACKAGE_NAME "@PACKAGE_NAME@"
/* Define to the full name and version of this package. */
#cmakedefine PACKAGE_STRING "@PACKAGE_STRING@"
/* Define to the one symbol short name of this package. */
#cmakedefine PACKAGE_TARNAME "@PACKAGE_TARNAME@"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#cmakedefine PACKAGE_VERSION "@PACKAGE_VERSION@"
/* Define to 1 if you have the ANSI C header files. */
#ifndef STDC_HEADERS
#cmakedefine STDC_HEADERS
#endif
#endif // ndef MODSECURITY_CONFIG_H

View File

@ -0,0 +1,115 @@
# escape=`
ARG FROM_IMAGE=mcr.microsoft.com/windows/servercore:ltsc2022
FROM ${FROM_IMAGE}
# reset the shell.
SHELL ["cmd", "/S", "/C"]
# set up environment to collect install errors.
COPY InstallBuildTools.cmd C:\TEMP\
ADD https://aka.ms/vscollect.exe C:\TEMP\collect.exe
# download channel for fixed install.
ARG CHANNEL_URL=https://aka.ms/vs/17/release/channel
ADD ${CHANNEL_URL} C:\TEMP\VisualStudio.chman
# download and install Build Tools for Visual Studio 2022 for native desktop workload.
ADD https://aka.ms/vs/17/release/vs_buildtools.exe C:\TEMP\vs_buildtools.exe
RUN C:\TEMP\InstallBuildTools.cmd C:\TEMP\vs_buildtools.exe --quiet --wait --norestart --nocache `
--channelUri C:\TEMP\VisualStudio.chman `
--installChannelUri C:\TEMP\VisualStudio.chman `
--add Microsoft.VisualStudio.Workload.VCTools `
--includeRecommended `
--installPath C:\BuildTools
# download & install GIT
ARG GIT_VERSION=2.44.0
ARG GIT_BINARY=Git-${GIT_VERSION}-64-bit.exe
ARG GIT_URL=https://github.com/git-for-windows/git/releases/download/v${GIT_VERSION}.windows.1/${GIT_BINARY}
COPY git.inf C:\TEMP\
ARG INSTALLER=C:\TEMP\${GIT_BINARY}
ADD ${GIT_URL} ${INSTALLER}
RUN %INSTALLER% /SP- /VERYSILENT /SUPPRESSMSGBOXES /NOCANCEL `
/NORESTART /CLOSEAPPLICATIONS /RESTARTAPPLICATIONS /LOADINF=git.inf
# download & setup conan
ARG CONAN_VERSION=2.10.2
ARG CONAN_BINARY=conan-${CONAN_VERSION}-windows-x86_64-installer.exe
ARG CONAN_URL=https://github.com/conan-io/conan/releases/download/${CONAN_VERSION}/${CONAN_BINARY}
ARG INSTALLER=C:\TEMP\${CONAN_BINARY}
ADD ${CONAN_URL} ${INSTALLER}
RUN %INSTALLER% /SP- /VERYSILENT /SUPPRESSMSGBOXES
# setup conan profile
RUN C:\BuildTools\VC\Auxiliary\Build\vcvars64.bat && conan profile detect --force
# download libModSecurity
#
# create src dir
ARG SRC_DIR=C:\src
WORKDIR C:\
RUN cmd.exe /C md %SRC_DIR%
# libModSecurity
WORKDIR ${SRC_DIR}
ARG MOD_SECURITY_TAG=v3/master
RUN git clone -c advice.detachedHead=false --depth 1 --branch %MOD_SECURITY_TAG% https://github.com/owasp-modsecurity/ModSecurity.git
ARG MOD_SECURITY_DIR=${SRC_DIR}\ModSecurity
WORKDIR ${MOD_SECURITY_DIR}
# fetch submodules (bindings/python, others/libinjection, test/test-cases/secrules-language-tests)
RUN git submodule init
RUN git submodule update
# build libraries
#
ARG BUILD_TYPE=Release
ARG ARCH=x86_64
ARG USE_ASAN=
RUN C:\BuildTools\VC\Auxiliary\Build\vcvars64.bat && vcbuild.bat %BUILD_TYPE% %ARCH% %USE_ASAN%
# test suite
#
# setup test environment
RUN cmd.exe /C md \tmp
RUN cmd.exe /C md \bin
RUN cmd.exe /C copy "C:\Program Files\GIT\usr\bin" \bin > NUL
RUN cmd.exe /C copy "C:\Program Files\GIT\usr\bin\echo.exe" \bin\echo > NUL
# disable tests that don't work on windows
ARG JQ_VERSION=1.7.1
ARG JQ_BINARY=jq-windows-amd64.exe
ARG JQ_URL=https://github.com/jqlang/jq/releases/download/jq-${JQ_VERSION}/${JQ_BINARY}
ARG JQ_BIN=C:\TEMP\jq.exe
ADD ${JQ_URL} ${JQ_BIN}
WORKDIR ${MOD_SECURITY_DIR}\test\test-cases\regression
RUN %JQ_BIN% "map(if .title == \"Test match variable (1/n)\" then .enabled = 0 else . end)" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json
RUN %JQ_BIN% "map(if .title == \"Test match variable (2/n)\" then .enabled = 0 else . end)" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json
RUN %JQ_BIN% "map(if .title == \"Test match variable (3/n)\" then .enabled = 0 else . end)" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json
RUN %JQ_BIN% "map(if .title == \"Variable offset - FILES_NAMES\" then .enabled = 0 else . end)" offset-variable.json > tmp.json && move /Y tmp.json offset-variable.json
# run tests
WORKDIR ${MOD_SECURITY_DIR}\build\win32\build
RUN C:\BuildTools\VC\Auxiliary\Build\vcvars64.bat && ctest -C %BUILD_TYPE% --output-on-failure
# setup container's entrypoint
#
WORKDIR C:\
# Use developer command prompt and start PowerShell if no other command specified.
ENTRYPOINT ["C:\\BuildTools\\VC\\Auxiliary\\Build\\vcvars64.bat", "&&", "powershell.exe", "-NoLogo", "-ExecutionPolicy", "Bypass"]

View File

@ -0,0 +1,17 @@
@rem Copyright (C) Microsoft Corporation. All rights reserved.
@rem Licensed under the MIT license. See LICENSE.txt in the project root for license information.
@if not defined _echo echo off
setlocal enabledelayedexpansion
call %*
if "%ERRORLEVEL%"=="3010" (
exit /b 0
) else (
if not "%ERRORLEVEL%"=="0" (
set ERR=%ERRORLEVEL%
call C:\TEMP\collect.exe -zip:C:\vslogs.zip
exit /b !ERR!
)
)

View File

@ -0,0 +1,20 @@
[Setup]
Lang=default
Dir=C:\Program Files\Git
Group=Git
NoIcons=0
SetupType=default
Components=ext,ext\shellhere,ext\guihere,gitlfs,assoc,autoupdate
Tasks=
EditorOption=VIM
CustomEditorPath=
PathOption=Cmd
SSHOption=OpenSSH
TortoiseOption=false
CURLOption=WinSSL
CRLFOption=LFOnly
BashTerminalOption=ConHost
PerformanceTweaksFSCache=Enabled
UseCredentialManager=Enabled
EnableSymlinks=Disabled
EnableBuiltinInteractiveAdd=Disabled

View File

@ -62,7 +62,7 @@ else
YAJL_DISPLAY="${YAJL_LDADD}, ${YAJL_CFLAGS}"
else
# If pkg-config did not find anything useful, go over file lookup.
for x in ${YAJL_POSSIBLE_LIB_NAMES}; do
for x in ${YAJL_POSSIBLE_PATHS}; do
CHECK_FOR_YAJL_AT(${x})
if test -n "${YAJL_VERSION}"; then
break
@ -78,6 +78,29 @@ else
# fi
fi
# FIX: if the include directory in CFLAGS ends with "include/yajl",
# remove the suffix "/yajl". the library header files are included
# using the prefix (for example, #include <yajl/yajl_tree.h>), and
# this is even the case for the library itself (for example,
# yajl_tree.h includes yajl/yajl_common.h).
new_cflags=""
for flag in $YAJL_CFLAGS; do
case "$flag" in
-I*/include/yajl)
new_flag="${flag%/yajl}"
new_cflags="$new_cflags $new_flag"
;;
*)
new_cflags="$new_cflags $flag"
;;
esac
done
YAJL_CFLAGS="$new_cflags"
if test -z "${YAJL_LDADD}"; then
if test -z "${YAJL_MANDATORY}"; then
if test -z "${YAJL_DISABLED}"; then

View File

@ -42,7 +42,7 @@ AC_PREFIX_DEFAULT([/usr/local/modsecurity])
# General automake options.
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects])
AM_INIT_AUTOMAKE([-Wall foreign subdir-objects])
# Check for dependencies (C++, AR, Lex, Yacc and Make)
@ -52,8 +52,8 @@ AC_PROG_MAKE_SET
PKG_PROG_PKG_CONFIG
# Check if the compiler is c++11 compatible.
# AX_CXX_COMPILE_STDCXX_11(,mandatory)
# Set C++ standard version and check if compiler supports it.
AX_CXX_COMPILE_STDCXX(17, noext, mandatory)
# Check for libinjection
if ! test -f "${srcdir}/others/libinjection/src/libinjection_html5.c"; then
@ -75,6 +75,28 @@ AC_MSG_ERROR([\
fi
# Libinjection version
AC_DEFUN([LIBINJECTION_VERSION], m4_esyscmd_s(cd "others/libinjection" && git describe && cd ../..))
AC_SUBST([LIBINJECTION_VERSION])
# Check for Mbed TLS
if ! test -f "${srcdir}/others/mbedtls/library/base64.c"; then
AC_MSG_ERROR([\
Mbed TLS was not found within ModSecurity source directory.
Mbed TLS code is available as part of ModSecurity source code in a format
of a git-submodule. git-submodule allow us to specify the correct version of
Mbed TLS and still uses the Mbed TLS repository to download it.
You can download Mbed TLS using git:
$ git submodule init
$ git submodule update
])
fi
# Mbed TLS version
AC_DEFUN([MBEDTLS_VERSION], m4_esyscmd_s(cd "others/mbedtls" && git describe && cd ../..))
# SecLang test version
AC_DEFUN([SECLANG_TEST_VERSION], m4_esyscmd_s(cd "test/test-cases/secrules-language-tests" && git log -1 --format="%h" --abbrev-commit && cd ../../..))
@ -87,24 +109,19 @@ AM_CONDITIONAL([YAJL_VERSION], [test "$YAJL_VERSION" != ""])
# Check for LibGeoIP
PROG_GEOIP
AM_CONDITIONAL([GEOIP_CFLAGS], [test "GEOIP_CFLAGS" != ""])
# Check for MaxMind
PROG_MAXMIND
AM_CONDITIONAL([MAXMIND_CFLAGS], [test "MAXMIND_CFLAGS" != ""])
# Check for LMDB
PROG_LMDB
AM_CONDITIONAL([LMDB_CFLAGS], [test "LMDB_CFLAGS" != ""])
# Check for SSDEEP
CHECK_SSDEEP
AM_CONDITIONAL([SSDEEP_CFLAGS], [test "SSDEEP_CFLAGS" != ""])
# Check for LUA
CHECK_LUA
AM_CONDITIONAL([LUA_CFLAGS], [test "LUA_CFLAGS" != ""])
#
@ -124,27 +141,26 @@ CHECK_LIBXML2
#
# Check for libpcre
# Check for libpcre only if explicitly requested
#
CHECK_PCRE
#
# Check for pcre2
#
PROG_PCRE2
AM_CONDITIONAL([PCRE2_CFLAGS], [test "PCRE2_CFLAGS" != ""])
if test "x${with_pcre}" != "x" && test "x${with_pcre}" != "xno"; then
CHECK_PCRE
else
#
# Check for pcre2
#
PROG_PCRE2
fi
# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([string])
AC_CHECK_HEADERS([iostream])
AC_CHECK_HEADERS([sys/utsname.h])
# ??
LT_INIT([dlopen])
# Initialize libtool
LT_INIT
# Identify platform
AC_CANONICAL_HOST
@ -227,6 +243,17 @@ AC_SUBST([MSC_VERSION])
MSC_GIT_VERSION=msc_version_git
AC_SUBST([MSC_GIT_VERSION])
AC_ARG_ENABLE(assertions,
[AS_HELP_STRING([--enable-assertions],[Turn on assertions feature: undefine NDEBUG])],
[case "${enableval}" in
yes) assertions=true ;;
no) assertions=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-assertions) ;;
esac],
[assertions=false]
)
AC_ARG_ENABLE(debug-logs,
[AS_HELP_STRING([--disable-debug-logs],[Turn off the SecDebugLog feature])],
@ -284,27 +311,10 @@ AC_ARG_ENABLE(parser-generation,
[buildParser=false]
)
# Mutex
AC_ARG_ENABLE(mutex-on-pm,
[AS_HELP_STRING([--enable-mutex-on-pm],[Treats pm operations as a critical section])],
[case "${enableval}" in
yes) mutexPm=true ;;
no) mutexPm=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-mutex-on-pm) ;;
esac],
[mutexPm=false]
)
if test "$mutexPm" == "true"; then
MODSEC_MUTEX_ON_PM="-DMUTEX_ON_PM=1"
AC_SUBST(MODSEC_MUTEX_ON_PM)
fi
if test $buildParser = true; then
AC_PROG_YACC
AC_PROG_LEX
AC_PROG_LEX(noyywrap)
AC_PATH_PROG([FLEX], [flex])
test "x$FLEX" = "x" && AC_MSG_ERROR([flex is needed to build ModSecurity])
@ -356,6 +366,14 @@ if test "$aflFuzzer" == "true"; then
GLOBAL_CPPFLAGS="$GLOBAL_CPPFLAGS $FUZZ_CPPCFLAGS"
$buildExamples = false
fi
case $assertions in
false) ASSERTIONS_CPPCFLAGS="-DNDEBUG" ;;
true) ASSERTIONS_CPPCFLAGS="-UNDEBUG" ;;
*) AC_MSG_ERROR(bad value ${assertions} for assertions) ;;
esac
GLOBAL_CPPFLAGS="$GLOBAL_CPPFLAGS $ASSERTIONS_CPPCFLAGS"
AC_SUBST(GLOBAL_LDADD)
AC_SUBST(GLOBAL_CPPFLAGS)
@ -383,6 +401,7 @@ AM_COND_IF([EXAMPLES],
examples/Makefile \
examples/simple_example_using_c/Makefile \
examples/multiprocess_c/Makefile \
examples/multithread/Makefile \
examples/reading_logs_with_offset/Makefile \
examples/reading_logs_via_rule_message/Makefile \
examples/using_bodies_in_chunks/Makefile \
@ -426,6 +445,8 @@ echo " "
echo " Mandatory dependencies"
AS_ECHO_N(" + libInjection ....")
echo LIBINJECTION_VERSION
AS_ECHO_N(" + Mbed TLS ....")
echo MBEDTLS_VERSION
AS_ECHO_N(" + SecLang tests ....")
echo SECLANG_TEST_VERSION
@ -561,6 +582,17 @@ if test "x$LUA_FOUND" = "x2"; then
echo " + LUA ....disabled"
fi
##PCRE
if test "x${with_pcre}" != "x" \
&& test "x${with_pcre}" != "xno" \
&& test "x${PCRE_VERSION}" == "x"; then
AC_MSG_NOTICE([*** pcre library not found.])
else
echo " + PCRE ....found "
echo " using pcre v${PCRE_VERSION}"
echo " ${PCRE_LDADD}, ${PCRE_CFLAGS}"
fi
## PCRE2
if test "x$PCRE2_FOUND" = "x0"; then
@ -590,6 +622,11 @@ if test $buildTestUtilities = true; then
else
echo " + Test Utilities ....disabled"
fi
if test $assertions = true; then
echo " + Assertions ....enabled"
else
echo " + Assertions ....disabled"
fi
if test $debugLogs = true; then
echo " + SecDebugLog ....enabled"
else

View File

@ -4,6 +4,7 @@ ACLOCAL_AMFLAGS = -I build
SUBDIRS = \
multiprocess_c \
multithread \
reading_logs_with_offset \
reading_logs_via_rule_message \
simple_example_using_c \

View File

@ -15,7 +15,6 @@ multi_LDFLAGS = \
-L$(top_builddir)/src/.libs/ \
$(GEOIP_LDFLAGS) \
-lmodsecurity \
-lpthread \
-lm \
-lstdc++ \
$(LUA_LDFLAGS) \

View File

@ -19,7 +19,11 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef WIN32
#include <unistd.h>
#else
#include <io.h>
#endif
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>
@ -34,7 +38,7 @@ RulesSet *rules = NULL;
ModSecurity *modsec = NULL;
void process_special_request (int j) {
static void process_special_request (int j) {
Transaction *transaction;
transaction = msc_new_transaction(modsec, rules, NULL);
@ -56,7 +60,7 @@ void process_special_request (int j) {
msc_transaction_cleanup(transaction);
}
void process_request (int j) {
static void process_request (int j) {
int i;
for (i = 0; i < REQUESTS_PER_PROCESS; i++) {

View File

@ -0,0 +1,57 @@
noinst_PROGRAMS = multithread
multithread_SOURCES = \
multithread.cc
multithread_LDADD = \
$(CURL_LDADD) \
$(GEOIP_LDADD) \
$(GLOBAL_LDADD) \
$(LIBXML2_LDADD) \
$(LMDB_LDADD) \
$(MAXMIND_LDADD) \
$(LUA_LDADD) \
$(PCRE_LDADD) \
$(PCRE2_LDADD) \
$(SSDEEP_LDADD) \
$(YAJL_LDADD)
multithread_LDFLAGS = \
-L$(top_builddir)/src/.libs/ \
$(GEOIP_LDFLAGS) \
-lmodsecurity \
-lpthread \
-lm \
-lstdc++ \
$(LMDB_LDFLAGS) \
$(LUA_LDFLAGS) \
$(MAXMIND_LDFLAGS) \
$(SSDEEP_LDFLAGS) \
$(YAJL_LDFLAGS)
multithread_CPPFLAGS = \
$(GLOBAL_CFLAGS) \
-I$(top_builddir)/headers \
-I$(top_builddir) \
-g \
-I../others \
-fPIC \
-O3 \
$(CURL_CFLAGS) \
$(GEOIP_CFLAGS) \
$(GLOBAL_CPPFLAGS) \
$(MODSEC_NO_LOGS) \
$(YAJL_CFLAGS) \
$(LMDB_CFLAGS) \
$(LUA_CFLAGS) \
$(PCRE_CFLAGS) \
$(PCRE2_CFLAGS) \
$(LIBXML2_CFLAGS)
MAINTAINERCLEANFILES = \
Makefile.in

View File

@ -0,0 +1,14 @@
SecDebugLog debug.log
SecDebugLogLevel 9
SecRule REQUEST_HEADERS:User-Agent ".*" "id:1,phase:1,t:sha1,t:hexEncode,setvar:tx.ua_hash=%{MATCHED_VAR}"
SecAction "id:2,phase:2,initcol:ip=%{REMOTE_ADDR}_%{tx.ua_hash}"
SecRule REQUEST_HEADERS:User-Agent "@rx .*" "id:3,phase:2,setvar:ip.auth_attempt=+1"
SecRule ARGS:foo "@rx herewego" "id:4,phase:2,setvar:ip.foo=bar,expirevar:ip.foo=2"
#SecRule ARGS:foo "@rx herewego" "id:4,phase:2,setvar:ip.foo=bar"
SecRule IP "@rx bar" "id:5,phase:2,pass"
SecRule IP:auth_attempt "@rx bar" "id:6,phase:2,pass"

View File

@ -0,0 +1,68 @@
#include <iostream>
#include <thread>
#include <array>
#include <modsecurity/modsecurity.h>
#include <modsecurity/transaction.h>
#include <modsecurity/rules_set.h>
static void process_request(modsecurity::ModSecurity *modsec, modsecurity::RulesSet *rules, int tid) {
std::cout << "Hello World! It's me, thread #" << tid << std::endl;
for(int i = 0; i != 1'000; i++) {
auto modsecTransaction = std::make_unique<modsecurity::Transaction>(modsec, rules, nullptr);
modsecTransaction->processConnection("127.0.0.1", 12345, "127.0.0.1", 80);
modsecTransaction->processURI(
"https://www.modsecurity.org/test?foo=herewego",
"GET", "1.1");
modsecTransaction->addRequestHeader("User-Agent",
"Basic ModSecurity example");
modsecTransaction->processRequestHeaders();
modsecTransaction->processRequestBody();
modsecTransaction->addResponseHeader("HTTP/1.1",
"200 OK");
modsecTransaction->processResponseHeaders(200, "HTTP 1.2");
modsecTransaction->processResponseBody();
modsecTransaction->processLogging();
std::this_thread::sleep_for(std::chrono::microseconds(100));
}
std::cout << "Thread #" << tid << " exits" << std::endl;
}
int main (int argc, char *argv[]) {
auto modsec = std::make_unique<modsecurity::ModSecurity>();
modsec->setConnectorInformation("ModSecurity-test v0.0.1-alpha (Simple " \
"example on how to use ModSecurity API");
const char main_rule_uri[] = "basic_rules.conf";
auto rules = std::make_unique<modsecurity::RulesSet>();
if (rules->loadFromUri(main_rule_uri) < 0) {
std::cerr << "Problems loading the rules..." << std::endl;
std::cerr << rules->m_parserError.str() << std::endl;
return -1;
}
constexpr auto NUM_THREADS = 100;
std::array<std::thread, NUM_THREADS> threads;
for (auto i = 0; i != threads.size(); ++i) {
threads[i] = std::thread(
[&modsec, &rules, i]() {
process_request(modsec.get(), rules.get(), i);
});
}
std::this_thread::sleep_for(std::chrono::microseconds(10000));
for (auto i = 0; i != threads.size(); ++i) {
threads[i].join();
}
return 0;
}

View File

@ -14,6 +14,7 @@ simple_request_LDADD = \
$(MAXMIND_LDADD) \
$(LUA_LDADD) \
$(PCRE_LDADD) \
$(PCRE2_LDADD) \
$(SSDEEP_LDADD) \
$(YAJL_LDADD)
@ -32,7 +33,6 @@ simple_request_LDFLAGS = \
simple_request_CPPFLAGS = \
$(GLOBAL_CFLAGS) \
-std=c++11 \
-I$(top_builddir)/headers \
-I$(top_builddir) \
-g \
@ -47,6 +47,7 @@ simple_request_CPPFLAGS = \
$(LMDB_CFLAGS) \
$(LUA_CFLAGS) \
$(PCRE_CFLAGS) \
$(PCRE2_CFLAGS) \
$(LIBXML2_CFLAGS)

View File

@ -13,13 +13,19 @@
*
*/
#include <unistd.h>
#ifndef EXAMPLES_READING_LOGS_VIA_RULE_MESSAGE_READING_LOGS_VIA_RULE_MESSAGE_H_
#define EXAMPLES_READING_LOGS_VIA_RULE_MESSAGE_READING_LOGS_VIA_RULE_MESSAGE_H_
#include <string>
#include <memory>
#include <thread>
#include <array>
#include <chrono>
#include "modsecurity/rule_message.h"
#define NUM_THREADS 100
constexpr auto NUM_THREADS = 100;
char request_header[] = "" \
@ -61,35 +67,21 @@ char response_body[] = "" \
char ip[] = "200.249.12.31";
#include "modsecurity/rule_message.h"
#ifndef EXAMPLES_READING_LOGS_VIA_RULE_MESSAGE_READING_LOGS_VIA_RULE_MESSAGE_H_
#define EXAMPLES_READING_LOGS_VIA_RULE_MESSAGE_READING_LOGS_VIA_RULE_MESSAGE_H_
static void process_request(modsecurity::ModSecurity *modsec, modsecurity::RulesSet *rules) {
for (auto z = 0; z < 10000; z++) {
auto modsecTransaction = std::make_unique<modsecurity::Transaction>(modsec, rules, nullptr);
struct data_ms {
modsecurity::ModSecurity *modsec;
modsecurity::RulesSet *rules;
};
static void *process_request(void *data) {
struct data_ms *a = (struct data_ms *)data;
modsecurity::ModSecurity *modsec = a->modsec;
modsecurity::RulesSet *rules = a->rules;
int z = 0;
for (z = 0; z < 10000; z++) {
modsecurity::Transaction *modsecTransaction = \
new modsecurity::Transaction(modsec, rules, NULL);
modsecTransaction->processConnection(ip, 12345, "127.0.0.1", 80);
modsecTransaction->processURI(request_uri, "GET", "1.1");
usleep(10);
std::this_thread::sleep_for(std::chrono::microseconds(10));
modsecTransaction->addRequestHeader("Host",
"net.tutsplus.com");
modsecTransaction->processRequestHeaders();
modsecTransaction->processRequestBody();
modsecTransaction->addResponseHeader("HTTP/1.1",
"200 OK");
modsecTransaction->processResponseHeaders(200, "HTTP 1.2");
@ -97,16 +89,11 @@ static void *process_request(void *data) {
(const unsigned char*)response_body,
strlen((const char*)response_body));
modsecTransaction->processResponseBody();
modsecTransaction->processLogging();
delete modsecTransaction;
}
pthread_exit(NULL);
return NULL;
}
class ReadingLogsViaRuleMessage {
public:
ReadingLogsViaRuleMessage(char *request_header,
@ -125,47 +112,36 @@ class ReadingLogsViaRuleMessage {
m_rules(rules)
{ }
int process() {
pthread_t threads[NUM_THREADS];
int i;
struct data_ms dms;
void *status;
modsecurity::ModSecurity *modsec;
modsecurity::RulesSet *rules;
modsec = new modsecurity::ModSecurity();
int process() const {
auto modsec = std::make_unique<modsecurity::ModSecurity>();
modsec->setConnectorInformation("ModSecurity-test v0.0.1-alpha" \
" (ModSecurity test)");
modsec->setServerLogCb(logCb, modsecurity::RuleMessageLogProperty
| modsecurity::IncludeFullHighlightLogProperty);
rules = new modsecurity::RulesSet();
auto rules = std::make_unique<modsecurity::RulesSet>();
if (rules->loadFromUri(m_rules.c_str()) < 0) {
std::cout << "Problems loading the rules..." << std::endl;
std::cout << rules->m_parserError.str() << std::endl;
return -1;
}
dms.modsec = modsec;
dms.rules = rules;
std::array<std::thread, NUM_THREADS> threads;
for (i = 0; i < NUM_THREADS; i++) {
pthread_create(&threads[i], NULL, process_request,
reinterpret_cast<void *>(&dms));
// process_request((void *)&dms);
for (auto i = 0; i != threads.size(); ++i) {
threads[i] = std::thread(
[&modsec, &rules]() {
process_request(modsec.get(), rules.get());
});
}
usleep(10000);
std::this_thread::sleep_for(std::chrono::microseconds(10000));
for (i=0; i < NUM_THREADS; i++) {
pthread_join(threads[i], &status);
for (auto i = 0; i != threads.size(); ++i) {
threads[i].join();
std::cout << "Main: completed thread id :" << i << std::endl;
}
delete rules;
delete modsec;
pthread_exit(NULL);
return 0;
}
@ -179,18 +155,18 @@ class ReadingLogsViaRuleMessage {
const modsecurity::RuleMessage *ruleMessage = \
reinterpret_cast<const modsecurity::RuleMessage *>(ruleMessagev);
std::cout << "Rule Id: " << std::to_string(ruleMessage->m_ruleId);
std::cout << " phase: " << std::to_string(ruleMessage->m_phase);
std::cout << "Rule Id: " << std::to_string(ruleMessage->m_rule.m_ruleId);
std::cout << " phase: " << std::to_string(ruleMessage->getPhase());
std::cout << std::endl;
if (ruleMessage->m_isDisruptive) {
std::cout << " * Disruptive action: ";
std::cout << modsecurity::RuleMessage::log(ruleMessage);
std::cout << modsecurity::RuleMessage::log(*ruleMessage);
std::cout << std::endl;
std::cout << " ** %d is meant to be informed by the webserver.";
std::cout << std::endl;
} else {
std::cout << " * Match, but no disruptive action: ";
std::cout << modsecurity::RuleMessage::log(ruleMessage);
std::cout << modsecurity::RuleMessage::log(*ruleMessage);
std::cout << std::endl;
}
}

View File

@ -35,8 +35,5 @@ int main(int argc, char **argv) {
response_headers, response_body, ip, rules);
rlvrm.process();
pthread_exit(NULL);
return 0;
}

View File

@ -14,6 +14,7 @@ read_LDADD = \
$(LMDB_LDADD) \
$(LUA_LDADD) \
$(PCRE_LDADD) \
$(PCRE2_LDADD) \
$(SSDEEP_LDADD) \
$(YAJL_LDADD)
@ -21,7 +22,6 @@ read_LDFLAGS = \
-L$(top_builddir)/src/.libs/ \
$(GEOIP_LDFLAGS) \
-lmodsecurity \
-lpthread \
-lm \
-lstdc++ \
$(LMDB_LDFLAGS) \
@ -32,7 +32,6 @@ read_LDFLAGS = \
read_CPPFLAGS = \
$(GLOBAL_CFLAGS) \
-std=c++11 \
-I$(top_builddir)/headers \
-I$(top_builddir) \
-g \
@ -48,6 +47,7 @@ read_CPPFLAGS = \
$(LMDB_CFLAGS) \
$(LUA_CFLAGS) \
$(PCRE_CFLAGS) \
$(PCRE2_CFLAGS) \
$(LIBXML2_CFLAGS)

View File

@ -47,7 +47,7 @@ int main (int argc, char **argv)
msc_rules_dump(rules);
ret = msc_rules_add_remote(rules, "test",
"https://www.modsecurity.org/modsecurity-regression-test-secremoterules.txt",
"https://raw.githubusercontent.com/owasp-modsecurity/ModSecurity/refs/heads/v3/master/test/modsecurity-regression-rules.txt",
&error);
if (ret < 0) {
fprintf(stderr, "Problems loading the rules --\n");
@ -68,6 +68,8 @@ int main (int argc, char **argv)
msc_process_response_body(transaction);
msc_process_logging(transaction);
end:
if(error != NULL)
msc_rules_error_cleanup(error);
msc_rules_cleanup(rules);
msc_cleanup(modsec);

View File

@ -14,6 +14,7 @@ simple_request_LDADD = \
$(LMDB_LDADD) \
$(LUA_LDADD) \
$(PCRE_LDADD) \
$(PCRE2_LDADD) \
$(SSDEEP_LDADD) \
$(YAJL_LDADD)
@ -21,19 +22,16 @@ simple_request_LDFLAGS = \
-L$(top_builddir)/src/.libs/ \
$(GEOIP_LDFLAGS) \
-lmodsecurity \
-lpthread \
-lm \
-lstdc++ \
$(MAXMIND_LDFLAGS) \
$(LMDB_LDFLAGS) \
-lpthread \
$(LUA_LDFLAGS) \
$(SSDEEP_LDFLAGS) \
$(YAJL_LDFLAGS)
simple_request_CPPFLAGS = \
$(GLOBAL_CFLAGS) \
-std=c++11 \
-I$(top_builddir)/headers \
-I$(top_builddir) \
-g \
@ -49,6 +47,7 @@ simple_request_CPPFLAGS = \
$(LMDB_CFLAGS) \
$(LUA_CFLAGS) \
$(PCRE_CFLAGS) \
$(PCRE2_CFLAGS) \
$(LIBXML2_CFLAGS)
MAINTAINERCLEANFILES = \

View File

@ -13,7 +13,11 @@
*
*/
#ifndef WIN32
#include <unistd.h>
#else
#include <io.h>
#endif
#include <stdio.h>
#include <string.h>
@ -72,18 +76,18 @@ static void logCb(void *data, const void *ruleMessagev) {
const modsecurity::RuleMessage *ruleMessage = \
reinterpret_cast<const modsecurity::RuleMessage *>(ruleMessagev);
std::cout << "Rule Id: " << std::to_string(ruleMessage->m_ruleId);
std::cout << " phase: " << std::to_string(ruleMessage->m_phase);
std::cout << "Rule Id: " << std::to_string(ruleMessage->m_rule.m_ruleId);
std::cout << " phase: " << std::to_string(ruleMessage->getPhase());
std::cout << std::endl;
if (ruleMessage->m_isDisruptive) {
std::cout << " * Disruptive action: ";
std::cout << modsecurity::RuleMessage::log(ruleMessage);
std::cout << modsecurity::RuleMessage::log(*ruleMessage);
std::cout << std::endl;
std::cout << " ** %d is meant to be informed by the webserver.";
std::cout << std::endl;
} else {
std::cout << " * Match, but no disruptive action: ";
std::cout << modsecurity::RuleMessage::log(ruleMessage);
std::cout << modsecurity::RuleMessage::log(*ruleMessage);
std::cout << std::endl;
}
}

View File

@ -13,113 +13,32 @@
*
*/
#ifdef __cplusplus
#include <string>
#include <iostream>
#include <memory>
#endif
#include "modsecurity/intervention.h"
#include "modsecurity/rule.h"
#include "modsecurity/rule_with_actions.h"
#ifndef HEADERS_MODSECURITY_ACTIONS_ACTION_H_
#define HEADERS_MODSECURITY_ACTIONS_ACTION_H_
#ifdef __cplusplus
#include <string>
#include <memory>
namespace modsecurity {
class Transaction;
class RuleWithOperator;
class RuleWithActions;
class RuleMessage;
namespace actions {
class Action {
public:
explicit Action(const std::string& _action)
: m_isNone(false),
temporaryAction(false),
action_kind(2),
m_name(nullptr),
m_parser_payload("") {
set_name_and_payload(_action);
}
explicit Action(const std::string& _action, int kind)
: m_isNone(false),
temporaryAction(false),
action_kind(kind),
m_name(nullptr),
m_parser_payload("") {
set_name_and_payload(_action);
}
Action(const Action &a)
: m_isNone(a.m_isNone),
temporaryAction(a.temporaryAction),
action_kind(a.action_kind),
m_name(a.m_name),
m_parser_payload(a.m_parser_payload) { }
Action &operator=(const Action& a) {
m_isNone = a.m_isNone;
temporaryAction = a.temporaryAction;
action_kind = a.action_kind;
m_name = a.m_name;
m_parser_payload = a.m_parser_payload;
return *this;
}
virtual ~Action() { }
virtual std::string evaluate(const std::string &exp,
Transaction *transaction);
virtual bool evaluate(RuleWithActions *rule, Transaction *transaction);
virtual bool evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> ruleMessage) {
return evaluate(rule, transaction);
}
virtual bool init(std::string *error) { return true; }
virtual bool isDisruptive() { return false; }
void set_name_and_payload(const std::string& data) {
size_t pos = data.find(":");
std::string t = "t:";
if (data.compare(0, t.length(), t) == 0) {
pos = data.find(":", 2);
}
if (pos == std::string::npos) {
m_name = std::shared_ptr<std::string>(new std::string(data));
return;
}
m_name = std::shared_ptr<std::string>(new std::string(data, 0, pos));
m_parser_payload = std::string(data, pos + 1, data.length());
if (m_parser_payload.at(0) == '\'' && m_parser_payload.size() > 2) {
m_parser_payload.erase(0, 1);
m_parser_payload.pop_back();
}
}
bool m_isNone;
bool temporaryAction;
int action_kind;
std::shared_ptr<std::string> m_name;
std::string m_parser_payload;
/**
*
* Define the action kind regarding to the execution time.
*
*
*/
enum Kind {
enum class Kind {
/**
*
* Action that are executed while loading the configuration. For instance
@ -144,6 +63,66 @@ class Action {
*/
RunTimeOnlyIfMatchKind,
};
explicit Action(const std::string& _action)
: m_isNone(false),
temporaryAction(false),
action_kind(Kind::RunTimeOnlyIfMatchKind),
m_name(nullptr),
m_parser_payload("") {
set_name_and_payload(_action);
}
explicit Action(const std::string& _action, Kind kind)
: m_isNone(false),
temporaryAction(false),
action_kind(kind),
m_name(nullptr),
m_parser_payload("") {
set_name_and_payload(_action);
}
Action(const Action &a) = delete;
Action &operator=(const Action& a) = delete;
virtual ~Action() { }
virtual bool evaluate(RuleWithActions *rule, Transaction *transaction);
virtual bool evaluate(RuleWithActions *rule, Transaction *transaction,
RuleMessage &ruleMessage) {
return evaluate(rule, transaction);
}
virtual bool init(std::string *error) { return true; }
virtual bool isDisruptive() { return false; }
void set_name_and_payload(const std::string& data) {
size_t pos = data.find(":");
const char t[] = "t:";
if (data.compare(0, std::size(t) - 1, t) == 0) {
pos = data.find(":", 2);
}
if (pos == std::string::npos) {
m_name = std::make_shared<std::string>(data);
return;
}
m_name = std::make_shared<std::string>(data, 0, pos);
m_parser_payload = std::string(data, pos + 1, data.length());
if (m_parser_payload.at(0) == '\'' && m_parser_payload.size() > 2) {
m_parser_payload.erase(0, 1);
m_parser_payload.pop_back();
}
}
bool m_isNone;
bool temporaryAction;
Kind action_kind;
std::shared_ptr<std::string> m_name;
std::string m_parser_payload;
};

View File

@ -42,16 +42,17 @@ class AnchoredSetVariableTranslationProxy {
: m_name(name),
m_fount(fount)
{
m_translate = [](std::string *name, std::vector<const VariableValue *> *l) {
m_translate = [](const std::string *name, std::vector<const VariableValue *> *l) {
for (int i = 0; i < l->size(); ++i) {
VariableValue *newVariableValue = new VariableValue(name, &l->at(i)->getKey(), &l->at(i)->getKey());
const VariableValue *oldVariableValue = l->at(i);
l->at(i) = newVariableValue;
newVariableValue->reserveOrigin(oldVariableValue->getOrigin().size());
for (const auto &oldOrigin : oldVariableValue->getOrigin()) {
std::unique_ptr<VariableOrigin> newOrigin(new VariableOrigin);
newOrigin->m_length = oldVariableValue->getKey().size();
newOrigin->m_offset = oldOrigin->m_offset - oldVariableValue->getKey().size() - 1;
newVariableValue->addOrigin(std::move(newOrigin));
newVariableValue->addOrigin(
oldVariableValue->getKey().size(),
oldOrigin.m_offset - oldVariableValue->getKey().size() - 1
);
}
delete oldVariableValue;
}
@ -99,13 +100,9 @@ class AnchoredSetVariableTranslationProxy {
return nullptr;
}
std::unique_ptr<std::string> ret(new std::string(""));
auto ret = std::make_unique<std::string>(l[0]->getValue());
ret->assign(l.at(0)->getValue());
while (!l.empty()) {
auto &a = l.back();
l.pop_back();
for(auto a : l) {
delete a;
}

View File

@ -47,23 +47,11 @@ class AnchoredVariable {
AnchoredVariable(const AnchoredVariable &a) = delete;
AnchoredVariable &operator= (const AnchoredVariable &a) = delete;
/*
: m_transaction(a.m_transaction),
m_offset(a.m_offset),
m_name(a.m_name),
m_value(a.m_value),
m_var(a.m_var) { }
*/
~AnchoredVariable();
~AnchoredVariable() = default;
void unset();
void set(const std::string &a, size_t offset);
void set(const std::string &a, size_t offset, size_t offsetLen);
void append(const std::string &a, size_t offset,
bool spaceSeparator = false);
void append(const std::string &a, size_t offset,
bool spaceSeparator, int size);
void evaluate(std::vector<const VariableValue *> *l);
std::string * evaluate();
@ -75,7 +63,7 @@ class AnchoredVariable {
std::string m_value;
private:
VariableValue *m_var;
VariableValue m_var;
};
} // namespace modsecurity

View File

@ -153,17 +153,18 @@ class AuditLog {
bool setStorageDirMode(int permission);
bool setFileMode(int permission);
bool setStatus(AuditLogStatus new_status);
bool setRelevantStatus(const std::basic_string<char>& new_relevant_status);
bool setFilePath1(const std::basic_string<char>& path);
bool setFilePath2(const std::basic_string<char>& path);
bool setStorageDir(const std::basic_string<char>& path);
bool setRelevantStatus(std::string_view new_relevant_status);
bool setFilePath1(std::string_view path);
bool setFilePath2(std::string_view path);
bool setStorageDir(std::string_view path);
bool setPrefix(std::string_view prefix);
bool setFormat(AuditLogFormat fmt);
int getDirectoryPermission() const;
int getFilePermission() const;
int getParts() const;
bool setParts(const std::basic_string<char>& new_parts);
bool setParts(std::string_view new_parts);
bool setType(AuditLogType audit_type);
bool init(std::string *error);
@ -173,8 +174,8 @@ class AuditLog {
bool saveIfRelevant(Transaction *transaction, int parts);
bool isRelevant(int status);
static int addParts(int parts, const std::string& new_parts);
static int removeParts(int parts, const std::string& new_parts);
static int addParts(int parts, std::string_view new_parts);
static int removeParts(int parts, std::string_view new_parts);
void setCtlAuditEngineActive() {
m_ctlAuditEngineActive = true;
@ -182,31 +183,32 @@ class AuditLog {
bool merge(AuditLog *from, std::string *error);
std::string m_path1;
std::string m_path2;
std::string m_storage_dir;
std::string m_path1 = std::string("");
std::string m_path2 = std::string("");
std::string m_storage_dir = std::string("");
std::string m_prefix = std::string("");
AuditLogFormat m_format;
AuditLogFormat m_format = NotSetAuditLogFormat;
protected:
int m_parts;
int m_parts = -1;
int m_defaultParts = AAuditLogPart | BAuditLogPart | CAuditLogPart
| FAuditLogPart | HAuditLogPart | ZAuditLogPart;
int m_filePermission;
int m_filePermission = -1;
int m_defaultFilePermission = 0640;
int m_directoryPermission;
int m_directoryPermission = -1;
int m_defaultDirectoryPermission = 0750;
private:
AuditLogStatus m_status;
AuditLogStatus m_status = NotSetLogStatus;
AuditLogType m_type;
std::string m_relevant;
AuditLogType m_type = NotSetAuditLogType;
std::string m_relevant = std::string("");
audit_log::writer::Writer *m_writer;
bool m_ctlAuditEngineActive; // rules have at least one action On or RelevantOnly
audit_log::writer::Writer *m_writer = nullptr;
bool m_ctlAuditEngineActive = false; // rules have at least one action On or RelevantOnly
};

View File

@ -38,10 +38,10 @@
* std::cout << "There is an intervention" << std::endl;
* }
*
* ...
* ...
*
* @endcode
*
*
*/
/**
@ -81,6 +81,11 @@
#endif
#include "modsecurity/intervention.h"
#include "modsecurity/transaction.h"
#include "modsecurity/debug_log.h"
#ifndef HEADERS_MODSECURITY_MODSECURITY_H_
#define HEADERS_MODSECURITY_MODSECURITY_H_
@ -160,7 +165,7 @@ namespace modsecurity {
LoggingPhase,
/**
* Just a marking for the expected number of phases.
*
*
*/
NUMBER_OF_PHASES,
};
@ -170,11 +175,6 @@ namespace modsecurity {
#endif
#include "modsecurity/intervention.h"
#include "modsecurity/transaction.h"
#include "modsecurity/debug_log.h"
/**
* TAG_NUM:
*
@ -190,7 +190,7 @@ namespace modsecurity {
#define MODSECURITY_MAJOR "3"
#define MODSECURITY_MINOR "0"
#define MODSECURITY_PATCHLEVEL "11"
#define MODSECURITY_PATCHLEVEL "14"
#define MODSECURITY_TAG ""
#define MODSECURITY_TAG_NUM "100"
@ -198,7 +198,7 @@ namespace modsecurity {
MODSECURITY_MINOR "." MODSECURITY_PATCHLEVEL \
MODSECURITY_TAG
#define MODSECURITY_VERSION_NUM 30110100
#define MODSECURITY_VERSION_NUM 30140100
#define MODSECURITY_CHECK_VERSION(a) (MODSECURITY_VERSION_NUM <= a)
@ -286,13 +286,13 @@ class ModSecurity {
void setServerLogCb(ModSecLogCb cb);
/**
*
* properties Properties to inform ModSecurity what kind of infornation
* properties Properties to inform ModSecurity what kind of information
* is expected be returned.
*
*/
void setServerLogCb(ModSecLogCb cb, int properties);
void serverLog(void *data, std::shared_ptr<RuleMessage> rm);
void serverLog(void *data, const RuleMessage &rm);
const std::string& getConnectorInformation() const;

View File

@ -13,15 +13,6 @@
*
*/
#ifdef __cplusplus
#include <stack>
#include <vector>
#include <string>
#include <list>
#include <memory>
#include <utility>
#endif
#ifndef HEADERS_MODSECURITY_RULE_H_
#define HEADERS_MODSECURITY_RULE_H_
@ -31,6 +22,12 @@
#ifdef __cplusplus
#include <vector>
#include <string>
#include <list>
#include <memory>
#include <utility>
namespace modsecurity {
namespace variables {
class Variable;
@ -52,7 +49,7 @@ namespace operators {
class Operator;
}
using TransformationResult = std::pair<std::shared_ptr<std::string>,
using TransformationResult = std::pair<std::string,
std::shared_ptr<std::string>>;
using TransformationResults = std::list<TransformationResult>;
@ -67,33 +64,23 @@ using MatchActions = std::vector<actions::Action *>;
class Rule {
public:
Rule(std::unique_ptr<std::string> fileName, int lineNumber)
: m_fileName(std::make_shared<std::string>(*fileName)),
Rule(const std::string &fileName, int lineNumber)
: m_fileName(fileName),
m_lineNumber(lineNumber),
m_phase(modsecurity::Phases::RequestHeadersPhase) {
}
Rule(const Rule &other) :
m_fileName(other.m_fileName),
m_lineNumber(other.m_lineNumber),
m_phase(other.m_phase)
{ }
Rule(const Rule &other) = delete;
Rule &operator=(const Rule& other) {
m_fileName = other.m_fileName;
m_lineNumber = other.m_lineNumber;
m_phase = other.m_phase;
return *this;
}
Rule &operator=(const Rule &other) = delete;
virtual ~Rule() {}
virtual bool evaluate(Transaction *transaction) = 0;
virtual bool evaluate(Transaction *transaction,
std::shared_ptr<RuleMessage> rm) = 0;
virtual bool evaluate(Transaction *transaction, RuleMessage &ruleMessage) = 0;
std::shared_ptr<std::string> getFileName() const {
const std::string& getFileName() const {
return m_fileName;
}
@ -105,18 +92,15 @@ class Rule {
void setPhase(int phase) { m_phase = phase; }
virtual std::string getReference() {
if (m_fileName) {
return *m_fileName + ":" + std::to_string(m_lineNumber);
}
return "<<no file>>:" + std::to_string(m_lineNumber);
return m_fileName + ":" + std::to_string(m_lineNumber);
}
virtual bool isMarker() { return false; }
private:
std::shared_ptr<std::string> m_fileName;
int m_lineNumber;
const std::string m_fileName;
const int m_lineNumber;
// FIXME: phase may not be neede to SecMarker.
int m_phase;
};

View File

@ -13,15 +13,6 @@
*
*/
#ifdef __cplusplus
#include <stack>
#include <vector>
#include <string>
#include <list>
#include <memory>
#include <utility>
#endif
#ifndef HEADERS_MODSECURITY_RULE_MARKER_H_
#define HEADERS_MODSECURITY_RULE_MARKER_H_
@ -32,6 +23,9 @@
#ifdef __cplusplus
#include <string>
#include <memory>
namespace modsecurity {
@ -39,48 +33,34 @@ class RuleMarker : public Rule {
public:
RuleMarker(
const std::string &name,
std::unique_ptr<std::string> fileName,
const std::string &fileName,
int lineNumber)
: Rule(std::move(fileName), lineNumber),
m_name(std::make_shared<std::string>(name)) { }
: Rule(fileName, lineNumber),
m_name(name) { }
RuleMarker(const RuleMarker& r) :
Rule(r),
m_name(r.m_name)
{ }
RuleMarker(const RuleMarker &r) = delete;
RuleMarker &operator =(const RuleMarker& r) {
Rule::operator = (r);
m_name = r.m_name;
return *this;
}
virtual bool evaluate(Transaction *transaction,
std::shared_ptr<RuleMessage> rm) override {
RuleMarker &operator=(const RuleMarker &r) = delete;
virtual bool evaluate(Transaction *transaction, RuleMessage &ruleMessage) override {
return evaluate(transaction);
}
virtual bool evaluate(Transaction *transaction) override {
if (transaction->isInsideAMarker()) {
if (*transaction->getCurrentMarker() == *m_name) {
if (transaction->isInsideAMarker() &&
*transaction->getCurrentMarker() == m_name) {
transaction->removeMarker();
// FIXME: Move this to .cc
// ms_dbg_a(transaction, 4, "Out of a SecMarker " + *m_name);
}
}
return true;
};
std::shared_ptr<std::string> getName() {
return m_name;
}
bool isMarker() override { return true; }
private:
std::shared_ptr<std::string> m_name;
const std::string m_name;
};

View File

@ -13,14 +13,6 @@
*
*/
#ifdef __cplusplus
#include <stack>
#include <vector>
#include <string>
#include <list>
#include <cstring>
#endif
#ifndef HEADERS_MODSECURITY_RULE_MESSAGE_H_
#define HEADERS_MODSECURITY_RULE_MESSAGE_H_
@ -31,8 +23,10 @@
#ifdef __cplusplus
namespace modsecurity {
#include <string>
#include <list>
namespace modsecurity {
class RuleMessage {
@ -42,168 +36,67 @@ class RuleMessage {
ClientLogMessageInfo = 4
};
/**
*
* FIXME: RuleMessage is currently too big, doing a lot of
* unnecessary data duplication. Needs to be shrink down.
*
*/
RuleMessage(RuleWithActions *rule, Transaction *trans) :
m_accuracy(rule->m_accuracy),
m_clientIpAddress(trans->m_clientIpAddress),
m_data(""),
m_id(trans->m_id),
m_isDisruptive(false),
m_match(""),
m_maturity(rule->m_maturity),
m_message(""),
m_noAuditLog(false),
m_phase(rule->getPhase() - 1),
m_reference(""),
m_rev(rule->m_rev),
RuleMessage(const RuleWithActions &rule, const Transaction &trans) :
m_rule(rule),
m_ruleFile(rule->getFileName()),
m_ruleId(rule->m_ruleId),
m_ruleLine(rule->getLineNumber()),
m_saveMessage(true),
m_serverIpAddress(trans->m_serverIpAddress),
m_severity(0),
m_uriNoQueryStringDecoded(trans->m_uri_no_query_string_decoded),
m_ver(rule->m_ver),
m_tags()
{ }
explicit RuleMessage(RuleMessage *rule) :
m_accuracy(rule->m_accuracy),
m_clientIpAddress(rule->m_clientIpAddress),
m_data(rule->m_data),
m_id(rule->m_id),
m_isDisruptive(rule->m_isDisruptive),
m_match(rule->m_match),
m_maturity(rule->m_maturity),
m_message(rule->m_message),
m_noAuditLog(rule->m_noAuditLog),
m_phase(rule->m_phase),
m_reference(rule->m_reference),
m_rev(rule->m_rev),
m_rule(rule->m_rule),
m_ruleFile(rule->m_ruleFile),
m_ruleId(rule->m_ruleId),
m_ruleLine(rule->m_ruleLine),
m_saveMessage(rule->m_saveMessage),
m_serverIpAddress(rule->m_serverIpAddress),
m_severity(rule->m_severity),
m_uriNoQueryStringDecoded(rule->m_uriNoQueryStringDecoded),
m_ver(rule->m_ver),
m_tags(rule->m_tags)
{ }
RuleMessage(const RuleMessage& ruleMessage)
: m_accuracy(ruleMessage.m_accuracy),
m_clientIpAddress(ruleMessage.m_clientIpAddress),
m_data(ruleMessage.m_data),
m_id(ruleMessage.m_id),
m_isDisruptive(ruleMessage.m_isDisruptive),
m_match(ruleMessage.m_match),
m_maturity(ruleMessage.m_maturity),
m_message(ruleMessage.m_message),
m_noAuditLog(ruleMessage.m_noAuditLog),
m_phase(ruleMessage.m_phase),
m_reference(ruleMessage.m_reference),
m_rev(ruleMessage.m_rev),
m_rule(ruleMessage.m_rule),
m_ruleFile(ruleMessage.m_ruleFile),
m_ruleId(ruleMessage.m_ruleId),
m_ruleLine(ruleMessage.m_ruleLine),
m_saveMessage(ruleMessage.m_saveMessage),
m_serverIpAddress(ruleMessage.m_serverIpAddress),
m_severity(ruleMessage.m_severity),
m_uriNoQueryStringDecoded(ruleMessage.m_uriNoQueryStringDecoded),
m_ver(ruleMessage.m_ver),
m_tags(ruleMessage.m_tags)
{ }
RuleMessage &operator=(const RuleMessage& ruleMessage) {
m_accuracy = ruleMessage.m_accuracy;
m_clientIpAddress = ruleMessage.m_clientIpAddress;
m_data = ruleMessage.m_data;
m_id = ruleMessage.m_id;
m_isDisruptive = ruleMessage.m_isDisruptive;
m_match = ruleMessage.m_match;
m_maturity = ruleMessage.m_maturity;
m_message = ruleMessage.m_message;
m_noAuditLog = ruleMessage.m_noAuditLog;
m_phase = ruleMessage.m_phase;
m_reference = ruleMessage.m_reference;
m_rev = ruleMessage.m_rev;
m_rule = ruleMessage.m_rule;
m_ruleFile = ruleMessage.m_ruleFile;
m_ruleId = ruleMessage.m_ruleId;
m_ruleLine = ruleMessage.m_ruleLine;
m_saveMessage = ruleMessage.m_saveMessage;
m_serverIpAddress = ruleMessage.m_serverIpAddress;
m_severity = ruleMessage.m_severity;
m_uriNoQueryStringDecoded = ruleMessage.m_uriNoQueryStringDecoded;
m_ver = ruleMessage.m_ver;
m_tags = ruleMessage.m_tags;
return *this;
m_transaction(trans)
{
reset(true);
}
void clean() {
m_data = "";
m_match = "";
RuleMessage(const RuleMessage &ruleMessage) = default;
RuleMessage &operator=(const RuleMessage &ruleMessage) = delete;
void reset(const bool resetSaveMessage)
{
m_data.clear();
m_isDisruptive = false;
m_reference = "";
m_match.clear();
m_message.clear();
m_noAuditLog = false;
m_reference.clear();
if (resetSaveMessage == true)
m_saveMessage = true;
m_severity = 0;
m_ver = "";
m_tags.clear();
}
std::string log() {
return log(this, 0);
std::string log() const {
return log(*this, 0);
}
std::string log(int props) {
return log(this, props);
std::string log(int props) const {
return log(*this, props);
}
std::string log(int props, int responseCode) {
return log(this, props, responseCode);
std::string log(int props, int responseCode) const {
return log(*this, props, responseCode);
}
std::string errorLog() {
return log(this,
ClientLogMessageInfo | ErrorLogTailLogMessageInfo);
std::string errorLog() const {
return log(*this,
ClientLogMessageInfo | ErrorLogTailLogMessageInfo);
}
static std::string log(const RuleMessage *rm, int props, int code);
static std::string log(const RuleMessage *rm, int props) {
static std::string log(const RuleMessage &rm, int props, int code);
static std::string log(const RuleMessage &rm, int props) {
return log(rm, props, -1);
}
static std::string log(const RuleMessage *rm) {
static std::string log(const RuleMessage &rm) {
return log(rm, 0);
}
static std::string _details(const RuleMessage *rm);
static std::string _errorLogTail(const RuleMessage *rm);
static std::string _details(const RuleMessage &rm);
static std::string _errorLogTail(const RuleMessage &rm);
int m_accuracy;
std::shared_ptr<std::string> m_clientIpAddress;
int getPhase() const { return m_rule.getPhase() - 1; }
const RuleWithActions &m_rule;
const Transaction &m_transaction;
std::string m_data;
std::shared_ptr<std::string> m_id;
bool m_isDisruptive;
bool m_isDisruptive = false;
std::string m_match;
int m_maturity;
std::string m_message;
bool m_noAuditLog;
int m_phase;
bool m_noAuditLog = false;
std::string m_reference;
std::string m_rev;
RuleWithActions *m_rule;
std::shared_ptr<std::string> m_ruleFile;
int m_ruleId;
int m_ruleLine;
bool m_saveMessage;
std::shared_ptr<std::string> m_serverIpAddress;
int m_severity;
std::shared_ptr<std::string> m_uriNoQueryStringDecoded;
std::string m_ver;
bool m_saveMessage = true;
int m_severity = 0;
std::list<std::string> m_tags;
};

View File

@ -13,15 +13,6 @@
*
*/
#ifdef __cplusplus
#include <stack>
#include <vector>
#include <string>
#include <list>
#include <memory>
#include <utility>
#endif
#ifndef HEADERS_MODSECURITY_RULE_UNCONDITIONAL_H_
#define HEADERS_MODSECURITY_RULE_UNCONDITIONAL_H_
@ -34,30 +25,18 @@
#ifdef __cplusplus
#include <vector>
#include <string>
#include <memory>
namespace modsecurity {
class RuleUnconditional : public RuleWithActions {
public:
RuleUnconditional(
std::vector<actions::Action *> *actions,
Transformations *transformations,
std::unique_ptr<std::string> fileName,
int lineNumber)
: RuleWithActions(actions, transformations, std::move(fileName), lineNumber) { }
using RuleWithActions::RuleWithActions;
RuleUnconditional(const RuleUnconditional& r)
: RuleWithActions(r)
{ }
RuleUnconditional &operator=(const RuleUnconditional& r) {
RuleWithActions::operator = (r);
return *this;
}
virtual bool evaluate(Transaction *transaction, std::shared_ptr<RuleMessage> ruleMessage) override;
private:
virtual bool evaluate(Transaction *transaction, RuleMessage &ruleMessage) override;
};

View File

@ -40,103 +40,46 @@ class RuleWithActions : public Rule {
RuleWithActions(
Actions *a,
Transformations *t,
std::unique_ptr<std::string> fileName,
const std::string &fileName,
int lineNumber);
~RuleWithActions();
~RuleWithActions() override;
RuleWithActions(const RuleWithActions& r)
: Rule(r),
m_rev(r.m_rev),
m_ver(r.m_ver),
m_accuracy(r.m_accuracy),
m_maturity(r.m_maturity),
m_ruleId(r.m_ruleId),
m_chainedRuleChild(r.m_chainedRuleChild),
m_chainedRuleParent(r.m_chainedRuleParent),
m_disruptiveAction(r.m_disruptiveAction),
m_logData(r.m_logData),
m_msg(r.m_msg),
m_severity(r.m_severity),
m_actionsRuntimePos(r.m_actionsRuntimePos),
m_actionsSetVar(r.m_actionsSetVar),
m_actionsTag(r.m_actionsTag),
m_transformations(r.m_transformations),
m_containsCaptureAction(r.m_containsCaptureAction),
m_containsMultiMatchAction(r.m_containsMultiMatchAction),
m_containsStaticBlockAction(r.m_containsStaticBlockAction),
m_isChained(r.m_isChained)
{ }
RuleWithActions(const RuleWithActions &r) = delete;
RuleWithActions &operator=(const RuleWithActions& r) {
Rule::operator = (r);
m_rev = r.m_rev;
m_ver = r.m_ver;
m_accuracy = r.m_accuracy;
m_maturity = r.m_maturity;
m_ruleId = r.m_ruleId;
m_chainedRuleChild = r.m_chainedRuleChild;
m_chainedRuleParent = r.m_chainedRuleParent;
m_disruptiveAction = r.m_disruptiveAction;
m_logData = r.m_logData;
m_msg = r.m_msg;
m_severity = r.m_severity;
m_actionsRuntimePos = r.m_actionsRuntimePos;
m_actionsSetVar = r.m_actionsSetVar;
m_actionsTag = r.m_actionsTag;
m_transformations = r.m_transformations;
m_containsCaptureAction = r.m_containsCaptureAction;
m_containsMultiMatchAction = r.m_containsMultiMatchAction;
m_containsStaticBlockAction = r.m_containsStaticBlockAction;
m_isChained = r.m_isChained;
return *this;
}
virtual bool evaluate(Transaction *transaction, std::shared_ptr<RuleMessage> ruleMessage) override;
RuleWithActions &operator=(const RuleWithActions &r) = delete;
virtual bool evaluate(Transaction *transaction) override;
virtual bool evaluate(Transaction *transaction, RuleMessage &ruleMessage) override;
void executeActionsIndependentOfChainedRuleResult(
Transaction *trasn,
bool *containsDisruptive,
std::shared_ptr<RuleMessage> ruleMessage);
RuleMessage &ruleMessage);
void executeActionsAfterFullMatch(
Transaction *trasn,
bool containsDisruptive,
std::shared_ptr<RuleMessage> ruleMessage);
RuleMessage &ruleMessage);
void executeAction(Transaction *trans,
bool containsBlock,
std::shared_ptr<RuleMessage> ruleMessage,
RuleMessage &ruleMessage,
actions::Action *a,
bool context);
void executeTransformations(
Transaction *trasn, const std::string &value, TransformationResults &ret);
inline void executeTransformation(
actions::transformations::Transformation *a,
std::shared_ptr<std::string> *value,
Transaction *trans,
TransformationResults *ret,
std::string *path,
int *nth) const;
const Transaction *trasn, const std::string &value, TransformationResults &ret);
void performLogging(Transaction *trans,
std::shared_ptr<RuleMessage> ruleMessage,
RuleMessage &ruleMessage,
bool lastLog = true,
bool chainedParentNull = false);
bool chainedParentNull = false) const;
std::vector<actions::Action *> getActionsByName(const std::string& name,
Transaction *t);
const Transaction *t);
bool containsTag(const std::string& name, Transaction *t);
bool containsMsg(const std::string& name, Transaction *t);
@ -166,6 +109,14 @@ class RuleWithActions : public Rule {
RuleWithActions *m_chainedRuleParent;
private:
inline void executeTransformation(
const actions::transformations::Transformation &a,
std::string &value,
const Transaction *trans,
TransformationResults &ret,
std::string &path,
int &nth) const;
/* actions */
actions::Action *m_disruptiveAction;
actions::LogData *m_logData;

View File

@ -42,28 +42,26 @@ class RuleWithOperator : public RuleWithActions {
variables::Variables *variables,
std::vector<actions::Action *> *actions,
Transformations *transformations,
std::unique_ptr<std::string> fileName,
const std::string &fileName,
int lineNumber);
virtual ~RuleWithOperator();
~RuleWithOperator() override;
bool evaluate(Transaction *transaction,
std::shared_ptr<RuleMessage> rm) override;
bool evaluate(Transaction *transaction, RuleMessage &ruleMessage) override;
void getVariablesExceptions(Transaction *t,
void getVariablesExceptions(Transaction &t,
variables::Variables *exclusion, variables::Variables *addition);
inline void getFinalVars(variables::Variables *vars,
variables::Variables *eclusion, Transaction *trans);
bool executeOperatorAt(Transaction *trasn, const std::string &key,
const std::string &value, std::shared_ptr<RuleMessage> rm);
const std::string &value, RuleMessage &ruleMessage);
static void updateMatchedVars(Transaction *trasn, const std::string &key,
const std::string &value);
static void cleanMatchedVars(Transaction *trasn);
std::string getOperatorName() const;
const std::string& getOperatorName() const;
virtual std::string getReference() override {
return std::to_string(m_ruleId);

View File

@ -41,16 +41,16 @@ namespace modsecurity {
class Rules {
public:
void dump() const {
for (int j = 0; j < m_rules.size(); j++) {
std::cout << " Rule ID: " << m_rules.at(j)->getReference();
std::cout << "--" << m_rules.at(j) << std::endl;
for (const auto &r : m_rules) {
std::cout << " Rule ID: " << r->getReference();
std::cout << "--" << r << std::endl;
}
}
int append(Rules *from, const std::vector<int64_t> &ids, std::ostringstream *err) {
size_t j = 0;
for (; j < from->size(); j++) {
RuleWithOperator *rule = dynamic_cast<RuleWithOperator *>(from->at(j).get());
const RuleWithOperator *rule = dynamic_cast<RuleWithOperator *>(from->at(j).get());
if (rule && std::binary_search(ids.begin(), ids.end(), rule->m_ruleId)) {
if (err != NULL) {
*err << "Rule id: " << std::to_string(rule->m_ruleId) \
@ -68,7 +68,7 @@ class Rules {
}
bool insert(std::shared_ptr<Rule> rule, const std::vector<int64_t> *ids, std::ostringstream *err) {
RuleWithOperator *r = dynamic_cast<RuleWithOperator *>(rule.get());
const RuleWithOperator *r = dynamic_cast<RuleWithOperator *>(rule.get());
if (r && ids != nullptr && std::binary_search(ids->begin(), ids->end(), r->m_ruleId)) {
if (err != nullptr) {
*err << "Rule id: " << std::to_string(r->m_ruleId) \

View File

@ -53,8 +53,8 @@ class RulesExceptions {
bool contains(int a);
bool merge(RulesExceptions *from);
bool loadRemoveRuleByMsg(const std::string &msg, std::string *error);
bool loadRemoveRuleByTag(const std::string &msg, std::string *error);
bool loadRemoveRuleByMsg(const std::string &msg, const std::string *error);
bool loadRemoveRuleByTag(const std::string &msg, const std::string *error);
bool loadUpdateTargetByMsg(const std::string &msg,
std::unique_ptr<std::vector<std::unique_ptr<variables::Variable> > > v,

View File

@ -22,6 +22,7 @@
#include <string>
#include <vector>
#include <list>
#include <cstdint>
#endif
@ -79,6 +80,8 @@ class RulesSet : public RulesSetProperties {
void debug(int level, const std::string &id, const std::string &uri,
const std::string &msg);
static void cleanMatchedVars(Transaction *trans);
RulesSetPhases m_rulesSetPhases;
private:
#ifndef NO_LOGS
@ -93,12 +96,13 @@ extern "C" {
#endif
RulesSet *msc_create_rules_set(void);
void msc_rules_dump(RulesSet *rules);
void msc_rules_dump(const RulesSet *rules);
int msc_rules_merge(RulesSet *rules_dst, RulesSet *rules_from, const char **error);
int msc_rules_add_remote(RulesSet *rules, const char *key, const char *uri,
const char **error);
int msc_rules_add_file(RulesSet *rules, const char *file, const char **error);
int msc_rules_add(RulesSet *rules, const char *plain_rules, const char **error);
void msc_rules_error_cleanup(const char *error);
int msc_rules_cleanup(RulesSet *rules);
#ifdef __cplusplus

View File

@ -13,6 +13,14 @@
*
*/
#ifdef WIN32
#ifdef max
#undef max
#endif
#ifdef min
#undef min
#endif
#endif
#ifdef __cplusplus
#include <ctime>
@ -22,6 +30,8 @@
#include <list>
#include <set>
#include <cstring>
#include <limits>
#include <cstdint>
#endif
@ -52,6 +62,11 @@
to = (from == PropertyNotSetBodyLimitAction) ? default : from; \
}
#define merge_xmlargparse_value(to, from, default) \
if (to == PropertyNotSetConfigXMLParseXmlIntoArgs) { \
to = (from == PropertyNotSetConfigXMLParseXmlIntoArgs) ? default : from; \
}
#ifdef __cplusplus
namespace modsecurity {
@ -63,48 +78,134 @@ class Driver;
using modsecurity::debug_log::DebugLog;
using modsecurity::audit_log::AuditLog;
/** @ingroup ModSecurity_CPP_API */
class ConfigInt {
public:
ConfigInt() : m_set(false), m_value(0) { }
bool m_set;
int m_value;
// template for different numeric int types
template <typename T>
class ConfigValue {
public:
bool m_set = false;
T m_value = 0;
void merge(ConfigInt *from) {
if (m_set == true || from->m_set == false) {
ConfigValue() = default;
void merge(const ConfigValue<T>* from) {
if (m_set || !from->m_set) {
return;
}
m_set = true;
m_value = from->m_value;
return;
}
// default parser
bool parse(const std::string& a, std::string* errmsg = nullptr) {
// use an alias type because the template can convert both signed and unsigned int
using LimitSigned = std::conditional_t<std::is_signed_v<T>, std::int64_t, std::uint64_t>;
LimitSigned val;
// clear errno variable, wee need that later
errno = 0;
try {
if constexpr (std::is_signed_v<T>) {
val = static_cast<std::int64_t>(std::stoll(a));
} else {
val = static_cast<std::uint64_t>(std::stoull(a));
}
}
catch (const std::invalid_argument&) {
// probably can't occur, but we handle it anyway
set_error(errmsg, "Invalid number format (not numeric)");
return false;
}
catch (const std::out_of_range&) {
// the value is out of range, we can not handle it
set_error(errmsg, "Number out of range");
return false;
}
catch (...) { // NOSONAR
// we don't need to handle all exceptions, the engine's BISON parser
// does not allow other symbols than numbers
set_error(errmsg, "An unknown error occurred while parsing number.");
return false;
}
if (
// The first condition will be true when the value is bigger than int64/uint64 maximum value.
// The second condition checks whether the value fits into int64/uint64, but not
// into the designed type, e.g., uint32; in that case the errno will be 0, but
// we must check the value is not bigger than the defined maximum of the class.
(errno == ERANGE && val == std::numeric_limits<LimitSigned>::max())
||
(val > static_cast<LimitSigned>(maxValue()))
) {
set_error(errmsg, "Value is too big.");
return false;
}
if (
// same as above
(errno == ERANGE && val == std::numeric_limits<LimitSigned>::min())
||
(val < static_cast<LimitSigned>(minValue()))
) {
set_error(errmsg, "Value is too small.");
return false;
}
m_value = static_cast<T>(val);
m_set = true;
return true;
}
protected:
// derived classes must implement the maxValue
virtual T maxValue() const = 0;
// minValue is optional
virtual T minValue() const { return 0; }
private:
static inline void set_error(std::string* err, const char* msg) {
if (err) {
*err = msg;
}
}
};
/** @ingroup ModSecurity_CPP_API */
class ConfigDouble {
public:
ConfigDouble() : m_set(false), m_value(0) { }
bool m_set;
double m_value;
class ConfigInt : public ConfigValue<int32_t> {
protected:
int32_t minValue() const override {
return std::numeric_limits<int32_t>::min();
}
int32_t maxValue() const override {
return std::numeric_limits<int32_t>::max();
}
};
void merge(ConfigDouble *from) {
if (m_set == true || from->m_set == false) {
return;
}
m_set = true;
m_value = from->m_value;
return;
class ConfigUnsignedInt : public ConfigValue<uint32_t> {
protected:
uint32_t maxValue() const override {
return std::numeric_limits<uint32_t>::max();
}
};
class ConfigUnsignedLong : public ConfigValue<uint64_t> {
protected:
uint64_t maxValue() const override {
return std::numeric_limits<uint64_t>::max();
}
};
class ConfigString {
public:
ConfigString() : m_set(false), m_value("") { }
bool m_set;
std::string m_value;
bool m_set = false;
std::string m_value = "";
ConfigString() = default;
void merge(ConfigString *from) {
void merge(const ConfigString *from) {
if (m_set == true || from->m_set == false) {
return;
}
@ -117,10 +218,10 @@ class ConfigString {
class ConfigSet {
public:
ConfigSet() : m_set(false), m_clear(false) { }
bool m_set;
bool m_clear;
bool m_set = false;
bool m_clear = false;
std::set<std::string> m_value;
ConfigSet() = default;
};
@ -150,7 +251,7 @@ class ConfigUnicodeMap {
static void loadConfig(std::string f, double codePage,
RulesSetProperties *driver, std::string *errg);
void merge(ConfigUnicodeMap *from) {
void merge(const ConfigUnicodeMap *from) {
if (from->m_set == false) {
return;
}
@ -177,6 +278,7 @@ class RulesSetProperties {
m_secRequestBodyAccess(PropertyNotSetConfigBoolean),
m_secResponseBodyAccess(PropertyNotSetConfigBoolean),
m_secXMLExternalEntity(PropertyNotSetConfigBoolean),
m_secXMLParseXmlIntoArgs(PropertyNotSetConfigXMLParseXmlIntoArgs),
m_tmpSaveUploadedFiles(PropertyNotSetConfigBoolean),
m_uploadKeepFiles(PropertyNotSetConfigBoolean),
m_debugLog(new DebugLog()),
@ -191,6 +293,7 @@ class RulesSetProperties {
m_secRequestBodyAccess(PropertyNotSetConfigBoolean),
m_secResponseBodyAccess(PropertyNotSetConfigBoolean),
m_secXMLExternalEntity(PropertyNotSetConfigBoolean),
m_secXMLParseXmlIntoArgs(PropertyNotSetConfigXMLParseXmlIntoArgs),
m_tmpSaveUploadedFiles(PropertyNotSetConfigBoolean),
m_uploadKeepFiles(PropertyNotSetConfigBoolean),
m_debugLog(debugLog),
@ -218,7 +321,8 @@ class RulesSetProperties {
/**
*
*
* The ConfigBoolean enumerator defines the states for configuration boolean values.
* The default value is PropertyNotSetConfigBoolean.
*/
enum ConfigBoolean {
TrueConfigBoolean,
@ -226,6 +330,18 @@ class RulesSetProperties {
PropertyNotSetConfigBoolean
};
/**
*
* The ConfigXMLParseXmlIntoArgs enumerator defines the states for the configuration
* XMLParseXmlIntoArgs values.
* The default value is PropertyNotSetConfigXMLParseXmlIntoArgs.
*/
enum ConfigXMLParseXmlIntoArgs {
TrueConfigXMLParseXmlIntoArgs,
FalseConfigXMLParseXmlIntoArgs,
OnlyArgsConfigXMLParseXmlIntoArgs,
PropertyNotSetConfigXMLParseXmlIntoArgs
};
/**
*
@ -311,7 +427,7 @@ class RulesSetProperties {
};
static const char *ruleEngineStateString(RuleEngine i) {
static std::string ruleEngineStateString(RuleEngine i) {
switch (i) {
case DisabledRuleEngine:
return "Disabled";
@ -322,7 +438,7 @@ class RulesSetProperties {
case PropertyNotSetRuleEngine:
return "PropertyNotSet/DetectionOnly";
}
return NULL;
return std::string{};
}
@ -333,11 +449,24 @@ class RulesSetProperties {
case FalseConfigBoolean:
return "False";
case PropertyNotSetConfigBoolean:
default:
return "Not set";
}
return NULL;
}
static std::string configXMLParseXmlIntoArgsString(ConfigXMLParseXmlIntoArgs i) {
switch (i) {
case TrueConfigXMLParseXmlIntoArgs:
return "True";
case FalseConfigXMLParseXmlIntoArgs:
return "False";
case OnlyArgsConfigXMLParseXmlIntoArgs:
return "OnlyArgs";
case PropertyNotSetConfigXMLParseXmlIntoArgs:
default:
return "Not set";
}
}
static int mergeProperties(RulesSetProperties *from,
RulesSetProperties *to, std::ostringstream *err) {
@ -357,6 +486,10 @@ class RulesSetProperties {
from->m_secXMLExternalEntity,
PropertyNotSetConfigBoolean);
merge_xmlargparse_value(to->m_secXMLParseXmlIntoArgs,
from->m_secXMLParseXmlIntoArgs,
PropertyNotSetConfigXMLParseXmlIntoArgs);
merge_boolean_value(to->m_uploadKeepFiles,
from->m_uploadKeepFiles,
PropertyNotSetConfigBoolean);
@ -464,16 +597,17 @@ class RulesSetProperties {
ConfigBoolean m_secRequestBodyAccess;
ConfigBoolean m_secResponseBodyAccess;
ConfigBoolean m_secXMLExternalEntity;
ConfigXMLParseXmlIntoArgs m_secXMLParseXmlIntoArgs;
ConfigBoolean m_tmpSaveUploadedFiles;
ConfigBoolean m_uploadKeepFiles;
ConfigDouble m_argumentsLimit;
ConfigDouble m_requestBodyJsonDepthLimit;
ConfigDouble m_requestBodyLimit;
ConfigDouble m_requestBodyNoFilesLimit;
ConfigDouble m_responseBodyLimit;
ConfigInt m_pcreMatchLimit;
ConfigInt m_uploadFileLimit;
ConfigInt m_uploadFileMode;
ConfigUnsignedInt m_argumentsLimit;
ConfigUnsignedInt m_requestBodyJsonDepthLimit;
ConfigUnsignedLong m_requestBodyLimit;
ConfigUnsignedLong m_requestBodyNoFilesLimit;
ConfigUnsignedLong m_responseBodyLimit;
ConfigUnsignedInt m_pcreMatchLimit;
ConfigUnsignedInt m_uploadFileLimit;
ConfigUnsignedInt m_uploadFileMode;
DebugLog *m_debugLog;
OnFailedRemoteRulesAction m_remoteRulesActionOnFailed;
RuleEngine m_secRuleEngine;

View File

@ -13,7 +13,11 @@
*
*/
#ifndef HEADERS_MODSECURITY_TRANSACTION_H_
#define HEADERS_MODSECURITY_TRANSACTION_H_
#ifdef __cplusplus
#include <cassert>
#include <ctime>
#include <fstream>
#include <iomanip>
@ -32,9 +36,6 @@
#include <stdlib.h>
#include <stddef.h>
#ifndef HEADERS_MODSECURITY_TRANSACTION_H_
#define HEADERS_MODSECURITY_TRANSACTION_H_
#ifndef __cplusplus
typedef struct ModSecurity_t ModSecurity;
typedef struct Transaction_t Transaction;
@ -56,7 +57,7 @@ typedef struct Rules_t RulesSet;
#define ms_dbg(b, c) \
do { \
if (m_rules && m_rules->m_debugLog && m_rules->m_debugLog->m_debugLevel >= b) { \
m_rules->debug(b, *m_id.get(), m_uri, c); \
m_rules->debug(b, m_id, m_uri, c); \
} \
} while (0);
#else
@ -79,15 +80,14 @@ typedef struct Rules_t RulesSet;
#define LOGFY_ADD(a, b) \
yajl_gen_string(g, reinterpret_cast<const unsigned char*>(a), strlen(a)); \
if (b == NULL) { \
if (b.data() == NULL) { \
yajl_gen_string(g, reinterpret_cast<const unsigned char*>(""), \
strlen("")); \
} else { \
yajl_gen_string(g, reinterpret_cast<const unsigned char*>(b), \
strlen(b)); \
yajl_gen_string(g, reinterpret_cast<const unsigned char*>(b.data()), \
b.length()); \
}
#define LOGFY_ADD_INT(a, b) \
yajl_gen_string(g, reinterpret_cast<const unsigned char*>(a), strlen(a)); \
yajl_gen_number(g, reinterpret_cast<const char*>(b), strlen(b));
@ -307,11 +307,8 @@ class TransactionSecMarkerManagement {
}
std::shared_ptr<std::string> getCurrentMarker() const {
if (m_marker) {
return m_marker;
} else {
throw;
}
assert((m_marker != nullptr) && "You might have forgotten to call and evaluate isInsideAMarker() before calling getCurrentMarker().");
return m_marker;
}
void removeMarker() {
@ -329,8 +326,8 @@ class TransactionSecMarkerManagement {
/** @ingroup ModSecurity_CPP_API */
class Transaction : public TransactionAnchoredVariables, public TransactionSecMarkerManagement {
public:
Transaction(ModSecurity *transaction, RulesSet *rules, void *logCbData);
Transaction(ModSecurity *transaction, RulesSet *rules, char *id,
Transaction(ModSecurity *ms, RulesSet *rules, void *logCbData);
Transaction(ModSecurity *ms, RulesSet *rules, const char *id,
void *logCbData);
~Transaction();
@ -393,6 +390,8 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa
int processLogging();
int updateStatusCode(int status);
int setRequestHostName(const std::string& hostname);
bool intervention(ModSecurityIntervention *it);
bool addArgument(const std::string& orig, const std::string& key,
@ -405,14 +404,14 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa
size_t getRequestBodyLength();
#ifndef NO_LOGS
void debug(int, const std::string&) const;
void debug(int, const std::string &) const;
#endif
void serverLog(std::shared_ptr<RuleMessage> rm);
void serverLog(const RuleMessage &rm);
int getRuleEngineState() const;
std::string toJSON(int parts);
std::string toOldAuditLogFormat(int parts, const std::string &trailer);
std::string toOldAuditLogFormat(int parts, const std::string &trailer, const std::string &header);
std::string toOldAuditLogFormatIndex(const std::string &filename,
double size, const std::string &md5);
@ -426,12 +425,12 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa
* need to be filled if there is no rule using the variable
* `duration'.
*/
clock_t m_creationTimeStamp;
const clock_t m_creationTimeStamp;
/**
* Holds the client IP address.
*/
std::shared_ptr<std::string> m_clientIpAddress;
std::string m_clientIpAddress;
/**
* Holds the HTTP version: 1.2, 2.0, 3.0 and so on....
@ -441,7 +440,12 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa
/**
* Holds the server IP Address
*/
std::shared_ptr<std::string> m_serverIpAddress;
std::string m_serverIpAddress;
/**
* Holds the request's hostname
*/
std::string m_requestHostName;
/**
* Holds the raw URI that was requested.
@ -451,7 +455,7 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa
/**
* Holds the URI that was requests (without the query string).
*/
std::shared_ptr<std::string> m_uri_no_query_string_decoded;
std::string m_uri_no_query_string_decoded;
/**
* Holds the combined size of all arguments, later used to fill the
@ -500,7 +504,7 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa
/**
* Rules object utilized during this specific transaction.
*/
RulesSet *m_rules;
RulesSet * const m_rules;
/**
*
@ -563,7 +567,7 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa
* Contains the unique ID of the transaction. Use by the variable
* `UNIQUE_ID'. This unique id is also saved as part of the AuditLog.
*/
std::shared_ptr<std::string> m_id;
const std::string m_id;
/**
* Holds the amount of rules that should be skipped. If bigger than 0 the
@ -595,7 +599,7 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa
* TODO: m_timeStamp and m_creationTimeStamp may be merged into a single
* variable.
*/
time_t m_timeStamp;
const time_t m_timeStamp;
/**
@ -614,6 +618,7 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa
RequestBodyProcessor::JSON *m_json;
int m_secRuleEngine;
int m_secXMLParseXmlIntoArgs;
std::string m_variableDuration;
std::map<std::string, std::string> m_variableEnvs;
@ -631,6 +636,10 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa
std::vector<std::shared_ptr<RequestBodyProcessor::MultipartPartTmpFile>> m_multipartPartTmpFiles;
private:
Transaction(ModSecurity *ms, RulesSet *rules, const char *id,
void *logCbData, const time_t timestamp);
/**
* Pointer to the callback function that will be called to fill
* the web server (connector) log.
@ -651,7 +660,7 @@ Transaction *msc_new_transaction(ModSecurity *ms,
/** @ingroup ModSecurity_C_API */
Transaction *msc_new_transaction_with_id(ModSecurity *ms,
RulesSet *rules, char *id, void *logCbData);
RulesSet *rules, const char *id, void *logCbData);
/** @ingroup ModSecurity_C_API */
int msc_process_connection(Transaction *transaction,
@ -704,7 +713,7 @@ int msc_process_uri(Transaction *transaction, const char *uri,
const char *protocol, const char *http_version);
/** @ingroup ModSecurity_C_API */
const char *msc_get_response_body(Transaction *transaction);
const char *msc_get_response_body(const Transaction *transaction);
/** @ingroup ModSecurity_C_API */
size_t msc_get_response_body_length(Transaction *transaction);
@ -718,12 +727,18 @@ void msc_transaction_cleanup(Transaction *transaction);
/** @ingroup ModSecurity_C_API */
int msc_intervention(Transaction *transaction, ModSecurityIntervention *it);
/** @ingroup ModSecurity_C_API */
void msc_intervention_cleanup(ModSecurityIntervention *it);
/** @ingroup ModSecurity_C_API */
int msc_process_logging(Transaction *transaction);
/** @ingroup ModSecurity_C_API */
int msc_update_status_code(Transaction *transaction, int status);
/** @ingroup ModSecurity_C_API */
int msc_set_request_hostname(Transaction *transaction, const unsigned char *hostname);
#ifdef __cplusplus
}
} // namespace modsecurity

View File

@ -15,6 +15,7 @@
#ifdef __cplusplus
#include <string>
#include <memory>
#endif
#ifndef HEADERS_MODSECURITY_VARIABLE_ORIGIN_H_
@ -36,14 +37,17 @@ class VariableOrigin {
VariableOrigin()
: m_length(0),
m_offset(0) { }
VariableOrigin(size_t length, size_t offset)
: m_length(length),
m_offset(offset) { }
std::string toText() {
std::string offset = std::to_string(m_offset);
std::string len = std::to_string(m_length);
std::string toText() const {
const auto offset = std::to_string(m_offset);
const auto len = std::to_string(m_length);
return "v" + offset + "," + len;
}
int m_length;
size_t m_length;
size_t m_offset;
};

View File

@ -18,7 +18,7 @@
#include <string>
#include <iostream>
#include <memory>
#include <list>
#include <vector>
#include <utility>
#endif
@ -37,7 +37,7 @@ namespace modsecurity {
class Collection;
class VariableValue {
public:
using Origins = std::list<std::unique_ptr<VariableOrigin>>;
using Origins = std::vector<VariableOrigin>;
explicit VariableValue(const std::string *key,
const std::string *value = nullptr)
@ -62,11 +62,9 @@ class VariableValue {
m_keyWithCollection(o->m_keyWithCollection),
m_value(o->m_value)
{
reserveOrigin(o->m_orign.size());
for (const auto &i : o->m_orign) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin());
origin->m_offset = i->m_offset;
origin->m_length = i->m_length;
m_orign.push_back(std::move(origin));
addOrigin(i);
}
}
@ -98,8 +96,14 @@ class VariableValue {
}
void addOrigin(std::unique_ptr<VariableOrigin> origin) {
m_orign.push_back(std::move(origin));
void addOrigin(const VariableOrigin &origin) {
m_orign.emplace_back(origin);
}
template<typename... Args>
void addOrigin(Args&&... args) {
m_orign.emplace_back(args...);
}
@ -107,6 +111,12 @@ class VariableValue {
return m_orign;
}
void reserveOrigin(Origins::size_type additionalSize) {
m_orign.reserve(m_orign.size() + additionalSize);
}
private:
Origins m_orign;
std::string m_collection;

View File

@ -156,7 +156,7 @@ SecPcreMatchLimitRecursion 1000
# MSC_PCRE_LIMITS_EXCEEDED: PCRE match limits were exceeded.
#
SecRule TX:/^MSC_/ "!@streq 0" \
"id:'200005',phase:2,t:none,deny,msg:'ModSecurity internal error flagged: %{MATCHED_VAR_NAME}'"
"id:'200005',phase:2,t:none,log,deny,msg:'ModSecurity internal error flagged: %{MATCHED_VAR_NAME}'"
# -- Response body handling --------------------------------------------------
@ -281,5 +281,7 @@ SecUnicodeMapFile unicode.mapping 20127
# The following information will be shared: ModSecurity version,
# Web Server version, APR version, PCRE version, Lua version, Libxml2
# version, Anonymous unique id for host.
SecStatusEngine On
# NB: As of April 2022, there is no longer any advantage to turning this
# setting On, as there is no active receiver for the information.
SecStatusEngine Off

View File

@ -1,28 +1,33 @@
noinst_LTLIBRARIES = libinjection.la libmbedtls.la
libinjection_la_SOURCES = \
libinjection/src/libinjection_html5.c \
libinjection/src/libinjection_sqli.c \
libinjection/src/libinjection_xss.c
libinjection_la_CFLAGS = -D LIBINJECTION_VERSION=\"${LIBINJECTION_VERSION}\"
libinjection_la_LIBADD =
noinst_HEADERS = \
libinjection/src/libinjection.h \
libinjection/src/libinjection_html5.h \
libinjection/src/libinjection_sqli.h \
libinjection/src/libinjection_sqli_data.h \
libinjection/src/libinjection_xss.h \
mbedtls/base64.h \
mbedtls/check_config.h \
mbedtls/mbed-tls-config.h \
mbedtls/md5.h \
mbedtls/platform.h \
mbedtls/sha1.h
mbedtls/include/mbedtls/base64.h \
mbedtls/include/mbedtls/check_config.h \
mbedtls/include/mbedtls/mbedtls_config.h \
mbedtls/include/mbedtls/md5.h \
mbedtls/include/mbedtls/platform.h \
mbedtls/include/mbedtls/sha1.h
libmbedtls_la_SOURCES = \
mbedtls/base64.c \
mbedtls/md5.c \
mbedtls/sha1.c
mbedtls/library/base64.c \
mbedtls/library/md5.c \
mbedtls/library/sha1.c \
mbedtls/library/platform_util.c
libmbedtls_la_CFLAGS = -D MBEDTLS_CONFIG_FILE=\"mbed-tls-config.h\" -Iothers
libmbedtls_la_CFLAGS = -DMBEDTLS_CONFIG_FILE=\"mbedtls/mbedtls_config.h\" -I$(top_srcdir)/others/mbedtls/include
libmbedtls_la_CPPFLAGS =
libmbedtls_la_LIBADD =

@ -1 +1 @@
Subproject commit bfba51f5af8f1f6cf5d6c4bf862f1e2474e018e3
Subproject commit b9fcaaf9e50e9492807b23ffcc6af46ee1f203b9

1
others/mbedtls Submodule

@ -0,0 +1 @@
Subproject commit 2ca6c285a0dd3f33982dd57299012dacab1ff206

View File

@ -1,289 +0,0 @@
/*
* RFC 1521 base64 encoding/decoding
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_BASE64_C)
#include "mbedtls/base64.h"
#include <stdint.h>
#if defined(MBEDTLS_SELF_TEST)
#include <string.h>
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdio.h>
#define mbedtls_printf printf
#endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */
static const unsigned char base64_enc_map[64] =
{
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', '+', '/'
};
static const unsigned char base64_dec_map[128] =
{
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 62, 127, 127, 127, 63, 52, 53,
54, 55, 56, 57, 58, 59, 60, 61, 127, 127,
127, 64, 127, 127, 127, 0, 1, 2, 3, 4,
5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 127, 127, 127, 127, 127, 127, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, 127, 127, 127, 127, 127
};
#define BASE64_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
/*
* Encode a buffer into base64 format
*/
int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
const unsigned char *src, size_t slen )
{
size_t i, n;
int C1, C2, C3;
unsigned char *p;
if( slen == 0 )
{
*olen = 0;
return( 0 );
}
n = slen / 3 + ( slen % 3 != 0 );
if( n > ( BASE64_SIZE_T_MAX - 1 ) / 4 )
{
*olen = BASE64_SIZE_T_MAX;
return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
}
n *= 4;
if( dlen < n + 1 )
{
*olen = n + 1;
return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
}
n = ( slen / 3 ) * 3;
for( i = 0, p = dst; i < n; i += 3 )
{
C1 = *src++;
C2 = *src++;
C3 = *src++;
*p++ = base64_enc_map[(C1 >> 2) & 0x3F];
*p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
*p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F];
*p++ = base64_enc_map[C3 & 0x3F];
}
if( i < slen )
{
C1 = *src++;
C2 = ( ( i + 1 ) < slen ) ? *src++ : 0;
*p++ = base64_enc_map[(C1 >> 2) & 0x3F];
*p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
if( ( i + 1 ) < slen )
*p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F];
else *p++ = '=';
*p++ = '=';
}
*olen = p - dst;
*p = 0;
return( 0 );
}
/*
* Decode a base64-formatted buffer
*/
int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
const unsigned char *src, size_t slen )
{
size_t i, n;
uint32_t j, x;
unsigned char *p;
/* First pass: check for validity and get output length */
for( i = n = j = 0; i < slen; i++ )
{
/* Skip spaces before checking for EOL */
x = 0;
while( i < slen && src[i] == ' ' )
{
++i;
++x;
}
/* Spaces at end of buffer are OK */
if( i == slen )
break;
if( ( slen - i ) >= 2 &&
src[i] == '\r' && src[i + 1] == '\n' )
continue;
if( src[i] == '\n' )
continue;
/* Space inside a line is an error */
if( x != 0 )
return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
if( src[i] == '=' && ++j > 2 )
return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
if( src[i] > 127 || base64_dec_map[src[i]] == 127 )
return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
if( base64_dec_map[src[i]] < 64 && j != 0 )
return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
n++;
}
if( n == 0 )
{
*olen = 0;
return( 0 );
}
n = ( ( n * 6 ) + 7 ) >> 3;
n -= j;
if( dst == NULL || dlen < n )
{
*olen = n;
return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
}
for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
{
if( *src == '\r' || *src == '\n' || *src == ' ' )
continue;
j -= ( base64_dec_map[*src] == 64 );
x = ( x << 6 ) | ( base64_dec_map[*src] & 0x3F );
if( ++n == 4 )
{
n = 0;
if( j > 0 ) *p++ = (unsigned char)( x >> 16 );
if( j > 1 ) *p++ = (unsigned char)( x >> 8 );
if( j > 2 ) *p++ = (unsigned char)( x );
}
}
*olen = p - dst;
return( 0 );
}
#if defined(MBEDTLS_SELF_TEST)
static const unsigned char base64_test_dec[64] =
{
0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,
0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,
0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,
0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13,
0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31,
0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38,
0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B,
0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97
};
static const unsigned char base64_test_enc[] =
"JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK"
"swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw==";
/*
* Checkup routine
*/
int mbedtls_base64_self_test( int verbose )
{
size_t len;
const unsigned char *src;
unsigned char buffer[128];
if( verbose != 0 )
mbedtls_printf( " Base64 encoding test: " );
src = base64_test_dec;
if( mbedtls_base64_encode( buffer, sizeof( buffer ), &len, src, 64 ) != 0 ||
memcmp( base64_test_enc, buffer, 88 ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
mbedtls_printf( "passed\n Base64 decoding test: " );
src = base64_test_enc;
if( mbedtls_base64_decode( buffer, sizeof( buffer ), &len, src, 88 ) != 0 ||
memcmp( base64_test_dec, buffer, 64 ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
mbedtls_printf( "passed\n\n" );
return( 0 );
}
#endif /* MBEDTLS_SELF_TEST */
#endif /* MBEDTLS_BASE64_C */

View File

@ -1,88 +0,0 @@
/**
* \file base64.h
*
* \brief RFC 1521 base64 encoding/decoding
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_BASE64_H
#define MBEDTLS_BASE64_H
#include <stddef.h>
#define MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL -0x002A /**< Output buffer too small. */
#define MBEDTLS_ERR_BASE64_INVALID_CHARACTER -0x002C /**< Invalid character in input. */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Encode a buffer into base64 format
*
* \param dst destination buffer
* \param dlen size of the destination buffer
* \param olen number of bytes written
* \param src source buffer
* \param slen amount of data to be encoded
*
* \return 0 if successful, or MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL.
* *olen is always updated to reflect the amount
* of data that has (or would have) been written.
* If that length cannot be represented, then no data is
* written to the buffer and *olen is set to the maximum
* length representable as a size_t.
*
* \note Call this function with dlen = 0 to obtain the
* required buffer size in *olen
*/
int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
const unsigned char *src, size_t slen );
/**
* \brief Decode a base64-formatted buffer
*
* \param dst destination buffer (can be NULL for checking size)
* \param dlen size of the destination buffer
* \param olen number of bytes written
* \param src source buffer
* \param slen amount of data to be decoded
*
* \return 0 if successful, MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL, or
* MBEDTLS_ERR_BASE64_INVALID_CHARACTER if the input data is
* not correct. *olen is always updated to reflect the amount
* of data that has (or would have) been written.
*
* \note Call this function with *dst = NULL or dlen = 0 to obtain
* the required buffer size in *olen
*/
int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
const unsigned char *src, size_t slen );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int mbedtls_base64_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* base64.h */

View File

@ -1,540 +0,0 @@
/**
* \file check_config.h
*
* \brief Consistency checks for configuration options
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* It is recommended to include this file from your config.h
* in order to catch dependency issues early.
*/
#ifndef MBEDTLS_CHECK_CONFIG_H
#define MBEDTLS_CHECK_CONFIG_H
/*
* We assume CHAR_BIT is 8 in many places. In practice, this is true on our
* target platforms, so not an issue, but let's just be extra sure.
*/
#include <limits.h>
#if CHAR_BIT != 8
#error "mbed TLS requires a platform with 8-bit chars"
#endif
#if defined(_WIN32)
#if !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_C is required on Windows"
#endif
/* Fix the config here. Not convenient to put an #ifdef _WIN32 in config.h as
* it would confuse config.pl. */
#if !defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && \
!defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO)
#define MBEDTLS_PLATFORM_SNPRINTF_ALT
#endif
#endif /* _WIN32 */
#if defined(TARGET_LIKE_MBED) && \
( defined(MBEDTLS_NET_C) || defined(MBEDTLS_TIMING_C) )
#error "The NET and TIMING modules are not available for mbed OS - please use the network and timing functions provided by mbed OS"
#endif
#if defined(MBEDTLS_DEPRECATED_WARNING) && \
!defined(__GNUC__) && !defined(__clang__)
#error "MBEDTLS_DEPRECATED_WARNING only works with GCC and Clang"
#endif
#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_HAVE_TIME)
#error "MBEDTLS_HAVE_TIME_DATE without MBEDTLS_HAVE_TIME does not make sense"
#endif
#if defined(MBEDTLS_AESNI_C) && !defined(MBEDTLS_HAVE_ASM)
#error "MBEDTLS_AESNI_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_CTR_DRBG_C) && !defined(MBEDTLS_AES_C)
#error "MBEDTLS_CTR_DRBG_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_DHM_C) && !defined(MBEDTLS_BIGNUM_C)
#error "MBEDTLS_DHM_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECDH_C) && !defined(MBEDTLS_ECP_C)
#error "MBEDTLS_ECDH_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECDSA_C) && \
( !defined(MBEDTLS_ECP_C) || \
!defined(MBEDTLS_ASN1_PARSE_C) || \
!defined(MBEDTLS_ASN1_WRITE_C) )
#error "MBEDTLS_ECDSA_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECJPAKE_C) && \
( !defined(MBEDTLS_ECP_C) || !defined(MBEDTLS_MD_C) )
#error "MBEDTLS_ECJPAKE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECDSA_DETERMINISTIC) && !defined(MBEDTLS_HMAC_DRBG_C)
#error "MBEDTLS_ECDSA_DETERMINISTIC defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECP_C) && ( !defined(MBEDTLS_BIGNUM_C) || ( \
!defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) ) )
#error "MBEDTLS_ECP_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ENTROPY_C) && (!defined(MBEDTLS_SHA512_C) && \
!defined(MBEDTLS_SHA256_C))
#error "MBEDTLS_ENTROPY_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ENTROPY_C) && defined(MBEDTLS_SHA512_C) && \
defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) && (MBEDTLS_CTR_DRBG_ENTROPY_LEN > 64)
#error "MBEDTLS_CTR_DRBG_ENTROPY_LEN value too high"
#endif
#if defined(MBEDTLS_ENTROPY_C) && \
( !defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_ENTROPY_FORCE_SHA256) ) \
&& defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) && (MBEDTLS_CTR_DRBG_ENTROPY_LEN > 32)
#error "MBEDTLS_CTR_DRBG_ENTROPY_LEN value too high"
#endif
#if defined(MBEDTLS_ENTROPY_C) && \
defined(MBEDTLS_ENTROPY_FORCE_SHA256) && !defined(MBEDTLS_SHA256_C)
#error "MBEDTLS_ENTROPY_FORCE_SHA256 defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_GCM_C) && ( \
!defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) )
#error "MBEDTLS_GCM_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_HAVEGE_C) && !defined(MBEDTLS_TIMING_C)
#error "MBEDTLS_HAVEGE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_HMAC_DRBG_C) && !defined(MBEDTLS_MD_C)
#error "MBEDTLS_HMAC_DRBG_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) && \
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) )
#error "MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) )
#error "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) && !defined(MBEDTLS_DHM_C)
#error "MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) && \
!defined(MBEDTLS_ECDH_C)
#error "MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
( !defined(MBEDTLS_DHM_C) || !defined(MBEDTLS_RSA_C) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) )
#error "MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_RSA_C) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) )
#error "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_ECDSA_C) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) )
#error "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) && \
( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \
!defined(MBEDTLS_PKCS1_V15) )
#error "MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \
!defined(MBEDTLS_PKCS1_V15) )
#error "MBEDTLS_KEY_EXCHANGE_RSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \
( !defined(MBEDTLS_ECJPAKE_C) || !defined(MBEDTLS_SHA256_C) || \
!defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) )
#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \
( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) )
#error "MBEDTLS_MEMORY_BUFFER_ALLOC_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PADLOCK_C) && !defined(MBEDTLS_HAVE_ASM)
#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PEM_PARSE_C) && !defined(MBEDTLS_BASE64_C)
#error "MBEDTLS_PEM_PARSE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PEM_WRITE_C) && !defined(MBEDTLS_BASE64_C)
#error "MBEDTLS_PEM_WRITE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PK_C) && \
( !defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_ECP_C) )
#error "MBEDTLS_PK_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_PK_C)
#error "MBEDTLS_PK_PARSE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PK_WRITE_C) && !defined(MBEDTLS_PK_C)
#error "MBEDTLS_PK_WRITE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PKCS11_C) && !defined(MBEDTLS_PK_C)
#error "MBEDTLS_PKCS11_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_EXIT_ALT) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_EXIT_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_EXIT_MACRO defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) &&\
( defined(MBEDTLS_PLATFORM_STD_EXIT) ||\
defined(MBEDTLS_PLATFORM_EXIT_ALT) )
#error "MBEDTLS_PLATFORM_EXIT_MACRO and MBEDTLS_PLATFORM_STD_EXIT/MBEDTLS_PLATFORM_EXIT_ALT cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_FPRINTF_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_FPRINTF_MACRO defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) &&\
( defined(MBEDTLS_PLATFORM_STD_FPRINTF) ||\
defined(MBEDTLS_PLATFORM_FPRINTF_ALT) )
#error "MBEDTLS_PLATFORM_FPRINTF_MACRO and MBEDTLS_PLATFORM_STD_FPRINTF/MBEDTLS_PLATFORM_FPRINTF_ALT cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_PLATFORM_FREE_MACRO) &&\
( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) )
#error "MBEDTLS_PLATFORM_FREE_MACRO defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_FREE_MACRO) &&\
defined(MBEDTLS_PLATFORM_STD_FREE)
#error "MBEDTLS_PLATFORM_FREE_MACRO and MBEDTLS_PLATFORM_STD_FREE cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && !defined(MBEDTLS_PLATFORM_CALLOC_MACRO)
#error "MBEDTLS_PLATFORM_CALLOC_MACRO must be defined if MBEDTLS_PLATFORM_FREE_MACRO is"
#endif
#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&\
( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) )
#error "MBEDTLS_PLATFORM_CALLOC_MACRO defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&\
defined(MBEDTLS_PLATFORM_STD_CALLOC)
#error "MBEDTLS_PLATFORM_CALLOC_MACRO and MBEDTLS_PLATFORM_STD_CALLOC cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && !defined(MBEDTLS_PLATFORM_FREE_MACRO)
#error "MBEDTLS_PLATFORM_FREE_MACRO must be defined if MBEDTLS_PLATFORM_CALLOC_MACRO is"
#endif
#if defined(MBEDTLS_PLATFORM_MEMORY) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_MEMORY defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_PRINTF_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_PRINTF_MACRO defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) &&\
( defined(MBEDTLS_PLATFORM_STD_PRINTF) ||\
defined(MBEDTLS_PLATFORM_PRINTF_ALT) )
#error "MBEDTLS_PLATFORM_PRINTF_MACRO and MBEDTLS_PLATFORM_STD_PRINTF/MBEDTLS_PLATFORM_PRINTF_ALT cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_SNPRINTF_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_SNPRINTF_MACRO defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) &&\
( defined(MBEDTLS_PLATFORM_STD_SNPRINTF) ||\
defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) )
#error "MBEDTLS_PLATFORM_SNPRINTF_MACRO and MBEDTLS_PLATFORM_STD_SNPRINTF/MBEDTLS_PLATFORM_SNPRINTF_ALT cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_PLATFORM_STD_MEM_HDR) &&\
!defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS)
#error "MBEDTLS_PLATFORM_STD_MEM_HDR defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_CALLOC) && !defined(MBEDTLS_PLATFORM_MEMORY)
#error "MBEDTLS_PLATFORM_STD_CALLOC defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_CALLOC) && !defined(MBEDTLS_PLATFORM_MEMORY)
#error "MBEDTLS_PLATFORM_STD_CALLOC defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_FREE) && !defined(MBEDTLS_PLATFORM_MEMORY)
#error "MBEDTLS_PLATFORM_STD_FREE defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_EXIT) &&\
!defined(MBEDTLS_PLATFORM_EXIT_ALT)
#error "MBEDTLS_PLATFORM_STD_EXIT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_FPRINTF) &&\
!defined(MBEDTLS_PLATFORM_FPRINTF_ALT)
#error "MBEDTLS_PLATFORM_STD_FPRINTF defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_PRINTF) &&\
!defined(MBEDTLS_PLATFORM_PRINTF_ALT)
#error "MBEDTLS_PLATFORM_STD_PRINTF defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_SNPRINTF) &&\
!defined(MBEDTLS_PLATFORM_SNPRINTF_ALT)
#error "MBEDTLS_PLATFORM_STD_SNPRINTF defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_BIGNUM_C) || \
!defined(MBEDTLS_OID_C) )
#error "MBEDTLS_RSA_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && \
( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_PKCS1_V21) )
#error "MBEDTLS_X509_RSASSA_PSS_SUPPORT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_PROTO_SSL3) && ( !defined(MBEDTLS_MD5_C) || \
!defined(MBEDTLS_SHA1_C) )
#error "MBEDTLS_SSL_PROTO_SSL3 defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1) && ( !defined(MBEDTLS_MD5_C) || \
!defined(MBEDTLS_SHA1_C) )
#error "MBEDTLS_SSL_PROTO_TLS1 defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_1) && ( !defined(MBEDTLS_MD5_C) || \
!defined(MBEDTLS_SHA1_C) )
#error "MBEDTLS_SSL_PROTO_TLS1_1 defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && ( !defined(MBEDTLS_SHA1_C) && \
!defined(MBEDTLS_SHA256_C) && !defined(MBEDTLS_SHA512_C) )
#error "MBEDTLS_SSL_PROTO_TLS1_2 defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_PROTO_DTLS) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_2)
#error "MBEDTLS_SSL_PROTO_DTLS defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_CLI_C) && !defined(MBEDTLS_SSL_TLS_C)
#error "MBEDTLS_SSL_CLI_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_TLS_C) && ( !defined(MBEDTLS_CIPHER_C) || \
!defined(MBEDTLS_MD_C) )
#error "MBEDTLS_SSL_TLS_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_SRV_C) && !defined(MBEDTLS_SSL_TLS_C)
#error "MBEDTLS_SSL_SRV_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_TLS_C) && (!defined(MBEDTLS_SSL_PROTO_SSL3) && \
!defined(MBEDTLS_SSL_PROTO_TLS1) && !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_2))
#error "MBEDTLS_SSL_TLS_C defined, but no protocols are active"
#endif
#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_SSL3) && \
defined(MBEDTLS_SSL_PROTO_TLS1_1) && !defined(MBEDTLS_SSL_PROTO_TLS1))
#error "Illegal protocol selection"
#endif
#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_TLS1) && \
defined(MBEDTLS_SSL_PROTO_TLS1_2) && !defined(MBEDTLS_SSL_PROTO_TLS1_1))
#error "Illegal protocol selection"
#endif
#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_SSL3) && \
defined(MBEDTLS_SSL_PROTO_TLS1_2) && (!defined(MBEDTLS_SSL_PROTO_TLS1) || \
!defined(MBEDTLS_SSL_PROTO_TLS1_1)))
#error "Illegal protocol selection"
#endif
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && !defined(MBEDTLS_SSL_PROTO_DTLS)
#error "MBEDTLS_SSL_DTLS_HELLO_VERIFY defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && \
!defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
#error "MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) && \
( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) )
#error "MBEDTLS_SSL_DTLS_ANTI_REPLAY defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) && \
( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) )
#error "MBEDTLS_SSL_DTLS_BADMAC_LIMIT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) && \
!defined(MBEDTLS_SSL_PROTO_TLS1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_2)
#error "MBEDTLS_SSL_ENCRYPT_THEN_MAC defined, but not all prerequsites"
#endif
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) && \
!defined(MBEDTLS_SSL_PROTO_TLS1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_2)
#error "MBEDTLS_SSL_EXTENDED_MASTER_SECRET defined, but not all prerequsites"
#endif
#if defined(MBEDTLS_SSL_TICKET_C) && !defined(MBEDTLS_CIPHER_C)
#error "MBEDTLS_SSL_TICKET_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) && \
!defined(MBEDTLS_SSL_PROTO_SSL3) && !defined(MBEDTLS_SSL_PROTO_TLS1)
#error "MBEDTLS_SSL_CBC_RECORD_SPLITTING defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) && \
!defined(MBEDTLS_X509_CRT_PARSE_C)
#error "MBEDTLS_SSL_SERVER_NAME_INDICATION defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_THREADING_PTHREAD)
#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL)
#error "MBEDTLS_THREADING_PTHREAD defined, but not all prerequisites"
#endif
#define MBEDTLS_THREADING_IMPL
#endif
#if defined(MBEDTLS_THREADING_ALT)
#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL)
#error "MBEDTLS_THREADING_ALT defined, but not all prerequisites"
#endif
#define MBEDTLS_THREADING_IMPL
#endif
#if defined(MBEDTLS_THREADING_C) && !defined(MBEDTLS_THREADING_IMPL)
#error "MBEDTLS_THREADING_C defined, single threading implementation required"
#endif
#undef MBEDTLS_THREADING_IMPL
#if defined(MBEDTLS_VERSION_FEATURES) && !defined(MBEDTLS_VERSION_C)
#error "MBEDTLS_VERSION_FEATURES defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_USE_C) && ( !defined(MBEDTLS_BIGNUM_C) || \
!defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_PARSE_C) || \
!defined(MBEDTLS_PK_PARSE_C) )
#error "MBEDTLS_X509_USE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_CREATE_C) && ( !defined(MBEDTLS_BIGNUM_C) || \
!defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_WRITE_C) || \
!defined(MBEDTLS_PK_WRITE_C) )
#error "MBEDTLS_X509_CREATE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_CRT_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) )
#error "MBEDTLS_X509_CRT_PARSE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_CRL_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) )
#error "MBEDTLS_X509_CRL_PARSE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_CSR_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) )
#error "MBEDTLS_X509_CSR_PARSE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_CRT_WRITE_C) && ( !defined(MBEDTLS_X509_CREATE_C) )
#error "MBEDTLS_X509_CRT_WRITE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_CSR_WRITE_C) && ( !defined(MBEDTLS_X509_CREATE_C) )
#error "MBEDTLS_X509_CSR_WRITE_C defined, but not all prerequisites"
#endif
/*
* Avoid warning from -pedantic. This is a convenient place for this
* workaround since this is included by every single file before the
* #if defined(MBEDTLS_xxx_C) that results in emtpy translation units.
*/
typedef int mbedtls_iso_c_forbids_empty_translation_units;
#endif /* MBEDTLS_CHECK_CONFIG_H */

File diff suppressed because it is too large Load Diff

View File

@ -1,404 +0,0 @@
/*
* RFC 1321 compliant MD5 implementation
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* The MD5 algorithm was designed by Ron Rivest in 1991.
*
* http://www.ietf.org/rfc/rfc1321.txt
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_MD5_C)
#include "mbedtls/md5.h"
#include <string.h>
#if defined(MBEDTLS_SELF_TEST)
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdio.h>
#define mbedtls_printf printf
#endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */
#if !defined(MBEDTLS_MD5_ALT)
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
/*
* 32-bit integer manipulation macros (little endian)
*/
#ifndef GET_UINT32_LE
#define GET_UINT32_LE(n,b,i) \
{ \
(n) = ( (uint32_t) (b)[(i) ] ) \
| ( (uint32_t) (b)[(i) + 1] << 8 ) \
| ( (uint32_t) (b)[(i) + 2] << 16 ) \
| ( (uint32_t) (b)[(i) + 3] << 24 ); \
}
#endif
#ifndef PUT_UINT32_LE
#define PUT_UINT32_LE(n,b,i) \
{ \
(b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
(b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
(b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
(b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
}
#endif
void mbedtls_md5_init( mbedtls_md5_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_md5_context ) );
}
void mbedtls_md5_free( mbedtls_md5_context *ctx )
{
if( ctx == NULL )
return;
mbedtls_zeroize( ctx, sizeof( mbedtls_md5_context ) );
}
void mbedtls_md5_clone( mbedtls_md5_context *dst,
const mbedtls_md5_context *src )
{
*dst = *src;
}
/*
* MD5 context setup
*/
void mbedtls_md5_starts( mbedtls_md5_context *ctx )
{
ctx->total[0] = 0;
ctx->total[1] = 0;
ctx->state[0] = 0x67452301;
ctx->state[1] = 0xEFCDAB89;
ctx->state[2] = 0x98BADCFE;
ctx->state[3] = 0x10325476;
}
#if !defined(MBEDTLS_MD5_PROCESS_ALT)
void mbedtls_md5_process( mbedtls_md5_context *ctx, const unsigned char data[64] )
{
uint32_t X[16], A, B, C, D;
GET_UINT32_LE( X[ 0], data, 0 );
GET_UINT32_LE( X[ 1], data, 4 );
GET_UINT32_LE( X[ 2], data, 8 );
GET_UINT32_LE( X[ 3], data, 12 );
GET_UINT32_LE( X[ 4], data, 16 );
GET_UINT32_LE( X[ 5], data, 20 );
GET_UINT32_LE( X[ 6], data, 24 );
GET_UINT32_LE( X[ 7], data, 28 );
GET_UINT32_LE( X[ 8], data, 32 );
GET_UINT32_LE( X[ 9], data, 36 );
GET_UINT32_LE( X[10], data, 40 );
GET_UINT32_LE( X[11], data, 44 );
GET_UINT32_LE( X[12], data, 48 );
GET_UINT32_LE( X[13], data, 52 );
GET_UINT32_LE( X[14], data, 56 );
GET_UINT32_LE( X[15], data, 60 );
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
#define P(a,b,c,d,k,s,t) \
{ \
a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
}
A = ctx->state[0];
B = ctx->state[1];
C = ctx->state[2];
D = ctx->state[3];
#define F(x,y,z) (z ^ (x & (y ^ z)))
P( A, B, C, D, 0, 7, 0xD76AA478 );
P( D, A, B, C, 1, 12, 0xE8C7B756 );
P( C, D, A, B, 2, 17, 0x242070DB );
P( B, C, D, A, 3, 22, 0xC1BDCEEE );
P( A, B, C, D, 4, 7, 0xF57C0FAF );
P( D, A, B, C, 5, 12, 0x4787C62A );
P( C, D, A, B, 6, 17, 0xA8304613 );
P( B, C, D, A, 7, 22, 0xFD469501 );
P( A, B, C, D, 8, 7, 0x698098D8 );
P( D, A, B, C, 9, 12, 0x8B44F7AF );
P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
P( B, C, D, A, 11, 22, 0x895CD7BE );
P( A, B, C, D, 12, 7, 0x6B901122 );
P( D, A, B, C, 13, 12, 0xFD987193 );
P( C, D, A, B, 14, 17, 0xA679438E );
P( B, C, D, A, 15, 22, 0x49B40821 );
#undef F
#define F(x,y,z) (y ^ (z & (x ^ y)))
P( A, B, C, D, 1, 5, 0xF61E2562 );
P( D, A, B, C, 6, 9, 0xC040B340 );
P( C, D, A, B, 11, 14, 0x265E5A51 );
P( B, C, D, A, 0, 20, 0xE9B6C7AA );
P( A, B, C, D, 5, 5, 0xD62F105D );
P( D, A, B, C, 10, 9, 0x02441453 );
P( C, D, A, B, 15, 14, 0xD8A1E681 );
P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
P( A, B, C, D, 9, 5, 0x21E1CDE6 );
P( D, A, B, C, 14, 9, 0xC33707D6 );
P( C, D, A, B, 3, 14, 0xF4D50D87 );
P( B, C, D, A, 8, 20, 0x455A14ED );
P( A, B, C, D, 13, 5, 0xA9E3E905 );
P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
P( C, D, A, B, 7, 14, 0x676F02D9 );
P( B, C, D, A, 12, 20, 0x8D2A4C8A );
#undef F
#define F(x,y,z) (x ^ y ^ z)
P( A, B, C, D, 5, 4, 0xFFFA3942 );
P( D, A, B, C, 8, 11, 0x8771F681 );
P( C, D, A, B, 11, 16, 0x6D9D6122 );
P( B, C, D, A, 14, 23, 0xFDE5380C );
P( A, B, C, D, 1, 4, 0xA4BEEA44 );
P( D, A, B, C, 4, 11, 0x4BDECFA9 );
P( C, D, A, B, 7, 16, 0xF6BB4B60 );
P( B, C, D, A, 10, 23, 0xBEBFBC70 );
P( A, B, C, D, 13, 4, 0x289B7EC6 );
P( D, A, B, C, 0, 11, 0xEAA127FA );
P( C, D, A, B, 3, 16, 0xD4EF3085 );
P( B, C, D, A, 6, 23, 0x04881D05 );
P( A, B, C, D, 9, 4, 0xD9D4D039 );
P( D, A, B, C, 12, 11, 0xE6DB99E5 );
P( C, D, A, B, 15, 16, 0x1FA27CF8 );
P( B, C, D, A, 2, 23, 0xC4AC5665 );
#undef F
#define F(x,y,z) (y ^ (x | ~z))
P( A, B, C, D, 0, 6, 0xF4292244 );
P( D, A, B, C, 7, 10, 0x432AFF97 );
P( C, D, A, B, 14, 15, 0xAB9423A7 );
P( B, C, D, A, 5, 21, 0xFC93A039 );
P( A, B, C, D, 12, 6, 0x655B59C3 );
P( D, A, B, C, 3, 10, 0x8F0CCC92 );
P( C, D, A, B, 10, 15, 0xFFEFF47D );
P( B, C, D, A, 1, 21, 0x85845DD1 );
P( A, B, C, D, 8, 6, 0x6FA87E4F );
P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
P( C, D, A, B, 6, 15, 0xA3014314 );
P( B, C, D, A, 13, 21, 0x4E0811A1 );
P( A, B, C, D, 4, 6, 0xF7537E82 );
P( D, A, B, C, 11, 10, 0xBD3AF235 );
P( C, D, A, B, 2, 15, 0x2AD7D2BB );
P( B, C, D, A, 9, 21, 0xEB86D391 );
#undef F
ctx->state[0] += A;
ctx->state[1] += B;
ctx->state[2] += C;
ctx->state[3] += D;
}
#endif /* !MBEDTLS_MD5_PROCESS_ALT */
/*
* MD5 process buffer
*/
void mbedtls_md5_update( mbedtls_md5_context *ctx, const unsigned char *input, size_t ilen )
{
size_t fill;
uint32_t left;
if( ilen == 0 )
return;
left = ctx->total[0] & 0x3F;
fill = 64 - left;
ctx->total[0] += (uint32_t) ilen;
ctx->total[0] &= 0xFFFFFFFF;
if( ctx->total[0] < (uint32_t) ilen )
ctx->total[1]++;
if( left && ilen >= fill )
{
memcpy( (void *) (ctx->buffer + left), input, fill );
mbedtls_md5_process( ctx, ctx->buffer );
input += fill;
ilen -= fill;
left = 0;
}
while( ilen >= 64 )
{
mbedtls_md5_process( ctx, input );
input += 64;
ilen -= 64;
}
if( ilen > 0 )
{
memcpy( (void *) (ctx->buffer + left), input, ilen );
}
}
static const unsigned char md5_padding[64] =
{
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/*
* MD5 final digest
*/
void mbedtls_md5_finish( mbedtls_md5_context *ctx, unsigned char output[16] )
{
uint32_t last, padn;
uint32_t high, low;
unsigned char msglen[8];
high = ( ctx->total[0] >> 29 )
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
PUT_UINT32_LE( low, msglen, 0 );
PUT_UINT32_LE( high, msglen, 4 );
last = ctx->total[0] & 0x3F;
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
mbedtls_md5_update( ctx, md5_padding, padn );
mbedtls_md5_update( ctx, msglen, 8 );
PUT_UINT32_LE( ctx->state[0], output, 0 );
PUT_UINT32_LE( ctx->state[1], output, 4 );
PUT_UINT32_LE( ctx->state[2], output, 8 );
PUT_UINT32_LE( ctx->state[3], output, 12 );
}
#endif /* !MBEDTLS_MD5_ALT */
/*
* output = MD5( input buffer )
*/
void mbedtls_md5( const unsigned char *input, size_t ilen, unsigned char output[16] )
{
mbedtls_md5_context ctx;
mbedtls_md5_init( &ctx );
mbedtls_md5_starts( &ctx );
mbedtls_md5_update( &ctx, input, ilen );
mbedtls_md5_finish( &ctx, output );
mbedtls_md5_free( &ctx );
}
#if defined(MBEDTLS_SELF_TEST)
/*
* RFC 1321 test vectors
*/
static const unsigned char md5_test_buf[7][81] =
{
{ "" },
{ "a" },
{ "abc" },
{ "message digest" },
{ "abcdefghijklmnopqrstuvwxyz" },
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
{ "12345678901234567890123456789012345678901234567890123456789012" \
"345678901234567890" }
};
static const int md5_test_buflen[7] =
{
0, 1, 3, 14, 26, 62, 80
};
static const unsigned char md5_test_sum[7][16] =
{
{ 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
{ 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
{ 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
{ 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
{ 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
{ 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
{ 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }
};
/*
* Checkup routine
*/
int mbedtls_md5_self_test( int verbose )
{
int i;
unsigned char md5sum[16];
for( i = 0; i < 7; i++ )
{
if( verbose != 0 )
mbedtls_printf( " MD5 test #%d: ", i + 1 );
mbedtls_md5( md5_test_buf[i], md5_test_buflen[i], md5sum );
if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
mbedtls_printf( "passed\n" );
}
if( verbose != 0 )
mbedtls_printf( "\n" );
return( 0 );
}
#endif /* MBEDTLS_SELF_TEST */
#endif /* MBEDTLS_MD5_C */

View File

@ -1,136 +0,0 @@
/**
* \file md5.h
*
* \brief MD5 message digest algorithm (hash function)
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_MD5_H
#define MBEDTLS_MD5_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#include <stdint.h>
#if !defined(MBEDTLS_MD5_ALT)
// Regular implementation
//
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief MD5 context structure
*/
typedef struct
{
uint32_t total[2]; /*!< number of bytes processed */
uint32_t state[4]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
}
mbedtls_md5_context;
/**
* \brief Initialize MD5 context
*
* \param ctx MD5 context to be initialized
*/
void mbedtls_md5_init( mbedtls_md5_context *ctx );
/**
* \brief Clear MD5 context
*
* \param ctx MD5 context to be cleared
*/
void mbedtls_md5_free( mbedtls_md5_context *ctx );
/**
* \brief Clone (the state of) an MD5 context
*
* \param dst The destination context
* \param src The context to be cloned
*/
void mbedtls_md5_clone( mbedtls_md5_context *dst,
const mbedtls_md5_context *src );
/**
* \brief MD5 context setup
*
* \param ctx context to be initialized
*/
void mbedtls_md5_starts( mbedtls_md5_context *ctx );
/**
* \brief MD5 process buffer
*
* \param ctx MD5 context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void mbedtls_md5_update( mbedtls_md5_context *ctx, const unsigned char *input, size_t ilen );
/**
* \brief MD5 final digest
*
* \param ctx MD5 context
* \param output MD5 checksum result
*/
void mbedtls_md5_finish( mbedtls_md5_context *ctx, unsigned char output[16] );
/* Internal use */
void mbedtls_md5_process( mbedtls_md5_context *ctx, const unsigned char data[64] );
#ifdef __cplusplus
}
#endif
#else /* MBEDTLS_MD5_ALT */
#include "md5_alt.h"
#endif /* MBEDTLS_MD5_ALT */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Output = MD5( input buffer )
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output MD5 checksum result
*/
void mbedtls_md5( const unsigned char *input, size_t ilen, unsigned char output[16] );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int mbedtls_md5_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* mbedtls_md5.h */

View File

@ -1,214 +0,0 @@
/**
* \file platform.h
*
* \brief mbed TLS Platform abstraction layer
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_PLATFORM_H
#define MBEDTLS_PLATFORM_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**
* \name SECTION: Module settings
*
* The configuration options you can set for this module are in this section.
* Either change them in config.h or define them on the compiler command line.
* \{
*/
#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS)
#include <stdio.h>
#include <stdlib.h>
#if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF)
#if defined(_WIN32)
#define MBEDTLS_PLATFORM_STD_SNPRINTF mbedtls_platform_win32_snprintf /**< Default snprintf to use */
#else
#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< Default snprintf to use */
#endif
#endif
#if !defined(MBEDTLS_PLATFORM_STD_PRINTF)
#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< Default printf to use */
#endif
#if !defined(MBEDTLS_PLATFORM_STD_FPRINTF)
#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use */
#endif
#if !defined(MBEDTLS_PLATFORM_STD_CALLOC)
#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< Default allocator to use */
#endif
#if !defined(MBEDTLS_PLATFORM_STD_FREE)
#define MBEDTLS_PLATFORM_STD_FREE free /**< Default free to use */
#endif
#if !defined(MBEDTLS_PLATFORM_STD_EXIT)
#define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default free to use */
#endif
#else /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
#if defined(MBEDTLS_PLATFORM_STD_MEM_HDR)
#include MBEDTLS_PLATFORM_STD_MEM_HDR
#endif
#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
/* \} name SECTION: Module settings */
/*
* The function pointers for calloc and free
*/
#if defined(MBEDTLS_PLATFORM_MEMORY)
#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && \
defined(MBEDTLS_PLATFORM_CALLOC_MACRO)
#define mbedtls_free MBEDTLS_PLATFORM_FREE_MACRO
#define mbedtls_calloc MBEDTLS_PLATFORM_CALLOC_MACRO
#else
/* For size_t */
#include <stddef.h>
extern void * (*mbedtls_calloc)( size_t n, size_t size );
extern void (*mbedtls_free)( void *ptr );
/**
* \brief Set your own memory implementation function pointers
*
* \param calloc_func the calloc function implementation
* \param free_func the free function implementation
*
* \return 0 if successful
*/
int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ),
void (*free_func)( void * ) );
#endif /* MBEDTLS_PLATFORM_FREE_MACRO && MBEDTLS_PLATFORM_CALLOC_MACRO */
#else /* !MBEDTLS_PLATFORM_MEMORY */
#define mbedtls_free free
#define mbedtls_calloc calloc
#endif /* MBEDTLS_PLATFORM_MEMORY && !MBEDTLS_PLATFORM_{FREE,CALLOC}_MACRO */
/*
* The function pointers for fprintf
*/
#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT)
/* We need FILE * */
#include <stdio.h>
extern int (*mbedtls_fprintf)( FILE *stream, const char *format, ... );
/**
* \brief Set your own fprintf function pointer
*
* \param fprintf_func the fprintf function implementation
*
* \return 0
*/
int mbedtls_platform_set_fprintf( int (*fprintf_func)( FILE *stream, const char *,
... ) );
#else
#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO)
#define mbedtls_fprintf MBEDTLS_PLATFORM_FPRINTF_MACRO
#else
#define mbedtls_fprintf fprintf
#endif /* MBEDTLS_PLATFORM_FPRINTF_MACRO */
#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */
/*
* The function pointers for printf
*/
#if defined(MBEDTLS_PLATFORM_PRINTF_ALT)
extern int (*mbedtls_printf)( const char *format, ... );
/**
* \brief Set your own printf function pointer
*
* \param printf_func the printf function implementation
*
* \return 0
*/
int mbedtls_platform_set_printf( int (*printf_func)( const char *, ... ) );
#else /* !MBEDTLS_PLATFORM_PRINTF_ALT */
#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO)
#define mbedtls_printf MBEDTLS_PLATFORM_PRINTF_MACRO
#else
#define mbedtls_printf printf
#endif /* MBEDTLS_PLATFORM_PRINTF_MACRO */
#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */
/*
* The function pointers for snprintf
*
* The snprintf implementation should conform to C99:
* - it *must* always correctly zero-terminate the buffer
* (except when n == 0, then it must leave the buffer untouched)
* - however it is acceptable to return -1 instead of the required length when
* the destination buffer is too short.
*/
#if defined(_WIN32)
/* For Windows (inc. MSYS2), we provide our own fixed implementation */
int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... );
#endif
#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT)
extern int (*mbedtls_snprintf)( char * s, size_t n, const char * format, ... );
/**
* \brief Set your own snprintf function pointer
*
* \param snprintf_func the snprintf function implementation
*
* \return 0
*/
int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n,
const char * format, ... ) );
#else /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO)
#define mbedtls_snprintf MBEDTLS_PLATFORM_SNPRINTF_MACRO
#else
#define mbedtls_snprintf snprintf
#endif /* MBEDTLS_PLATFORM_SNPRINTF_MACRO */
#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
/*
* The function pointers for exit
*/
#if defined(MBEDTLS_PLATFORM_EXIT_ALT)
extern void (*mbedtls_exit)( int status );
/**
* \brief Set your own exit function pointer
*
* \param exit_func the exit function implementation
*
* \return 0
*/
int mbedtls_platform_set_exit( void (*exit_func)( int status ) );
#else
#if defined(MBEDTLS_PLATFORM_EXIT_MACRO)
#define mbedtls_exit MBEDTLS_PLATFORM_EXIT_MACRO
#else
#define mbedtls_exit exit
#endif /* MBEDTLS_PLATFORM_EXIT_MACRO */
#endif /* MBEDTLS_PLATFORM_EXIT_ALT */
#ifdef __cplusplus
}
#endif
#endif /* platform.h */

View File

@ -1,448 +0,0 @@
/*
* FIPS-180-1 compliant SHA-1 implementation
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* The SHA-1 standard was published by NIST in 1993.
*
* http://www.itl.nist.gov/fipspubs/fip180-1.htm
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_SHA1_C)
#include "mbedtls/sha1.h"
#include <string.h>
#if defined(MBEDTLS_SELF_TEST)
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdio.h>
#define mbedtls_printf printf
#endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */
#if !defined(MBEDTLS_SHA1_ALT)
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
/*
* 32-bit integer manipulation macros (big endian)
*/
#ifndef GET_UINT32_BE
#define GET_UINT32_BE(n,b,i) \
{ \
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
| ( (uint32_t) (b)[(i) + 3] ); \
}
#endif
#ifndef PUT_UINT32_BE
#define PUT_UINT32_BE(n,b,i) \
{ \
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 3] = (unsigned char) ( (n) ); \
}
#endif
void mbedtls_sha1_init( mbedtls_sha1_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_sha1_context ) );
}
void mbedtls_sha1_free( mbedtls_sha1_context *ctx )
{
if( ctx == NULL )
return;
mbedtls_zeroize( ctx, sizeof( mbedtls_sha1_context ) );
}
void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
const mbedtls_sha1_context *src )
{
*dst = *src;
}
/*
* SHA-1 context setup
*/
void mbedtls_sha1_starts( mbedtls_sha1_context *ctx )
{
ctx->total[0] = 0;
ctx->total[1] = 0;
ctx->state[0] = 0x67452301;
ctx->state[1] = 0xEFCDAB89;
ctx->state[2] = 0x98BADCFE;
ctx->state[3] = 0x10325476;
ctx->state[4] = 0xC3D2E1F0;
}
#if !defined(MBEDTLS_SHA1_PROCESS_ALT)
void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] )
{
uint32_t temp, W[16], A, B, C, D, E;
GET_UINT32_BE( W[ 0], data, 0 );
GET_UINT32_BE( W[ 1], data, 4 );
GET_UINT32_BE( W[ 2], data, 8 );
GET_UINT32_BE( W[ 3], data, 12 );
GET_UINT32_BE( W[ 4], data, 16 );
GET_UINT32_BE( W[ 5], data, 20 );
GET_UINT32_BE( W[ 6], data, 24 );
GET_UINT32_BE( W[ 7], data, 28 );
GET_UINT32_BE( W[ 8], data, 32 );
GET_UINT32_BE( W[ 9], data, 36 );
GET_UINT32_BE( W[10], data, 40 );
GET_UINT32_BE( W[11], data, 44 );
GET_UINT32_BE( W[12], data, 48 );
GET_UINT32_BE( W[13], data, 52 );
GET_UINT32_BE( W[14], data, 56 );
GET_UINT32_BE( W[15], data, 60 );
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
#define R(t) \
( \
temp = W[( t - 3 ) & 0x0F] ^ W[( t - 8 ) & 0x0F] ^ \
W[( t - 14 ) & 0x0F] ^ W[ t & 0x0F], \
( W[t & 0x0F] = S(temp,1) ) \
)
#define P(a,b,c,d,e,x) \
{ \
e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \
}
A = ctx->state[0];
B = ctx->state[1];
C = ctx->state[2];
D = ctx->state[3];
E = ctx->state[4];
#define F(x,y,z) (z ^ (x & (y ^ z)))
#define K 0x5A827999
P( A, B, C, D, E, W[0] );
P( E, A, B, C, D, W[1] );
P( D, E, A, B, C, W[2] );
P( C, D, E, A, B, W[3] );
P( B, C, D, E, A, W[4] );
P( A, B, C, D, E, W[5] );
P( E, A, B, C, D, W[6] );
P( D, E, A, B, C, W[7] );
P( C, D, E, A, B, W[8] );
P( B, C, D, E, A, W[9] );
P( A, B, C, D, E, W[10] );
P( E, A, B, C, D, W[11] );
P( D, E, A, B, C, W[12] );
P( C, D, E, A, B, W[13] );
P( B, C, D, E, A, W[14] );
P( A, B, C, D, E, W[15] );
P( E, A, B, C, D, R(16) );
P( D, E, A, B, C, R(17) );
P( C, D, E, A, B, R(18) );
P( B, C, D, E, A, R(19) );
#undef K
#undef F
#define F(x,y,z) (x ^ y ^ z)
#define K 0x6ED9EBA1
P( A, B, C, D, E, R(20) );
P( E, A, B, C, D, R(21) );
P( D, E, A, B, C, R(22) );
P( C, D, E, A, B, R(23) );
P( B, C, D, E, A, R(24) );
P( A, B, C, D, E, R(25) );
P( E, A, B, C, D, R(26) );
P( D, E, A, B, C, R(27) );
P( C, D, E, A, B, R(28) );
P( B, C, D, E, A, R(29) );
P( A, B, C, D, E, R(30) );
P( E, A, B, C, D, R(31) );
P( D, E, A, B, C, R(32) );
P( C, D, E, A, B, R(33) );
P( B, C, D, E, A, R(34) );
P( A, B, C, D, E, R(35) );
P( E, A, B, C, D, R(36) );
P( D, E, A, B, C, R(37) );
P( C, D, E, A, B, R(38) );
P( B, C, D, E, A, R(39) );
#undef K
#undef F
#define F(x,y,z) ((x & y) | (z & (x | y)))
#define K 0x8F1BBCDC
P( A, B, C, D, E, R(40) );
P( E, A, B, C, D, R(41) );
P( D, E, A, B, C, R(42) );
P( C, D, E, A, B, R(43) );
P( B, C, D, E, A, R(44) );
P( A, B, C, D, E, R(45) );
P( E, A, B, C, D, R(46) );
P( D, E, A, B, C, R(47) );
P( C, D, E, A, B, R(48) );
P( B, C, D, E, A, R(49) );
P( A, B, C, D, E, R(50) );
P( E, A, B, C, D, R(51) );
P( D, E, A, B, C, R(52) );
P( C, D, E, A, B, R(53) );
P( B, C, D, E, A, R(54) );
P( A, B, C, D, E, R(55) );
P( E, A, B, C, D, R(56) );
P( D, E, A, B, C, R(57) );
P( C, D, E, A, B, R(58) );
P( B, C, D, E, A, R(59) );
#undef K
#undef F
#define F(x,y,z) (x ^ y ^ z)
#define K 0xCA62C1D6
P( A, B, C, D, E, R(60) );
P( E, A, B, C, D, R(61) );
P( D, E, A, B, C, R(62) );
P( C, D, E, A, B, R(63) );
P( B, C, D, E, A, R(64) );
P( A, B, C, D, E, R(65) );
P( E, A, B, C, D, R(66) );
P( D, E, A, B, C, R(67) );
P( C, D, E, A, B, R(68) );
P( B, C, D, E, A, R(69) );
P( A, B, C, D, E, R(70) );
P( E, A, B, C, D, R(71) );
P( D, E, A, B, C, R(72) );
P( C, D, E, A, B, R(73) );
P( B, C, D, E, A, R(74) );
P( A, B, C, D, E, R(75) );
P( E, A, B, C, D, R(76) );
P( D, E, A, B, C, R(77) );
P( C, D, E, A, B, R(78) );
P( B, C, D, E, A, R(79) );
#undef K
#undef F
ctx->state[0] += A;
ctx->state[1] += B;
ctx->state[2] += C;
ctx->state[3] += D;
ctx->state[4] += E;
}
#endif /* !MBEDTLS_SHA1_PROCESS_ALT */
/*
* SHA-1 process buffer
*/
void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen )
{
size_t fill;
uint32_t left;
if( ilen == 0 )
return;
left = ctx->total[0] & 0x3F;
fill = 64 - left;
ctx->total[0] += (uint32_t) ilen;
ctx->total[0] &= 0xFFFFFFFF;
if( ctx->total[0] < (uint32_t) ilen )
ctx->total[1]++;
if( left && ilen >= fill )
{
memcpy( (void *) (ctx->buffer + left), input, fill );
mbedtls_sha1_process( ctx, ctx->buffer );
input += fill;
ilen -= fill;
left = 0;
}
while( ilen >= 64 )
{
mbedtls_sha1_process( ctx, input );
input += 64;
ilen -= 64;
}
if( ilen > 0 )
memcpy( (void *) (ctx->buffer + left), input, ilen );
}
static const unsigned char sha1_padding[64] =
{
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/*
* SHA-1 final digest
*/
void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] )
{
uint32_t last, padn;
uint32_t high, low;
unsigned char msglen[8];
high = ( ctx->total[0] >> 29 )
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
PUT_UINT32_BE( high, msglen, 0 );
PUT_UINT32_BE( low, msglen, 4 );
last = ctx->total[0] & 0x3F;
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
mbedtls_sha1_update( ctx, sha1_padding, padn );
mbedtls_sha1_update( ctx, msglen, 8 );
PUT_UINT32_BE( ctx->state[0], output, 0 );
PUT_UINT32_BE( ctx->state[1], output, 4 );
PUT_UINT32_BE( ctx->state[2], output, 8 );
PUT_UINT32_BE( ctx->state[3], output, 12 );
PUT_UINT32_BE( ctx->state[4], output, 16 );
}
#endif /* !MBEDTLS_SHA1_ALT */
/*
* output = SHA-1( input buffer )
*/
void mbedtls_sha1( const unsigned char *input, size_t ilen, unsigned char output[20] )
{
mbedtls_sha1_context ctx;
mbedtls_sha1_init( &ctx );
mbedtls_sha1_starts( &ctx );
mbedtls_sha1_update( &ctx, input, ilen );
mbedtls_sha1_finish( &ctx, output );
mbedtls_sha1_free( &ctx );
}
#if defined(MBEDTLS_SELF_TEST)
/*
* FIPS-180-1 test vectors
*/
static const unsigned char sha1_test_buf[3][57] =
{
{ "abc" },
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
{ "" }
};
static const int sha1_test_buflen[3] =
{
3, 56, 1000
};
static const unsigned char sha1_test_sum[3][20] =
{
{ 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D },
{ 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 },
{ 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E,
0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F }
};
/*
* Checkup routine
*/
int mbedtls_sha1_self_test( int verbose )
{
int i, j, buflen, ret = 0;
unsigned char buf[1024];
unsigned char sha1sum[20];
mbedtls_sha1_context ctx;
mbedtls_sha1_init( &ctx );
/*
* SHA-1
*/
for( i = 0; i < 3; i++ )
{
if( verbose != 0 )
mbedtls_printf( " SHA-1 test #%d: ", i + 1 );
mbedtls_sha1_starts( &ctx );
if( i == 2 )
{
memset( buf, 'a', buflen = 1000 );
for( j = 0; j < 1000; j++ )
mbedtls_sha1_update( &ctx, buf, buflen );
}
else
mbedtls_sha1_update( &ctx, sha1_test_buf[i],
sha1_test_buflen[i] );
mbedtls_sha1_finish( &ctx, sha1sum );
if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
ret = 1;
goto exit;
}
if( verbose != 0 )
mbedtls_printf( "passed\n" );
}
if( verbose != 0 )
mbedtls_printf( "\n" );
exit:
mbedtls_sha1_free( &ctx );
return( ret );
}
#endif /* MBEDTLS_SELF_TEST */
#endif /* MBEDTLS_SHA1_C */

View File

@ -1,136 +0,0 @@
/**
* \file sha1.h
*
* \brief SHA-1 cryptographic hash function
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_SHA1_H
#define MBEDTLS_SHA1_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#include <stdint.h>
#if !defined(MBEDTLS_SHA1_ALT)
// Regular implementation
//
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief SHA-1 context structure
*/
typedef struct
{
uint32_t total[2]; /*!< number of bytes processed */
uint32_t state[5]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
}
mbedtls_sha1_context;
/**
* \brief Initialize SHA-1 context
*
* \param ctx SHA-1 context to be initialized
*/
void mbedtls_sha1_init( mbedtls_sha1_context *ctx );
/**
* \brief Clear SHA-1 context
*
* \param ctx SHA-1 context to be cleared
*/
void mbedtls_sha1_free( mbedtls_sha1_context *ctx );
/**
* \brief Clone (the state of) a SHA-1 context
*
* \param dst The destination context
* \param src The context to be cloned
*/
void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
const mbedtls_sha1_context *src );
/**
* \brief SHA-1 context setup
*
* \param ctx context to be initialized
*/
void mbedtls_sha1_starts( mbedtls_sha1_context *ctx );
/**
* \brief SHA-1 process buffer
*
* \param ctx SHA-1 context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen );
/**
* \brief SHA-1 final digest
*
* \param ctx SHA-1 context
* \param output SHA-1 checksum result
*/
void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] );
/* Internal use */
void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] );
#ifdef __cplusplus
}
#endif
#else /* MBEDTLS_SHA1_ALT */
#include "sha1_alt.h"
#endif /* MBEDTLS_SHA1_ALT */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Output = SHA-1( input buffer )
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output SHA-1 checksum result
*/
void mbedtls_sha1( const unsigned char *input, size_t ilen, unsigned char output[20] );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int mbedtls_sha1_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* mbedtls_sha1.h */

BIN
others/modsec_white_bg.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

View File

@ -68,21 +68,21 @@ libmodsecurity_includesub_actions_HEADERS = \
noinst_HEADERS = \
actions/*.h \
actions/ctl/*.h \
actions/data/*.h \
actions/disruptive/*.h \
actions/transformations/*.h \
debug_log/*.h \
audit_log/writer/*.h \
collection/backend/*.h \
operators/*.h \
parser/*.h \
request_body_processor/*.h \
utils/*.h \
variables/*.h \
engine/*.h \
*.h
$(wildcard actions/*.h) \
$(wildcard actions/ctl/*.h) \
$(wildcard actions/data/*.h) \
$(wildcard actions/disruptive/*.h) \
$(wildcard actions/transformations/*.h) \
$(wildcard debug_log/*.h) \
$(wildcard audit_log/writer/*.h) \
$(wildcard collection/backend/*.h) \
$(wildcard operators/*.h) \
$(wildcard parser/*.h) \
$(wildcard request_body_processor/*.h) \
$(wildcard utils/*.h) \
$(wildcard variables/*.h) \
$(wildcard engine/*.h) \
$(wildcard *.h)
ENGINES = \
@ -119,6 +119,7 @@ ACTIONS = \
actions/chain.cc \
actions/ctl/audit_log_parts.cc \
actions/ctl/audit_engine.cc \
actions/ctl/parse_xml_into_args.cc \
actions/ctl/rule_engine.cc \
actions/ctl/request_body_processor_json.cc \
actions/ctl/request_body_processor_xml.cc \
@ -219,7 +220,6 @@ OPERATORS = \
operators/no_match.cc \
operators/operator.cc \
operators/pm.cc \
operators/pm_f.cc \
operators/pm_from_file.cc \
operators/rbl.cc \
operators/rsub.cc \
@ -248,12 +248,9 @@ UTILS = \
utils/geo_lookup.cc \
utils/https_client.cc \
utils/ip_tree.cc \
utils/md5.cc \
utils/msc_tree.cc \
utils/random.cc \
utils/regex.cc \
utils/sha1.cc \
utils/string.cc \
utils/system.cc \
utils/shared_files.cc
@ -311,18 +308,18 @@ libmodsecurity_la_CFLAGS =
libmodsecurity_la_CPPFLAGS = \
-std=c++11 \
-I.. \
-I$(top_srcdir) \
-I$(top_builddir) \
-g \
-I../others \
-I$(top_srcdir)/others \
-I$(top_srcdir)/others/mbedtls/include \
-fPIC \
-O3 \
-I../headers \
-I$(top_srcdir)/headers \
$(CURL_CFLAGS) \
$(GEOIP_CFLAGS) \
$(GLOBAL_CPPFLAGS) \
$(MODSEC_NO_LOGS) \
$(MODSEC_MUTEX_ON_PM) \
$(YAJL_CFLAGS) \
$(LMDB_CFLAGS) \
$(PCRE_CFLAGS) \

View File

@ -15,16 +15,10 @@
#include "src/actions/accuracy.h"
#include <iostream>
#include <string>
#include "modsecurity/actions/action.h"
#include "modsecurity/transaction.h"
#include "modsecurity/rule.h"
#include "modsecurity/rule_with_actions.h"
namespace modsecurity {
namespace actions {
namespace modsecurity::actions {
bool Accuracy::init(std::string *error) {
@ -45,5 +39,4 @@ bool Accuracy::evaluate(RuleWithActions *rule, Transaction *transaction) {
}
} // namespace actions
} // namespace modsecurity
} // namespace modsecurity::actions

View File

@ -30,7 +30,7 @@ namespace actions {
class Accuracy : public Action {
public:
explicit Accuracy(const std::string &action)
: Action(action, ConfigurationKind),
: Action(action, Kind::ConfigurationKind),
m_accuracy(0) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction) override;

View File

@ -45,12 +45,6 @@ namespace modsecurity {
namespace actions {
std::string Action::evaluate(const std::string &value,
Transaction *transaction) {
return value;
}
bool Action::evaluate(RuleWithActions *rule, Transaction *transaction) {
return true;
}

View File

@ -27,11 +27,10 @@ namespace modsecurity {
namespace actions {
bool AuditLog::evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) {
rm->m_noAuditLog = false;
bool AuditLog::evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) {
ruleMessage.m_noAuditLog = false;
ms_dbg_a(transaction, 9, "Saving transaction to logs");
rm->m_saveMessage = true;
ruleMessage.m_saveMessage = true;
return true;
}

View File

@ -33,10 +33,9 @@ namespace actions {
class AuditLog : public Action {
public:
explicit AuditLog(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind) { }
: Action(action) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) override;
bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override;
};

View File

@ -29,15 +29,14 @@ namespace modsecurity {
namespace actions {
bool Block::evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) {
bool Block::evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) {
ms_dbg_a(transaction, 8, "Marking request as disruptive.");
for (auto &a : transaction->m_rules->m_defaultActions[rule->getPhase()]) {
if (a->isDisruptive() == false) {
continue;
}
a->evaluate(rule, transaction, rm);
a->evaluate(rule, transaction, ruleMessage);
}
return true;

View File

@ -35,8 +35,7 @@ class Block : public Action {
public:
explicit Block(const std::string &action) : Action(action) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) override;
bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override;
};

View File

@ -29,7 +29,7 @@ namespace actions {
class Capture : public Action {
public:
explicit Capture(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind) { }
: Action(action) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction) override;
};

View File

@ -15,14 +15,9 @@
#include "src/actions/chain.h"
#include <iostream>
#include <string>
#include "modsecurity/rule_with_actions.h"
#include "modsecurity/transaction.h"
#include "modsecurity/rule.h"
namespace modsecurity {
namespace actions {
namespace modsecurity::actions {
bool Chain::evaluate(RuleWithActions *rule, Transaction *transaction) {
@ -31,5 +26,4 @@ bool Chain::evaluate(RuleWithActions *rule, Transaction *transaction) {
}
} // namespace actions
} // namespace modsecurity
} // namespace modsecurity::actions

View File

@ -33,7 +33,7 @@ namespace actions {
class Chain : public Action {
public:
explicit Chain(const std::string &action)
: Action(action, ConfigurationKind) { }
: Action(action, Kind::ConfigurationKind) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction) override;
};

View File

@ -34,7 +34,7 @@ namespace ctl {
class AuditEngine : public Action {
public:
explicit AuditEngine(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind),
: Action(action),
m_auditEngine(audit_log::AuditLog::AuditLogStatus::NotSetLogStatus) { }
bool init(std::string *error) override;

View File

@ -29,7 +29,7 @@ namespace ctl {
class AuditLogParts : public Action {
public:
explicit AuditLogParts(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind),
: Action(action),
mPartsAction(0),
mParts("") { }

View File

@ -0,0 +1,63 @@
/*
* ModSecurity, http://www.modsecurity.org/
* Copyright (c) 2025 OWASP ModSecurity project
*
* You may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* If any of the files related to licensing are missing or if you have any
* other questions related to licensing please contact OWASP.
* directly using the email address modsecurity@owasp.org.
*
*/
#include "src/actions/ctl/parse_xml_into_args.h"
#include <iostream>
#include <string>
#include "modsecurity/rules_set_properties.h"
#include "modsecurity/rules_set.h"
#include "modsecurity/transaction.h"
namespace modsecurity {
namespace actions {
namespace ctl {
bool ParseXmlIntoArgs::init(std::string *error) {
std::string what(m_parser_payload, 17, m_parser_payload.size() - 17);
if (what == "on") {
m_secXMLParseXmlIntoArgs = RulesSetProperties::TrueConfigXMLParseXmlIntoArgs;
} else if (what == "off") {
m_secXMLParseXmlIntoArgs = RulesSetProperties::FalseConfigXMLParseXmlIntoArgs;
} else if (what == "onlyargs") {
m_secXMLParseXmlIntoArgs = RulesSetProperties::OnlyArgsConfigXMLParseXmlIntoArgs;
} else {
error->assign("Internal error. Expected: On, Off or OnlyArgs; " \
"got: " + m_parser_payload);
return false;
}
return true;
}
bool ParseXmlIntoArgs::evaluate(RuleWithActions *rule, Transaction *transaction) {
std::stringstream a;
a << "Setting SecParseXmlIntoArgs to ";
a << modsecurity::RulesSetProperties::configXMLParseXmlIntoArgsString(m_secXMLParseXmlIntoArgs);
a << " as requested by a ctl:parseXmlIntoArgs action";
ms_dbg_a(transaction, 8, a.str());
transaction->m_secXMLParseXmlIntoArgs = m_secXMLParseXmlIntoArgs;
return true;
}
} // namespace ctl
} // namespace actions
} // namespace modsecurity

View File

@ -0,0 +1,48 @@
/*
* ModSecurity, http://www.modsecurity.org/
* Copyright (c) 2025 OWASP ModSecurity Project
*
* You may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* If any of the files related to licensing are missing or if you have any
* other questions related to licensing please contact OWASP.
* directly using the email address modsecurity@owasp.org
*
*/
#include <string>
#include "modsecurity/rules_set_properties.h"
#include "modsecurity/actions/action.h"
#include "modsecurity/transaction.h"
#ifndef SRC_ACTIONS_CTL_PARSE_XML_INTO_ARGS_H_
#define SRC_ACTIONS_CTL_PARSE_XML_INTO_ARGS_H_
namespace modsecurity {
namespace actions {
namespace ctl {
class ParseXmlIntoArgs : public Action {
public:
explicit ParseXmlIntoArgs(const std::string &action)
: Action(action),
m_secXMLParseXmlIntoArgs(RulesSetProperties::PropertyNotSetConfigXMLParseXmlIntoArgs) { }
bool init(std::string *error) override;
bool evaluate(RuleWithActions *rule, Transaction *transaction) override;
RulesSetProperties::ConfigXMLParseXmlIntoArgs m_secXMLParseXmlIntoArgs;
};
} // namespace ctl
} // namespace actions
} // namespace modsecurity
#endif // SRC_ACTIONS_CTL_PARSE_XML_INTO_ARGS_H_

View File

@ -30,7 +30,7 @@ namespace ctl {
class RequestBodyAccess : public Action {
public:
explicit RequestBodyAccess(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind),
: Action(action),
m_request_body_access(false) { }
bool init(std::string *error) override;

View File

@ -29,7 +29,7 @@ namespace ctl {
class RequestBodyProcessorJSON : public Action {
public:
explicit RequestBodyProcessorJSON(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind) { }
: Action(action) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction) override;
};

View File

@ -29,7 +29,7 @@ namespace ctl {
class RequestBodyProcessorURLENCODED : public Action {
public:
explicit RequestBodyProcessorURLENCODED(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind) { }
: Action(action) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction) override;
};

View File

@ -29,7 +29,7 @@ namespace ctl {
class RequestBodyProcessorXML : public Action {
public:
explicit RequestBodyProcessorXML(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind) { }
: Action(action) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction) override;
};

View File

@ -31,7 +31,7 @@ namespace ctl {
class RuleEngine : public Action {
public:
explicit RuleEngine(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind),
: Action(action),
m_ruleEngine(RulesSetProperties::PropertyNotSetRuleEngine) { }
bool init(std::string *error) override;

View File

@ -84,10 +84,10 @@ bool RuleRemoveById::init(std::string *error) {
}
bool RuleRemoveById::evaluate(RuleWithActions *rule, Transaction *transaction) {
for (auto &i : m_ids) {
for (const auto &i : m_ids) {
transaction->m_ruleRemoveById.push_back(i);
}
for (auto &i : m_ranges) {
for (const auto &i : m_ranges) {
transaction->m_ruleRemoveByIdRange.push_back(i);
}

View File

@ -30,7 +30,7 @@ namespace ctl {
class RuleRemoveById : public Action {
public:
explicit RuleRemoveById(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind) { }
: Action(action) { }
bool init(std::string *error) override;
bool evaluate(RuleWithActions *rule, Transaction *transaction) override;

View File

@ -30,7 +30,7 @@ namespace ctl {
class RuleRemoveByTag : public Action {
public:
explicit RuleRemoveByTag(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind),
: Action(action),
m_tag("") { }
bool init(std::string *error) override;

View File

@ -30,7 +30,7 @@ namespace ctl {
class RuleRemoveTargetById : public Action {
public:
explicit RuleRemoveTargetById(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind),
: Action(action),
m_id(0),
m_target("") { }

View File

@ -30,7 +30,7 @@ namespace ctl {
class RuleRemoveTargetByTag : public Action {
public:
explicit RuleRemoveTargetByTag(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind) { }
: Action(action) { }
bool init(std::string *error) override;
bool evaluate(RuleWithActions *rule, Transaction *transaction) override;

View File

@ -39,7 +39,7 @@ bool Status::init(std::string *error) {
bool Status::evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) {
RuleMessage &ruleMessage) {
transaction->m_it.status = m_status;
return true;
}

View File

@ -33,12 +33,11 @@ namespace data {
class Status : public Action {
public:
explicit Status(const std::string &action) : Action(action, 2),
m_status(0) { }
explicit Status(const std::string &action)
: Action(action), m_status(0) { }
bool init(std::string *error) override;
bool evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) override;
bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override;
int m_status;
};

View File

@ -54,7 +54,7 @@ enum AllowType : int {
class Allow : public Action {
public:
explicit Allow(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind),
: Action(action),
m_allowType(NoneAllowType) { }

View File

@ -29,7 +29,7 @@ namespace disruptive {
bool Deny::evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) {
RuleMessage &ruleMessage) {
ms_dbg_a(transaction, 8, "Running action deny");
if (transaction->m_it.status == 200) {
@ -38,9 +38,9 @@ bool Deny::evaluate(RuleWithActions *rule, Transaction *transaction,
transaction->m_it.disruptive = true;
intervention::freeLog(&transaction->m_it);
rm->m_isDisruptive = true;
ruleMessage.m_isDisruptive = true;
transaction->m_it.log = strdup(
rm->log(RuleMessage::LogMessageInfo::ClientLogMessageInfo).c_str());
ruleMessage.log(RuleMessage::LogMessageInfo::ClientLogMessageInfo).c_str());
return true;
}

Some files were not shown because too many files have changed in this diff Show More