diff --git a/apache2/Makefile.am b/apache2/Makefile.am index 2bbc887c..e58e1f54 100644 --- a/apache2/Makefile.am +++ b/apache2/Makefile.am @@ -38,7 +38,8 @@ mod_security2_la_CFLAGS = @APR_CFLAGS@ \ @LIBXML2_CFLAGS@ \ @LUA_CFLAGS@ \ @MODSEC_EXTRA_CFLAGS@ \ - @PCRE_CFLAGS@ + @PCRE_CFLAGS@ \ + @YAJL_CFLAGS@ mod_security2_la_CPPFLAGS = @APR_CPPFLAGS@ \ @@ -49,7 +50,8 @@ mod_security2_la_LIBADD = @APR_LDADD@ \ @APU_LDADD@ \ @LIBXML2_LDADD@ \ @LUA_LDADD@ \ - @PCRE_LDADD@ + @PCRE_LDADD@ \ + @YAJL_LDADD@ if AIX mod_security2_la_LDFLAGS = -module -avoid-version \ @@ -58,7 +60,8 @@ mod_security2_la_LDFLAGS = -module -avoid-version \ @APXS_LDFLAGS@ \ @LIBXML2_LDFLAGS@ \ @LUA_LDFLAGS@ \ - @PCRE_LDFLAGS@ + @PCRE_LDFLAGS@ \ + @YAJL_LDFLAGS@ endif if HPUX @@ -68,7 +71,8 @@ mod_security2_la_LDFLAGS = -module -avoid-version \ @APXS_LDFLAGS@ \ @LIBXML2_LDFLAGS@ \ @LUA_LDFLAGS@ \ - @PCRE_LDFLAGS@ + @PCRE_LDFLAGS@ \ + @YAJL_LDFLAGS@ endif if MACOSX @@ -78,7 +82,8 @@ mod_security2_la_LDFLAGS = -module -avoid-version \ @APXS_LDFLAGS@ \ @LIBXML2_LDFLAGS@ \ @LUA_LDFLAGS@ \ - @PCRE_LDFLAGS@ + @PCRE_LDFLAGS@ \ + @YAJL_LDFLAGS@ endif if SOLARIS @@ -88,7 +93,8 @@ mod_security2_la_LDFLAGS = -module -avoid-version \ @APXS_LDFLAGS@ \ @LIBXML2_LDFLAGS@ \ @LUA_LDFLAGS@ \ - @PCRE_LDFLAGS@ + @PCRE_LDFLAGS@ \ + @YAJL_LDFLAGS@ endif if LINUX @@ -98,7 +104,8 @@ mod_security2_la_LDFLAGS = -no-undefined -module -avoid-version -R @PCRE_LD_PATH @APXS_LDFLAGS@ \ @LIBXML2_LDFLAGS@ \ @LUA_LDFLAGS@ \ - @PCRE_LDFLAGS@ + @PCRE_LDFLAGS@ \ + @YAJL_LDFLAGS@ endif if FREEBSD @@ -108,7 +115,8 @@ mod_security2_la_LDFLAGS = -no-undefined -module -avoid-version \ @APXS_LDFLAGS@ \ @LIBXML2_LDFLAGS@ \ @LUA_LDFLAGS@ \ - @PCRE_LDFLAGS@ + @PCRE_LDFLAGS@ \ + @YAJL_LDFLAGS@ endif if OPENBSD @@ -118,7 +126,8 @@ mod_security2_la_LDFLAGS = -no-undefined -module -avoid-version \ @APXS_LDFLAGS@ \ @LIBXML2_LDFLAGS@ \ @LUA_LDFLAGS@ \ - @PCRE_LDFLAGS@ + @PCRE_LDFLAGS@ \ + @YAJL_LDFLAGS@ endif if NETBSD @@ -128,7 +137,8 @@ mod_security2_la_LDFLAGS = -no-undefined -module -avoid-version \ @APXS_LDFLAGS@ \ @LIBXML2_LDFLAGS@ \ @LUA_LDFLAGS@ \ - @PCRE_LDFLAGS@ + @PCRE_LDFLAGS@ \ + @YAJL_LDFLAGS@ endif if LINUX diff --git a/apache2/modsecurity.c b/apache2/modsecurity.c index 51341cac..1260f38c 100644 --- a/apache2/modsecurity.c +++ b/apache2/modsecurity.c @@ -256,8 +256,10 @@ static apr_status_t modsecurity_tx_cleanup(void *data) { /* XML processor cleanup. */ if (msr->xml != NULL) xml_cleanup(msr); +#ifdef WITH_YAJL /* JSON processor cleanup. */ if (msr->json != NULL) json_cleanup(msr); +#endif // TODO: Why do we ignore return code here? modsecurity_request_body_clear(msr, &my_error_msg); diff --git a/apache2/modsecurity.h b/apache2/modsecurity.h index 9ca11f2b..429806d3 100644 --- a/apache2/modsecurity.h +++ b/apache2/modsecurity.h @@ -59,7 +59,6 @@ typedef struct msc_parm msc_parm; #include "msc_lua.h" #endif - #define PHASE_REQUEST_HEADERS 1 #define PHASE_REQUEST_BODY 2 #define PHASE_RESPONSE_HEADERS 3 @@ -369,7 +368,9 @@ struct modsec_rec { multipart_data *mpd; /* MULTIPART processor data structure */ xml_data *xml; /* XML processor data structure */ +#ifdef WITH_YAJL json_data *json; /* JSON processor data structure */ +#endif /* audit logging */ char *new_auditlog_boundary; diff --git a/apache2/msc_json.c b/apache2/msc_json.c index 91763d75..db7aa207 100644 --- a/apache2/msc_json.c +++ b/apache2/msc_json.c @@ -14,6 +14,8 @@ #include "msc_json.h" +#ifdef WITH_YAJL + int json_add_argument(modsec_rec *msr, const char *value, unsigned length) { msc_arg *arg = (msc_arg *) NULL; @@ -311,3 +313,4 @@ apr_status_t json_cleanup(modsec_rec *msr) { return 1; } +#endif diff --git a/apache2/msc_json.h b/apache2/msc_json.h index 06fa6c82..91c887b3 100644 --- a/apache2/msc_json.h +++ b/apache2/msc_json.h @@ -14,11 +14,19 @@ #ifndef _MSC_JSON_H_ #define _MSC_JSON_H_ +#ifdef WITH_YAJL typedef struct json_data json_data; + #include "modsecurity.h" + #include +//#ifdef WITH_YAJL +//#else + + +#include "modsecurity.h" /* Structures */ struct json_data { @@ -46,3 +54,4 @@ int DSOLOCAL json_complete(modsec_rec *msr, char **error_msg); apr_status_t DSOLOCAL json_cleanup(modsec_rec *msr); #endif +#endif diff --git a/apache2/msc_reqbody.c b/apache2/msc_reqbody.c index 1d3f59ef..7d150eed 100644 --- a/apache2/msc_reqbody.c +++ b/apache2/msc_reqbody.c @@ -128,12 +128,19 @@ apr_status_t modsecurity_request_body_start(modsec_rec *msr, char **error_msg) { } } else if (strcmp(msr->msc_reqbody_processor, "JSON") == 0) { +#ifdef WITH_YAJL if (json_init(msr, &my_error_msg) < 0) { *error_msg = apr_psprintf(msr->mp, "JSON parsing error (init): %s", my_error_msg); msr->msc_reqbody_error = 1; msr->msc_reqbody_error_msg = my_error_msg; msr_log(msr, 2, "%s", *error_msg); } +#else + *error_msg = apr_psprintf(msr->mp, "JSON support was not enabled"); + msr->msc_reqbody_error = 1; + msr->msc_reqbody_error_msg = my_error_msg; + msr_log(msr, 2, "%s", *error_msg); +#endif } else if (strcmp(msr->msc_reqbody_processor, "URLENCODED") == 0) { /* Do nothing, URLENCODED processor does not support streaming yet. */ @@ -356,13 +363,20 @@ apr_status_t modsecurity_request_body_store(modsec_rec *msr, /* Increase per-request data length counter. */ msr->msc_reqbody_no_files_length += length; - /* Process data as XML. */ + /* Process data as JSON. */ +#ifdef WITH_YAJL if (json_process_chunk(msr, data, length, &my_error_msg) < 0) { *error_msg = apr_psprintf(msr->mp, "JSON parsing error: %s", my_error_msg); msr->msc_reqbody_error = 1; msr->msc_reqbody_error_msg = *error_msg; msr_log(msr, 2, "%s", *error_msg); } +#else + *error_msg = apr_psprintf(msr->mp, "JSON support was not enabled"); + msr->msc_reqbody_error = 1; + msr->msc_reqbody_error_msg = *error_msg; + msr_log(msr, 2, "%s", *error_msg); +#endif } else if (strcmp(msr->msc_reqbody_processor, "URLENCODED") == 0) { /* Increase per-request data length counter. */ @@ -622,6 +636,7 @@ apr_status_t modsecurity_request_body_end(modsec_rec *msr, char **error_msg) { } } else if (strcmp(msr->msc_reqbody_processor, "JSON") == 0) { +#ifdef WITH_YAJL if (json_complete(msr, &my_error_msg) < 0) { *error_msg = apr_psprintf(msr->mp, "JSON parser error: %s", my_error_msg); msr->msc_reqbody_error = 1; @@ -629,6 +644,14 @@ apr_status_t modsecurity_request_body_end(modsec_rec *msr, char **error_msg) { msr_log(msr, 2, "%s", *error_msg); return -1; } +#else + *error_msg = apr_psprintf(msr->mp, "JSON support was not enabled"); + msr->msc_reqbody_error = 1; + msr->msc_reqbody_error_msg = *error_msg; + msr_log(msr, 2, "%s", *error_msg); + return -1; +#endif + } else if (strcmp(msr->msc_reqbody_processor, "URLENCODED") == 0) { return modsecurity_request_body_end_urlencoded(msr, error_msg); diff --git a/build/find_yajl.m4 b/build/find_yajl.m4 new file mode 100644 index 00000000..05c1aa6e --- /dev/null +++ b/build/find_yajl.m4 @@ -0,0 +1,153 @@ +dnl Check for YAJL Libraries +dnl CHECK_YAJL(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]) +dnl Sets: +dnl YAJL_CFLAGS +dnl YAJL_LDADD +dnl YAJL_LDFLAGS +dnl YAJL_LIBS + +AC_DEFUN([CHECK_YAJL], +[dnl + +AC_REQUIRE([PKG_PROG_PKG_CONFIG]) + +YAJL_CONFIG="" +YAJL_VERSION="" +YAJL_CFLAGS="" +YAJL_CPPFLAGS="" +YAJL_LDADD="" +YAJL_LDFLAGS="" +YAJL_CONFIG=${PKG_CONFIG} +YAJL_PKGNAMES="yajl2 yajl" +YAJL_SONAMES="so la sl dll dylib" + +AC_ARG_WITH( + yajl, + [AC_HELP_STRING([--with-yajl=PATH],[Path to yajl prefix or config script])] + ,, with_yajl=yes) + +AS_CASE(["${with_yajl}"], + [no], [test_paths=], + [yes], [test_paths="/usr/local/libyajl /usr/local/yajl /usr/local /opt/libyajl /opt/yajl /opt /usr"], + [test_paths="${with_yajl}"]) + +AS_IF([test "x${test_paths}" != "x"], [ +AC_MSG_CHECKING([for libyajl 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 + YAJL_CONFIG=$x + break + fi + + dnl # Try known config script names/locations + for y in $YAJL_CONFIG; do + if test -e "${x}/bin/${y}"; then + YAJL_CONFIG="${x}/bin/${y}" + yajl_config="${YAJL_CONFIG}" + break + elif test -e "${x}/${y}"; then + YAJL_CONFIG="${x}/${y}" + yajl_config="${YAJL_CONFIG}" + break + fi + done + if test -n "${yajl_config}"; then + break + fi +done + +dnl # Try known package names +if test -n "${YAJL_CONFIG}"; then + YAJL_PKGNAME="" + for x in ${YAJL_PKGNAMES}; do + if ${YAJL_CONFIG} --exists ${x}; then + YAJL_PKGNAME="$x" + break + fi + done +fi + +if test -n "${YAJL_PKGNAME}"; then + AC_MSG_RESULT([${YAJL_CONFIG}]) + YAJL_VERSION="`${YAJL_CONFIG} ${YAJL_PKGNAME} --modversion`" + if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(yajl VERSION: $YAJL_VERSION); fi + YAJL_CFLAGS="`${YAJL_CONFIG} ${YAJL_PKGNAME} --cflags`" + if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(yajl CFLAGS: $YAJL_CFLAGS); fi + YAJL_LDADD="`${YAJL_CONFIG} ${YAJL_PKGNAME} --libs-only-l`" + if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(yajl LDADD: $YAJL_LDADD); fi + YAJL_LDFLAGS="`${YAJL_CONFIG} ${YAJL_PKGNAME} --libs-only-L --libs-only-other`" + if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(yajl LDFLAGS: $YAJL_LDFLAGS); fi +else + AC_MSG_RESULT([no]) + + dnl Hack to just try to find the lib and include + AC_MSG_CHECKING([for yajl install]) + for x in ${test_paths}; do + for y in ${YAJL_SONAMES}; do + if test -e "${x}/libyajl.${y}"; then + yajl_lib_path="${x}/" + yajl_lib_name="yajl" + break + else + yajl_lib_path="" + yajl_lib_name="" + fi + done + if test -n "$yajl_lib_path"; then + break + fi + done + for x in ${test_paths}; do + if test -e "${x}/include/yajl.h"; then + yajl_inc_path="${x}/include" + break + elif test -e "${x}/yajl.h"; then + yajl_inc_path="${x}" + break + fi + + dnl # Check some sub-paths as well + for yajl_pkg_name in ${yajl_lib_name} ${YAJL_PKGNAMES}; do + if test -e "${x}/include/${yajl_pkg_name}/yajl.h"; then + yajl_inc_path="${x}/include" + break + elif test -e "${x}/${yajl_pkg_name}/yajl.h"; then + yajl_inc_path="${x}" + break + else + yajl_inc_path="" + fi + done + if test -n "$yajl_inc_path"; then + break + fi + done + if test -n "${yajl_lib_path}" -a -n "${yajl_inc_path}"; then + YAJL_CONFIG="" + AC_MSG_RESULT([${yajl_lib_path} ${yajl_inc_path}]) + YAJL_VERSION="2" + YAJL_CFLAGS="-I${yajl_inc_path}" + YAJL_LDADD="-l${yajl_lib_name}" + YAJL_LDFLAGS="-L${yajl_lib_path}" + else + YAJL_VERSION="" + AC_MSG_RESULT([no]) + fi +fi + +]) + +YAJL_LIBS=${YAJL_LDADD} +AC_SUBST(YAJL_CFLAGS) +AC_SUBST(YAJL_LDADD) +AC_SUBST(YAJL_LIBS) +AC_SUBST(YAJL_LDFLAGS) + if test -z "${YAJL_VERSION}"; then + ifelse([$2], , AC_MSG_NOTICE([optional yajl library not found]), $2) + else + AC_MSG_NOTICE([using yajl v${YAJL_VERSION}]) + YAJL_CFLAGS="-DWITH_YAJL ${YAJL_CFLAGS}" + ifelse([$1], , , $1) + fi +]) diff --git a/configure.ac b/configure.ac index 175e893d..5f47ca47 100644 --- a/configure.ac +++ b/configure.ac @@ -699,7 +699,8 @@ CHECK_CURL() fi # Check for YAJL libs (for JSON body processor) -AC_SEARCH_LIBS([yajl_alloc], [yajl]) +CHECK_YAJL() +#AC_SEARCH_LIBS([yajl_alloc], [yajl]) AC_CONFIG_FILES([Makefile]) AC_CONFIG_FILES([tools/Makefile]) diff --git a/standalone/Makefile.am b/standalone/Makefile.am index c555cc2d..f801d97c 100644 --- a/standalone/Makefile.am +++ b/standalone/Makefile.am @@ -47,7 +47,8 @@ standalone_la_CFLAGS = -DVERSION_NGINX \ @LIBXML2_CFLAGS@ \ @LUA_CFLAGS@ \ @MODSEC_EXTRA_CFLAGS@ \ - @PCRE_CFLAGS@ + @PCRE_CFLAGS@ \ + @YAJL_CFLAGS@ standalone_la_CPPFLAGS = @APR_CPPFLAGS@ \ @LIBXML2_CPPFLAGS@ \ @@ -57,7 +58,8 @@ standalone_la_LIBADD = @APR_LDADD@ \ @APU_LDADD@ \ @LIBXML2_LDADD@ \ @LUA_LDADD@ \ - @PCRE_LDADD@ + @PCRE_LDADD@ \ + @YAJL_LDADD@ if AIX standalone_la_LDFLAGS = -module -avoid-version \ @@ -66,7 +68,8 @@ standalone_la_LDFLAGS = -module -avoid-version \ @APXS_LDFLAGS@ \ @LIBXML2_LDFLAGS@ \ @LUA_LDFLAGS@ \ - @PCRE_LDFLAGS@ + @PCRE_LDFLAGS@ \ + @YAJL_LDFLAGS@ endif if HPUX @@ -76,7 +79,8 @@ standalone_la_LDFLAGS = -module -avoid-version \ @APXS_LDFLAGS@ \ @LIBXML2_LDFLAGS@ \ @LUA_LDFLAGS@ \ - @PCRE_LDFLAGS@ + @PCRE_LDFLAGS@ \ + @YAJL_LDFLAGS@ endif if MACOSX @@ -86,7 +90,8 @@ standalone_la_LDFLAGS = -module -avoid-version \ @APXS_LDFLAGS@ \ @LIBXML2_LDFLAGS@ \ @LUA_LDFLAGS@ \ - @PCRE_LDFLAGS@ + @PCRE_LDFLAGS@ \ + @YAJL_LDFLAGS@ endif if SOLARIS @@ -96,7 +101,8 @@ standalone_la_LDFLAGS = -module -avoid-version \ @APXS_LDFLAGS@ \ @LIBXML2_LDFLAGS@ \ @LUA_LDFLAGS@ \ - @PCRE_LDFLAGS@ + @PCRE_LDFLAGS@ \ + @YAJL_LDFLAGS@ endif if LINUX @@ -106,7 +112,8 @@ standalone_la_LDFLAGS = -no-undefined -module -avoid-version \ @APXS_LDFLAGS@ \ @LIBXML2_LDFLAGS@ \ @LUA_LDFLAGS@ \ - @PCRE_LDFLAGS@ + @PCRE_LDFLAGS@ \ + @YAJL_LDFLAGS@ endif if FREEBSD @@ -116,7 +123,8 @@ standalone_la_LDFLAGS = -no-undefined -module -avoid-version \ @APXS_LDFLAGS@ \ @LIBXML2_LDFLAGS@ \ @LUA_LDFLAGS@ \ - @PCRE_LDFLAGS@ + @PCRE_LDFLAGS@ \ + @YAJL_LDFLAGS@ endif if OPENBSD @@ -126,7 +134,8 @@ standalone_la_LDFLAGS = -no-undefined -module -avoid-version \ @APXS_LDFLAGS@ \ @LIBXML2_LDFLAGS@ \ @LUA_LDFLAGS@ \ - @PCRE_LDFLAGS@ + @PCRE_LDFLAGS@ \ + @YAJL_LDFLAGS@ endif if NETBSD @@ -136,5 +145,6 @@ standalone_la_LDFLAGS = -no-undefined -module -avoid-version \ @APXS_LDFLAGS@ \ @LIBXML2_LDFLAGS@ \ @LUA_LDFLAGS@ \ - @PCRE_LDFLAGS@ + @PCRE_LDFLAGS@ \ + @YAJL_LDFLAGS@ endif diff --git a/tests/Makefile.am b/tests/Makefile.am index 74f8fe0d..f7f5c001 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -6,6 +6,7 @@ msc_test_SOURCES = msc_test.c \ $(top_srcdir)/apache2/msc_crypt.c \ $(top_srcdir)/apache2/msc_geo.c \ $(top_srcdir)/apache2/msc_gsb.c \ + $(top_srcdir)/apache2/msc_json.c \ $(top_srcdir)/apache2/msc_logging.c \ $(top_srcdir)/apache2/msc_lua.c \ $(top_srcdir)/apache2/msc_multipart.c \ @@ -32,7 +33,8 @@ msc_test_CFLAGS = @APR_CFLAGS@ \ @LIBXML2_CFLAGS@ \ @LUA_CFLAGS@ \ @MODSEC_EXTRA_CFLAGS@ \ - @PCRE_CFLAGS@ + @PCRE_CFLAGS@ \ + @YAJL_CFLAGS@ msc_test_CPPFLAGS = -I$(top_srcdir)/apache2 \ @APR_CPPFLAGS@ \ @@ -43,14 +45,16 @@ msc_test_LDADD = @APR_LDADD@ \ @APU_LDADD@ \ @LIBXML2_LDADD@ \ @LUA_LDADD@ \ - @PCRE_LDADD@ + @PCRE_LDADD@ \ + @YAJL_LDADD@ msc_test_LDFLAGS = @APR_LDFLAGS@ \ @APU_LDFLAGS@ \ @APXS_LDFLAGS@ \ @LIBXML2_LDFLAGS@ \ @LUA_LDFLAGS@ \ - @PCRE_LDFLAGS@ + @PCRE_LDFLAGS@ \ + @YAJL_LDFLAGS@ check_SCRIPTS = run-unit-tests.pl TESTS = $(check_SCRIPTS)