;;; Copyright © 2025 Wojtek Kosior ;;; Licensed under the Creative Commons Zero v1.0. (define-module (gnu packages modsecurity) #:use-module ((gnu packages apr) #:select (apr apr-util)) #:use-module ((gnu packages autotools) #:select (autoconf automake libtool)) #:use-module ((gnu packages bison) #:select (bison)) #:use-module ((gnu packages curl) #:select (curl)) #:use-module ((gnu packages databases) #:select (lmdb)) #:use-module ((gnu packages datastructures) #:select (ssdeep)) #:use-module ((gnu packages documentation) #:select (doxygen)) #:use-module ((gnu packages flex) #:select (flex)) #:use-module ((gnu packages geo) #:select (libmaxminddb)) #:use-module ((gnu packages lua) #:select (lua)) #:use-module ((gnu packages pcre) #:select (pcre pcre2)) #:use-module ((gnu packages perl) #:select (perl)) #:use-module ((gnu packages pkg-config) #:select (pkg-config)) #:use-module ((gnu packages xml) #:select (libxml2)) #:use-module ((gnu packages valgrind) #:select (valgrind)) #:use-module ((gnu packages web) #:select (httpd yajl)) #:use-module ((guix build-system gnu) #:select (gnu-build-system)) #:use-module ((guix gexp) #:select (gexp file-append)) #:use-module ((guix git-download) #:select (git-fetch git-file-name git-reference)) #:use-module ((guix licenses) #:select (asl2.0 bsd-3)) #:use-module ((guix packages) #:select (base32 delete modify-inputs origin package package-arguments package-inputs replace)) #:use-module ((guix utils) #:select (substitute-keyword-arguments))) (define-public libmodsecurity (package (name "libmodsecurity") (version "3.0.13") (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/owasp-modsecurity/ModSecurity") (commit (format #f "v~a" version)) (recursive? #t))) (file-name (git-file-name name version)) (sha256 (base32 "0khzm7wfd34w3zdhinq8z46c21pwcczb5jvg2j0b0d1v9nvzaggv")))) (build-system gnu-build-system) (arguments (list #:configure-flags #~(cons* "--with-pcre2" (map (lambda (name) (format #f "--with-~a=~a" name (assoc-ref %build-inputs name))) '("curl" "lmdb" "ssdeep"))) #:phases #~(modify-phases %standard-phases (add-after 'patch-source-shebangs 'patch-prog-paths-in-tests (lambda _ (let* ((PATH (string-split (getenv "PATH") #\:)) (/bin/echo (search-path PATH "echo")) (/bin/ech (string-drop-right /bin/echo 1)) (regression "test/test-cases/regression")) (for-each (lambda (test) (substitute* (format #f "test/test-cases/regression/~a.json" test) (("/bin/ech") /bin/ech))) '("action-exec" "operator-inpectFile"))))) (add-before 'configure 'fix-ssdeep-searching (lambda _ (substitute* "build/ssdeep.m4" (("\\[Path to ssdeep prefix\\]\\)\\]" matched) (string-append matched ",[SSDEEP_POSSIBLE_PATHS=\"${with_ssdeep}\";" " with_ssdeep=yes]")))))))) (inputs (list curl libmaxminddb libxml2 lmdb lua pcre2 ssdeep yajl)) (native-inputs (list autoconf automake bison doxygen libtool flex perl pkg-config valgrind)) (synopsis "Free software web application firewall (WAF) library") (description "Libmodsecurity is one component of the ModSecurity v3 project. The library codebase serves as an interface to ModSecurity Connectors taking in web traffic and applying traditional ModSecurity processing.") (home-page "https://modsecurity.org/") (license (list asl2.0 ;; libmodsecurity, Mbed TLS bsd-3)))) ;; libinjection (define httpd-modsecurity-with-older-pcre (package (name "httpd-modsecurity") (version "2.9.8") (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/owasp-modsecurity/ModSecurity") (commit (format #f "v~a" version)))) (file-name (git-file-name name version)) (sha256 (base32 "04mjmc0kp3k56lvi4s8vmksiqsamspsj5cqbk14bkr36xrw5g7kw")))) (build-system gnu-build-system) (arguments (list #:configure-flags #~(let ((inputs `(("apu" . ,(assoc-ref %build-inputs "apr-util")) ("apxs" . ,(assoc-ref %build-inputs "httpd")) . ,%build-inputs))) (map (lambda (name) (format #f "--with-~a=~a" name (assoc-ref inputs name))) '("apr" "apu" "apxs" "curl" "pcre" "ssdeep"))) #:phases #~(modify-phases %standard-phases (add-after 'unpack 'supply-id_log-for-test-linking (lambda _ (let ((port (open-file "tests/msc_test.c" "a"))) ;; True `id_log' is in `apache2/apache2_config.c' which ;; isn't and cannot (easily) be linked with the test. (format port "const char* id_log(msre_rule* _) ~ {return \"DUMMY\";}") (close port)))) (add-after 'unpack 'fix-module-installation-prefix (lambda _ (substitute* "apache2/Makefile.am" (("(\\$.DESTDIR.)(\\$.APXS_MODULES.)" _ dst apxs_mods) (format #f "~a$(prefix)~a" dst apxs_mods))))) (add-after 'install-license-files 'install-NOTICE-file (lambda* (#:key outputs #:allow-other-keys) (let* ((out (assoc-ref outputs "out")) (package (strip-store-file-name out))) (install-file "NOTICE" (format #f "~a/share/doc/~a" out package)))))))) (inputs (list apr apr-util curl httpd libxml2 lua (list pcre "bin") ssdeep yajl)) (native-inputs (list autoconf automake httpd libtool perl pkg-config)) (synopsis "Free software web application firewall (WAF) module") (description "ModSecurity enables web application defenders to gain visibility into HTTP(S) and provides a power rules language and API to implement advanced protections.") (home-page "https://modsecurity.org/") (license (list asl2.0)))) (define-public httpd-modsecurity (let ((base httpd-modsecurity-with-older-pcre)) (package (inherit base) (arguments (substitute-keyword-arguments (package-arguments base) ;; Sadly, tests don't seem to work with PRCE2. ((#:tests? _ #f) #f) ((#:configure-flags flags) #~(cons (format #f "--with-pcre2=~a" (assoc-ref %build-inputs "pcre2")) #$flags)))) (inputs (modify-inputs (package-inputs base) (delete "pcre") (append pcre2))))))