mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-14 13:56:01 +03:00
commit
f31724e20f
29
CHANGES
29
CHANGES
@ -1,3 +1,28 @@
|
||||
10 May 2013 - 2.7.4
|
||||
-------------------
|
||||
Improvements:
|
||||
|
||||
* Added Libinjection project http://www.client9.com/projects/libinjection/ as a new operator @detectSQLi. (Thanks Nick Galbreath).
|
||||
|
||||
* Added new variable SDBM_DELETE_ERROR that will be set to 1 when sdbm engine fails to delete entries.
|
||||
|
||||
* Nginx module is set as STABLE.
|
||||
|
||||
Bug Fixes:
|
||||
|
||||
* Fixed SecRulePerfTime storing unnecessary rules performance times.
|
||||
|
||||
* Fixed Possible SDBM deadlock condition.
|
||||
|
||||
* Fixed Possible @rsub memory leak.
|
||||
|
||||
* Fixed REMOTE_ADDR content will receive the client ip address when mod_remoteip.c is present.
|
||||
|
||||
Security Issues:
|
||||
|
||||
* Fixed Remote Null Pointer DeReference (CVE-2013-2765). When forceRequestBodyVariable action is triggered and a unknown Content-Type is used,
|
||||
mod_security will crash trying to manipulate msr->msc_reqbody_chunks->elts however msr->msc_reqbody_chunks is NULL. (Thanks Younes JAAIDI).
|
||||
|
||||
28 Mar 2013 - 2.7.3
|
||||
-------------------
|
||||
|
||||
@ -32,7 +57,7 @@
|
||||
|
||||
* SECURITY: Added SecXmlExternalEntity (On|Off - default it Off) that will disable
|
||||
by default the external entity load task executed by LibXml2. This is a security issue
|
||||
reported by Timur Yunusov, Alexey Osipov (Positive Technologies).
|
||||
[CVE-2013-1915] reported by Timur Yunusov, Alexey Osipov (Positive Technologies).
|
||||
|
||||
21 Jan 2013 - 2.7.2
|
||||
-------------------
|
||||
@ -130,7 +155,7 @@
|
||||
support Include directive like Apache2.
|
||||
|
||||
* Added MULTIPART_INVALID_PART flag. Also used in rule id 200002 for multipart strict
|
||||
validation.
|
||||
validation. https://www.sec-consult.com/fxdata/seccons/prod/temedia/advisories_txt/20121017-0_mod_security_ruleset_bypass.txt).
|
||||
|
||||
* Updated Reference Manual.
|
||||
|
||||
|
2
NOTICE
2
NOTICE
@ -1,5 +1,5 @@
|
||||
ModSecurity (www.modsecurity.org)
|
||||
Copyright [2004-2011] Trustwave Holdings, Inc
|
||||
Copyright [2004-2013] Trustwave Holdings, Inc
|
||||
|
||||
This product includes software developed at
|
||||
Trustwave Holdings, Inc (http://www.trustwave.com/).
|
||||
|
@ -1,5 +1,5 @@
|
||||
ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
|
||||
You may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -11,7 +11,7 @@ mod_security2_la_SOURCES = mod_security2.c \
|
||||
re_variables.c msc_logging.c msc_xml.c \
|
||||
msc_multipart.c modsecurity.c msc_parsers.c \
|
||||
msc_util.c msc_pcre.c persist_dbm.c msc_reqbody.c \
|
||||
msc_geo.c msc_gsb.c msc_crypt.c msc_tree.c msc_unicode.c acmp.c msc_lua.c msc_release.c
|
||||
msc_geo.c msc_gsb.c msc_crypt.c msc_tree.c msc_unicode.c acmp.c msc_lua.c msc_release.c libinjection/sqlparse.c
|
||||
|
||||
mod_security2_la_CFLAGS = @APXS_CFLAGS@ @APR_CFLAGS@ @APU_CFLAGS@ \
|
||||
@PCRE_CFLAGS@ @LIBXML2_CFLAGS@ @LUA_CFLAGS@ @MODSEC_EXTRA_CFLAGS@ @CURL_CFLAGS@
|
||||
|
@ -46,7 +46,7 @@ OBJS = mod_security2.obj apache2_config.obj apache2_io.obj apache2_util.obj \
|
||||
msc_logging.obj msc_xml.obj msc_multipart.obj modsecurity.obj \
|
||||
msc_parsers.obj msc_util.obj msc_pcre.obj persist_dbm.obj \
|
||||
msc_reqbody.obj msc_geo.obj msc_gsb.obj msc_crypt.obj msc_tree.obj msc_unicode.obj acmp.obj msc_lua.obj \
|
||||
msc_release.obj
|
||||
msc_release.obj libinjection\sqlparse.obj
|
||||
|
||||
all: $(DLL)
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
@ -2346,7 +2346,7 @@ static const char *cmd_hash_engine(cmd_parms *cmd, void *_dcfg, const char *p1)
|
||||
dcfg->hash_is_enabled = HASH_DISABLED;
|
||||
dcfg->hash_enforcement = HASH_DISABLED;
|
||||
}
|
||||
else return apr_psprintf(cmd->pool, "ModSecurity: Invalid value for SexHashEngine: %s", p1);
|
||||
else return apr_psprintf(cmd->pool, "ModSecurity: Invalid value for SecHashEngine: %s", p1);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
@ -198,6 +198,10 @@ static void internal_log_ex(request_rec *r, directory_config *dcfg, modsec_rec *
|
||||
apr_size_t nbytes, nbytes_written;
|
||||
apr_file_t *debuglog_fd = NULL;
|
||||
int filter_debug_level = 0;
|
||||
char *remote = NULL;
|
||||
char *parse_remote = NULL;
|
||||
char *saved = NULL;
|
||||
char *str = NULL;
|
||||
char str1[1024] = "";
|
||||
char str2[1256] = "";
|
||||
|
||||
@ -269,8 +273,8 @@ static void internal_log_ex(request_rec *r, directory_config *dcfg, modsec_rec *
|
||||
hostname, log_escape(msr->mp, r->uri), unique_id);
|
||||
#else
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r->server,
|
||||
"[client %s] ModSecurity: %s%s [uri \"%s\"]%s", r->connection->remote_ip, str1,
|
||||
hostname, log_escape(msr->mp, r->uri), unique_id);
|
||||
"[client %s] ModSecurity: %s%s [uri \"%s\"]%s", msr->remote_addr ? msr->remote_addr : r->connection->remote_ip, str1,
|
||||
hostname, log_escape(msr->mp, r->uri), unique_id);
|
||||
#endif
|
||||
|
||||
/* Add this message to the list. */
|
||||
|
37
apache2/libinjection/COPYING.txt
Normal file
37
apache2/libinjection/COPYING.txt
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2012, 2013
|
||||
* Nick Galbreath -- nickg [at] client9 [dot] com
|
||||
* http://www.client9.com/projects/libinjection/
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of libinjection nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This is the standard "new" BSD license:
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
*/
|
2327
apache2/libinjection/sqli_fingerprints.h
Normal file
2327
apache2/libinjection/sqli_fingerprints.h
Normal file
File diff suppressed because it is too large
Load Diff
1340
apache2/libinjection/sqlparse.c
Normal file
1340
apache2/libinjection/sqlparse.c
Normal file
File diff suppressed because it is too large
Load Diff
113
apache2/libinjection/sqlparse.h
Normal file
113
apache2/libinjection/sqlparse.h
Normal file
@ -0,0 +1,113 @@
|
||||
/**
|
||||
* Copyright 2012, 2013 Nick Galbreath
|
||||
* nickg@client9.com
|
||||
* BSD License -- see COPYING.txt for details
|
||||
*
|
||||
*
|
||||
* HOW TO USE:
|
||||
*
|
||||
* // Normalize query or postvar value
|
||||
* // If it comes in urlencoded, then it's up to you
|
||||
* // to urldecode it. If it's in correct form already
|
||||
* // then nothing to do!
|
||||
*
|
||||
* sfilter s;
|
||||
* int sqli = is_sqli(&s, user_string, new_len);
|
||||
*
|
||||
* // 0 = not sqli
|
||||
* // 1 = is sqli
|
||||
*
|
||||
* // That's it! sfilter s has some data on how it matched or not
|
||||
* // details to come!
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _SQLPARSE_H
|
||||
#define _SQLPARSE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Version info.
|
||||
* See python's normalized version
|
||||
* http://www.python.org/dev/peps/pep-0386/#normalizedversion
|
||||
*/
|
||||
#define LIBINJECTION_VERSION "1.2.0"
|
||||
|
||||
#define ST_MAX_SIZE 32
|
||||
#define MAX_TOKENS 5
|
||||
|
||||
#define CHAR_NULL '\0'
|
||||
#define CHAR_SINGLE '\''
|
||||
#define CHAR_DOUBLE '"'
|
||||
|
||||
typedef struct {
|
||||
char type;
|
||||
char str_open;
|
||||
char str_close;
|
||||
char val[ST_MAX_SIZE];
|
||||
} stoken_t;
|
||||
|
||||
typedef struct {
|
||||
/* input */
|
||||
const char *s;
|
||||
size_t slen;
|
||||
|
||||
/* current tokenize state */
|
||||
size_t pos;
|
||||
int in_comment;
|
||||
|
||||
/* syntax fixups state */
|
||||
stoken_t syntax_current;
|
||||
stoken_t syntax_last;
|
||||
stoken_t syntax_comment;
|
||||
|
||||
/* constant folding state */
|
||||
stoken_t fold_current;
|
||||
stoken_t fold_last;
|
||||
int fold_state;
|
||||
|
||||
/* final sqli data */
|
||||
stoken_t tokenvec[MAX_TOKENS];
|
||||
|
||||
/* +1 for ending null */
|
||||
char pat[MAX_TOKENS + 1];
|
||||
char delim;
|
||||
int reason;
|
||||
} sfilter;
|
||||
|
||||
/**
|
||||
* Pointer to function, takes cstr input, return true/false
|
||||
*/
|
||||
typedef int (*ptr_fingerprints_fn)(const char*);
|
||||
|
||||
/**
|
||||
* Main API: tests for SQLi in three possible contexts, no quotes,
|
||||
* single quote and double quote
|
||||
*
|
||||
* \return 1 (true) if SQLi, 0 (false) if benign
|
||||
*/
|
||||
int is_sqli(sfilter * sql_state, const char *s, size_t slen,
|
||||
ptr_fingerprints_fn fn);
|
||||
|
||||
/**
|
||||
* This detects SQLi in a single context, mostly useful for custom
|
||||
* logic and debugging.
|
||||
*
|
||||
* \param delim must be "NULL" (no context), single quote or double quote.
|
||||
* Other values will likely be ignored.
|
||||
*
|
||||
* \return 1 (true) if SQLi, 0 (false) if not SQLi **in this context**
|
||||
*
|
||||
*/
|
||||
int is_string_sqli(sfilter * sql_state, const char *s, size_t slen,
|
||||
const char delim,
|
||||
ptr_fingerprints_fn fn);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SQLPARSE_H */
|
983
apache2/libinjection/sqlparse_data.h
Normal file
983
apache2/libinjection/sqlparse_data.h
Normal file
@ -0,0 +1,983 @@
|
||||
#ifndef _SQLPARSE_DATA_H
|
||||
#define _SQLPARSE_DATA_H
|
||||
#include "sqlparse.h"
|
||||
|
||||
static const char* operators2[] = {
|
||||
"!!",
|
||||
"!<",
|
||||
"!=",
|
||||
"!>",
|
||||
"!~",
|
||||
"%=",
|
||||
"&&",
|
||||
"&=",
|
||||
"*=",
|
||||
"+=",
|
||||
"-=",
|
||||
"/=",
|
||||
":=",
|
||||
"<<",
|
||||
"<=",
|
||||
"<>",
|
||||
"<@",
|
||||
">=",
|
||||
">>",
|
||||
"@>",
|
||||
"^=",
|
||||
"|/",
|
||||
"|=",
|
||||
"||",
|
||||
"~*",
|
||||
};
|
||||
static const size_t operators2_sz = 25;
|
||||
|
||||
static const keyword_t sql_keywords[] = {
|
||||
{"ABS", 'f'},
|
||||
{"ACCESSIBLE", 'k'},
|
||||
{"ACOS", 'f'},
|
||||
{"ADD", 'k'},
|
||||
{"ADDDATE", 'f'},
|
||||
{"ADDTIME", 'f'},
|
||||
{"AES_DECRYPT", 'f'},
|
||||
{"AES_ENCRYPT", 'f'},
|
||||
{"AGAINST", 'k'},
|
||||
{"AGE", 'f'},
|
||||
{"ALL_USERS", 'k'},
|
||||
{"ALTER", 'k'},
|
||||
{"ANALYZE", 'k'},
|
||||
{"AND", '&'},
|
||||
{"APPLOCK_MODE", 'f'},
|
||||
{"APPLOCK_TEST", 'f'},
|
||||
{"APP_NAME", 'f'},
|
||||
{"ARRAY_AGG", 'f'},
|
||||
{"ARRAY_CAT", 'f'},
|
||||
{"ARRAY_DIM", 'f'},
|
||||
{"ARRAY_FILL", 'f'},
|
||||
{"ARRAY_LENGTH", 'f'},
|
||||
{"ARRAY_LOWER", 'f'},
|
||||
{"ARRAY_NDIMS", 'f'},
|
||||
{"ARRAY_PREPEND", 'f'},
|
||||
{"ARRAY_TO_JSON", 'f'},
|
||||
{"ARRAY_TO_STRING", 'f'},
|
||||
{"ARRAY_UPPER", 'f'},
|
||||
{"AS", 'k'},
|
||||
{"ASC", 'k'},
|
||||
{"ASCII", 'f'},
|
||||
{"ASENSITIVE", 'k'},
|
||||
{"ASIN", 'f'},
|
||||
{"ASSEMBLYPROPERTY", 'f'},
|
||||
{"ASYMKEY_ID", 'f'},
|
||||
{"ATAN", 'f'},
|
||||
{"ATAN2", 'f'},
|
||||
{"AVG", 'f'},
|
||||
{"BEFORE", 'k'},
|
||||
{"BEGIN", 'k'},
|
||||
{"BENCHMARK", 'f'},
|
||||
{"BETWEEN", 'k'},
|
||||
{"BIGINT", 'k'},
|
||||
{"BIN", 'f'},
|
||||
{"BINARY", 'k'},
|
||||
{"BINARY_DOUBLE_INFINITY", '1'},
|
||||
{"BINARY_DOUBLE_NAN", '1'},
|
||||
{"BINARY_FLOAT_INFINITY", '1'},
|
||||
{"BINARY_FLOAT_NAN", '1'},
|
||||
{"BINBINARY", 'f'},
|
||||
{"BIT_AND", 'f'},
|
||||
{"BIT_COUNT", 'f'},
|
||||
{"BIT_LENGTH", 'f'},
|
||||
{"BIT_OR", 'f'},
|
||||
{"BIT_XOR", 'f'},
|
||||
{"BLOB", 'k'},
|
||||
{"BOOLEAN", 'k'},
|
||||
{"BOOL_AND", 'f'},
|
||||
{"BOOL_OR", 'f'},
|
||||
{"BOTH", 'k'},
|
||||
{"BTRIM", 'f'},
|
||||
{"BY", 'n'},
|
||||
{"CALL", 'k'},
|
||||
{"CASCADE", 'k'},
|
||||
{"CASE", 'o'},
|
||||
{"CAST", 'f'},
|
||||
{"CBOOL", 'f'},
|
||||
{"CBRT", 'f'},
|
||||
{"CBYTE", 'f'},
|
||||
{"CCUR", 'f'},
|
||||
{"CDATE", 'f'},
|
||||
{"CDBL", 'f'},
|
||||
{"CEIL", 'f'},
|
||||
{"CEILING", 'f'},
|
||||
{"CERTENCODED", 'f'},
|
||||
{"CERTPRIVATEKEY", 'f'},
|
||||
{"CERT_ID", 'f'},
|
||||
{"CERT_PROPERTY", 'f'},
|
||||
{"CHANGE", 'k'},
|
||||
{"CHAR", 'f'},
|
||||
{"CHARACTER", 'k'},
|
||||
{"CHARACTER_LENGTH", 'f'},
|
||||
{"CHARINDEX", 'f'},
|
||||
{"CHARSET", 'f'},
|
||||
{"CHAR_LENGTH", 'f'},
|
||||
{"CHDIR", 'f'},
|
||||
{"CHDRIVE", 'f'},
|
||||
{"CHECK", 'k'},
|
||||
{"CHECKSUM_AGG", 'f'},
|
||||
{"CHOOSE", 'f'},
|
||||
{"CHR", 'f'},
|
||||
{"CINT", 'f'},
|
||||
{"CLNG", 'f'},
|
||||
{"CLOCK_TIMESTAMP", 'f'},
|
||||
{"COALESCE", 'k'},
|
||||
{"COERCIBILITY", 'f'},
|
||||
{"COLLATE", 'k'},
|
||||
{"COLLATION", 'f'},
|
||||
{"COLLATIONPROPERTY", 'f'},
|
||||
{"COLUMN", 'k'},
|
||||
{"COLUMNPROPERTY", 'f'},
|
||||
{"COLUMNS_UPDATED", 'f'},
|
||||
{"COL_LENGTH", 'f'},
|
||||
{"COL_NAME", 'f'},
|
||||
{"COMPRESS", 'f'},
|
||||
{"CONCAT", 'f'},
|
||||
{"CONCAT_WS", 'f'},
|
||||
{"CONDITION", 'k'},
|
||||
{"CONNECTION_ID", 'f'},
|
||||
{"CONSTRAINT", 'k'},
|
||||
{"CONTINUE", 'k'},
|
||||
{"CONV", 'f'},
|
||||
{"CONVERT", 'f'},
|
||||
{"CONVERT_FROM", 'f'},
|
||||
{"CONVERT_TO", 'f'},
|
||||
{"CONVERT_TZ", 'f'},
|
||||
{"COS", 'f'},
|
||||
{"COT", 'f'},
|
||||
{"COUNT", 'f'},
|
||||
{"COUNT_BIG", 'k'},
|
||||
{"CRC32", 'f'},
|
||||
{"CREATE", 'k'},
|
||||
{"CSNG", 'f'},
|
||||
{"CTXSYS.DRITHSX.SN", 'f'},
|
||||
{"CUME_DIST", 'f'},
|
||||
{"CURDATE", 'f'},
|
||||
{"CURDIR", 'f'},
|
||||
{"CURRENTUSER", 'f'},
|
||||
{"CURRENT_DATABASE", 'f'},
|
||||
{"CURRENT_DATE", 'k'},
|
||||
{"CURRENT_QUERY", 'f'},
|
||||
{"CURRENT_SCHEMA", 'f'},
|
||||
{"CURRENT_SCHEMAS", 'f'},
|
||||
{"CURRENT_SETTING", 'p'},
|
||||
{"CURRENT_TIME", 'k'},
|
||||
{"CURRENT_TIMESTAMP", 'k'},
|
||||
{"CURRENT_USER", 'k'},
|
||||
{"CURRVAL", 'f'},
|
||||
{"CURSOR", 'k'},
|
||||
{"CURSOR_STATUS", 'f'},
|
||||
{"CURTIME", 'f'},
|
||||
{"CVAR", 'f'},
|
||||
{"DATABASE", 'k'},
|
||||
{"DATABASEPROPERTYEX", 'f'},
|
||||
{"DATABASES", 'k'},
|
||||
{"DATABASE_PRINCIPAL_ID", 'f'},
|
||||
{"DATALENGTH", 'f'},
|
||||
{"DATE", 'f'},
|
||||
{"DATEADD", 'f'},
|
||||
{"DATEDIFF", 'f'},
|
||||
{"DATEFROMPARTS", 'f'},
|
||||
{"DATENAME", 'f'},
|
||||
{"DATEPART", 'f'},
|
||||
{"DATESERIAL", 'f'},
|
||||
{"DATETIME2FROMPARTS", 'f'},
|
||||
{"DATETIMEFROMPARTS", 'f'},
|
||||
{"DATETIMEOFFSETFROMPARTS", 'f'},
|
||||
{"DATEVALUE", 'f'},
|
||||
{"DATE_ADD", 'f'},
|
||||
{"DATE_FORMAT", 'f'},
|
||||
{"DATE_PART", 'f'},
|
||||
{"DATE_SUB", 'f'},
|
||||
{"DATE_TRUNC", 'f'},
|
||||
{"DAVG", 'f'},
|
||||
{"DAY", 'f'},
|
||||
{"DAYNAME", 'f'},
|
||||
{"DAYOFMONTH", 'f'},
|
||||
{"DAYOFWEEK", 'f'},
|
||||
{"DAYOFYEAR", 'f'},
|
||||
{"DAY_HOUR", 'k'},
|
||||
{"DAY_MICROSECOND", 'k'},
|
||||
{"DAY_MINUTE", 'k'},
|
||||
{"DAY_SECOND", 'k'},
|
||||
{"DBMS_PIPE.RECEIVE_MESSAGE", 'f'},
|
||||
{"DB_ID", 'f'},
|
||||
{"DB_NAME", 'f'},
|
||||
{"DCOUNT", 'f'},
|
||||
{"DEC", 'k'},
|
||||
{"DECIMAL", 'k'},
|
||||
{"DECLARE", 'k'},
|
||||
{"DECODE", 'f'},
|
||||
{"DECRYPTBYASMKEY", 'f'},
|
||||
{"DECRYPTBYCERT", 'f'},
|
||||
{"DECRYPTBYKEY", 'f'},
|
||||
{"DECRYPTBYKEYAUTOCERT", 'f'},
|
||||
{"DECRYPTBYPASSPHRASE", 'f'},
|
||||
{"DEFAULT", 'k'},
|
||||
{"DEGREES", 'f'},
|
||||
{"DELAY", 'k'},
|
||||
{"DELAYED", 'k'},
|
||||
{"DELETE", 'k'},
|
||||
{"DENSE_RANK", 'f'},
|
||||
{"DESC", 'k'},
|
||||
{"DESCRIBE", 'k'},
|
||||
{"DES_DECRYPT", 'f'},
|
||||
{"DES_ENCRYPT", 'f'},
|
||||
{"DETERMINISTIC", 'k'},
|
||||
{"DFIRST", 'f'},
|
||||
{"DIFFERENCE", 'f'},
|
||||
{"DISTINCROW", 'k'},
|
||||
{"DISTINCT", 'k'},
|
||||
{"DIV", 'o'},
|
||||
{"DLAST", 'f'},
|
||||
{"DLOOKUP", 'f'},
|
||||
{"DMAX", 'f'},
|
||||
{"DMIN", 'f'},
|
||||
{"DROP", 'k'},
|
||||
{"DSUM", 'f'},
|
||||
{"DUAL", 'k'},
|
||||
{"EACH", 'k'},
|
||||
{"ELSE", 'k'},
|
||||
{"ELSEIF", 'k'},
|
||||
{"ELT", 'f'},
|
||||
{"ENCLOSED", 'k'},
|
||||
{"ENCODE", 'f'},
|
||||
{"ENCRYPT", 'f'},
|
||||
{"ENCRYPTBYASMKEY", 'f'},
|
||||
{"ENCRYPTBYCERT", 'f'},
|
||||
{"ENCRYPTBYKEY", 'f'},
|
||||
{"ENCRYPTBYPASSPHRASE", 'f'},
|
||||
{"ENUM_FIRST", 'f'},
|
||||
{"ENUM_LAST", 'f'},
|
||||
{"ENUM_RANGE", 'f'},
|
||||
{"EOMONTH", 'f'},
|
||||
{"ESCAPED", 'k'},
|
||||
{"EVENTDATA", 'f'},
|
||||
{"EXEC", 'k'},
|
||||
{"EXECUTE", 'k'},
|
||||
{"EXISTS", 'k'},
|
||||
{"EXIT", 'k'},
|
||||
{"EXP", 'f'},
|
||||
{"EXPLAIN", 'k'},
|
||||
{"EXPORT_SET", 'f'},
|
||||
{"EXTRACT", 'f'},
|
||||
{"EXTRACTVALUE", 'f'},
|
||||
{"EXTRACT_VALUE", 'f'},
|
||||
{"FALSE", '1'},
|
||||
{"FETCH", 'k'},
|
||||
{"FIELD", 'f'},
|
||||
{"FILEDATETIME", 'f'},
|
||||
{"FILEGROUPPROPERTY", 'f'},
|
||||
{"FILEGROUP_ID", 'f'},
|
||||
{"FILEGROUP_NAME", 'f'},
|
||||
{"FILELEN", 'f'},
|
||||
{"FILEPROPERTY", 'f'},
|
||||
{"FILE_ID", 'f'},
|
||||
{"FILE_IDEX", 'f'},
|
||||
{"FILE_NAME", 'f'},
|
||||
{"FIND_IN_SET", 'f'},
|
||||
{"FIRST_VALUE", 'f'},
|
||||
{"FLOOR", 'f'},
|
||||
{"FN_VIRTUALFILESTATS", 'f'},
|
||||
{"FOR", 'n'},
|
||||
{"FORCE", 'k'},
|
||||
{"FOREIGN", 'k'},
|
||||
{"FORMAT", 'f'},
|
||||
{"FOUND_ROWS", 'f'},
|
||||
{"FROM", 'k'},
|
||||
{"FROM_DAYS", 'f'},
|
||||
{"FROM_UNIXTIME", 'f'},
|
||||
{"FULLTEXT", 'k'},
|
||||
{"FULLTEXTCATALOGPROPERTY", 'f'},
|
||||
{"FULLTEXTSERVICEPROPERTY", 'f'},
|
||||
{"GENERATE_SERIES", 'f'},
|
||||
{"GENERATE_SUBSCRIPTS", 'f'},
|
||||
{"GETATTR", 'f'},
|
||||
{"GETDATE", 'f'},
|
||||
{"GETUTCDATE", 'f'},
|
||||
{"GET_BIT", 'f'},
|
||||
{"GET_BYTE", 'f'},
|
||||
{"GET_FORMAT", 'f'},
|
||||
{"GET_LOCK", 'f'},
|
||||
{"GOTO", 'k'},
|
||||
{"GRANT", 'k'},
|
||||
{"GREATEST", 'f'},
|
||||
{"GROUP", 'n'},
|
||||
{"GROUPING", 'f'},
|
||||
{"GROUPING_ID", 'f'},
|
||||
{"GROUP_CONCAT", 'f'},
|
||||
{"HASHBYTES", 'f'},
|
||||
{"HAS_PERMS_BY_NAME", 'f'},
|
||||
{"HAVING", 'k'},
|
||||
{"HEX", 'f'},
|
||||
{"HIGH_PRIORITY", 'k'},
|
||||
{"HOST_NAME", 'f'},
|
||||
{"HOUR", 'f'},
|
||||
{"HOUR_MICROSECOND", 'k'},
|
||||
{"HOUR_MINUTE", 'k'},
|
||||
{"HOUR_SECOND", 'k'},
|
||||
{"IDENTIFY", 'f'},
|
||||
{"IDENT_CURRENT", 'f'},
|
||||
{"IDENT_INCR", 'f'},
|
||||
{"IDENT_SEED", 'f'},
|
||||
{"IF", 'k'},
|
||||
{"IFF", 'f'},
|
||||
{"IFNULL", 'f'},
|
||||
{"IGNORE", 'k'},
|
||||
{"IIF", 'f'},
|
||||
{"IN", 'n'},
|
||||
{"INDEX", 'k'},
|
||||
{"INDEXKEY_PROPERTY", 'f'},
|
||||
{"INDEXPROPERTY", 'f'},
|
||||
{"INDEX_COL", 'f'},
|
||||
{"INET_ATON", 'f'},
|
||||
{"INET_NTOA", 'f'},
|
||||
{"INFILE", 'k'},
|
||||
{"INITCAP", 'f'},
|
||||
{"INNER", 'k'},
|
||||
{"INOUT", 'k'},
|
||||
{"INSENSITIVE", 'k'},
|
||||
{"INSERT", 'k'},
|
||||
{"INSTR", 'f'},
|
||||
{"INSTRREV", 'f'},
|
||||
{"INT", 'k'},
|
||||
{"INT1", 'k'},
|
||||
{"INT2", 'k'},
|
||||
{"INT3", 'k'},
|
||||
{"INT4", 'k'},
|
||||
{"INT8", 'k'},
|
||||
{"INTEGER", 'k'},
|
||||
{"INTERVAL", 'k'},
|
||||
{"INTO", 'k'},
|
||||
{"IS", 'o'},
|
||||
{"ISDATE", 'f'},
|
||||
{"ISEMPTY", 'f'},
|
||||
{"ISFINITE", 'f'},
|
||||
{"ISNULL", 'f'},
|
||||
{"ISNUMERIC", 'f'},
|
||||
{"IS_FREE_LOCK", 'f'},
|
||||
{"IS_MEMBER", 'f'},
|
||||
{"IS_OBJECTSIGNED", 'f'},
|
||||
{"IS_ROLEMEMBER", 'f'},
|
||||
{"IS_SRVROLEMEMBER", 'f'},
|
||||
{"IS_USED_LOCK", 'f'},
|
||||
{"ITERATE", 'k'},
|
||||
{"JOIN", 'k'},
|
||||
{"JUSTIFY_DAYS", 'f'},
|
||||
{"JUSTIFY_HOURS", 'f'},
|
||||
{"JUSTIFY_INTERVAL", 'f'},
|
||||
{"KEYS", 'k'},
|
||||
{"KEY_GUID", 'f'},
|
||||
{"KEY_ID", 'f'},
|
||||
{"KILL", 'k'},
|
||||
{"LAG", 'f'},
|
||||
{"LASTVAL", 'f'},
|
||||
{"LAST_INSERT_ID", 'f'},
|
||||
{"LAST_VALUE", 'f'},
|
||||
{"LCASE", 'f'},
|
||||
{"LEAD", 'f'},
|
||||
{"LEADING", 'k'},
|
||||
{"LEAST", 'f'},
|
||||
{"LEAVE", 'k'},
|
||||
{"LEFT", 'n'},
|
||||
{"LENGTH", 'f'},
|
||||
{"LIKE", 'o'},
|
||||
{"LIMIT", 'k'},
|
||||
{"LINEAR", 'k'},
|
||||
{"LINES", 'k'},
|
||||
{"LN", 'f'},
|
||||
{"LOAD", 'k'},
|
||||
{"LOAD_FILE", 'f'},
|
||||
{"LOCALTIME", 'k'},
|
||||
{"LOCALTIMESTAMP", 'k'},
|
||||
{"LOCATE", 'f'},
|
||||
{"LOCK", 'n'},
|
||||
{"LOG", 'f'},
|
||||
{"LOG10", 'f'},
|
||||
{"LOG2", 'f'},
|
||||
{"LONGBLOB", 'k'},
|
||||
{"LONGTEXT", 'k'},
|
||||
{"LOOP", 'k'},
|
||||
{"LOWER", 'f'},
|
||||
{"LOWER_INC", 'f'},
|
||||
{"LOWER_INF", 'f'},
|
||||
{"LOW_PRIORITY", 'k'},
|
||||
{"LPAD", 'f'},
|
||||
{"LTRIM", 'f'},
|
||||
{"MAKEDATE", 'f'},
|
||||
{"MAKE_SET", 'f'},
|
||||
{"MASKLEN", 'f'},
|
||||
{"MASTER_BIND", 'k'},
|
||||
{"MASTER_POS_WAIT", 'f'},
|
||||
{"MASTER_SSL_VERIFY_SERVER_CERT", 'k'},
|
||||
{"MATCH", 'k'},
|
||||
{"MAX", 'f'},
|
||||
{"MAXVALUE", 'k'},
|
||||
{"MD5", 'f'},
|
||||
{"MEDIUMBLOB", 'k'},
|
||||
{"MEDIUMINT", 'k'},
|
||||
{"MEDIUMTEXT", 'k'},
|
||||
{"MERGE", 'k'},
|
||||
{"MICROSECOND", 'f'},
|
||||
{"MID", 'f'},
|
||||
{"MIDDLEINT", 'k'},
|
||||
{"MIN", 'f'},
|
||||
{"MINUTE", 'f'},
|
||||
{"MINUTE_MICROSECOND", 'k'},
|
||||
{"MINUTE_SECOND", 'k'},
|
||||
{"MKDIR", 'f'},
|
||||
{"MOD", 'o'},
|
||||
{"MODE", 'n'},
|
||||
{"MODIFIES", 'k'},
|
||||
{"MONTH", 'f'},
|
||||
{"MONTHNAME", 'f'},
|
||||
{"NAME_CONST", 'f'},
|
||||
{"NETMASK", 'f'},
|
||||
{"NEXTVAL", 'f'},
|
||||
{"NOT", 'o'},
|
||||
{"NOW", 'f'},
|
||||
{"NO_WRITE_TO_BINLOG", 'k'},
|
||||
{"NTH_VALUE", 'f'},
|
||||
{"NTILE", 'f'},
|
||||
{"NULL", '1'},
|
||||
{"NULLIF", 'f'},
|
||||
{"NUMERIC", 'k'},
|
||||
{"NZ", 'f'},
|
||||
{"OBJECTPROPERTY", 'f'},
|
||||
{"OBJECTPROPERTYEX", 'f'},
|
||||
{"OBJECT_DEFINITION", 'f'},
|
||||
{"OBJECT_ID", 'f'},
|
||||
{"OBJECT_NAME", 'f'},
|
||||
{"OBJECT_SCHEMA_NAME", 'f'},
|
||||
{"OCT", 'f'},
|
||||
{"OCTET_LENGTH", 'f'},
|
||||
{"OFFSET", 'k'},
|
||||
{"OLD_PASSWORD", 'f'},
|
||||
{"ONE_SHOT", 'k'},
|
||||
{"OPEN", 'k'},
|
||||
{"OPENDATASOURCE", 'f'},
|
||||
{"OPENQUERY", 'f'},
|
||||
{"OPENROWSET", 'f'},
|
||||
{"OPENXML", 'f'},
|
||||
{"OPTIMIZE", 'k'},
|
||||
{"OPTION", 'k'},
|
||||
{"OPTIONALLY", 'k'},
|
||||
{"OR", '&'},
|
||||
{"ORD", 'f'},
|
||||
{"ORDER", 'n'},
|
||||
{"ORIGINAL_DB_NAME", 'f'},
|
||||
{"ORIGINAL_LOGIN", 'f'},
|
||||
{"OUT", 'k'},
|
||||
{"OUTFILE", 'k'},
|
||||
{"OVERLAPS", 'f'},
|
||||
{"OVERLAY", 'f'},
|
||||
{"OWN3D", 'k'},
|
||||
{"PARSENAME", 'f'},
|
||||
{"PARTITION", 'k'},
|
||||
{"PASSWORD", 'k'},
|
||||
{"PATHINDEX", 'f'},
|
||||
{"PATINDEX", 'f'},
|
||||
{"PERCENTILE_COUNT", 'f'},
|
||||
{"PERCENTILE_DISC", 'f'},
|
||||
{"PERCENTILE_RANK", 'f'},
|
||||
{"PERCENT_RANK", 'f'},
|
||||
{"PERIOD_ADD", 'f'},
|
||||
{"PERIOD_DIFF", 'f'},
|
||||
{"PERMISSIONS", 'f'},
|
||||
{"PG_ADVISORY_LOCK", 'f'},
|
||||
{"PG_BACKEND_PID", 'f'},
|
||||
{"PG_CANCEL_BACKEND", 'f'},
|
||||
{"PG_CLIENT_ENCODING", 'f'},
|
||||
{"PG_CONF_LOAD_TIME", 'f'},
|
||||
{"PG_CREATE_RESTORE_POINT", 'f'},
|
||||
{"PG_HAS_ROLE", 'f'},
|
||||
{"PG_IS_IN_RECOVERY", 'f'},
|
||||
{"PG_IS_OTHER_TEMP_SCHEMA", 'f'},
|
||||
{"PG_LISTENING_CHANNELS", 'f'},
|
||||
{"PG_LS_DIR", 'f'},
|
||||
{"PG_MY_TEMP_SCHEMA", 'f'},
|
||||
{"PG_POSTMASTER_START_TIME", 'f'},
|
||||
{"PG_READ_BINARY_FILE", 'f'},
|
||||
{"PG_READ_FILE", 'f'},
|
||||
{"PG_RELOAD_CONF", 'f'},
|
||||
{"PG_ROTATE_LOGFILE", 'f'},
|
||||
{"PG_SLEEP", 'f'},
|
||||
{"PG_START_BACKUP", 'f'},
|
||||
{"PG_STAT_FILE", 'f'},
|
||||
{"PG_STOP_BACKUP", 'f'},
|
||||
{"PG_SWITCH_XLOG", 'f'},
|
||||
{"PG_TERMINATE_BACKEND", 'f'},
|
||||
{"PG_TRIGGER_DEPTH", 'f'},
|
||||
{"PI", 'f'},
|
||||
{"POSITION", 'f'},
|
||||
{"POW", 'f'},
|
||||
{"POWER", 'f'},
|
||||
{"PRECISION", 'k'},
|
||||
{"PRIMARY", 'k'},
|
||||
{"PROCEDURE", 'k'},
|
||||
{"PUBLISHINGSERVERNAME", 'f'},
|
||||
{"PURGE", 'k'},
|
||||
{"PWDCOMPARE", 'f'},
|
||||
{"PWDENCRYPT", 'f'},
|
||||
{"QUARTER", 'f'},
|
||||
{"QUOTE", 'f'},
|
||||
{"QUOTENAME", 'f'},
|
||||
{"QUOTE_IDENT", 'f'},
|
||||
{"QUOTE_LITERAL", 'f'},
|
||||
{"QUOTE_NULLABLE", 'f'},
|
||||
{"RADIANS", 'f'},
|
||||
{"RAND", 'f'},
|
||||
{"RANDOM", 'f'},
|
||||
{"RANDOMBLOB", 'f'},
|
||||
{"RANGE", 'k'},
|
||||
{"RANK", 'f'},
|
||||
{"READ", 'k'},
|
||||
{"READS", 'k'},
|
||||
{"READ_WRITE", 'k'},
|
||||
{"REAL", 'n'},
|
||||
{"REFERENCES", 'k'},
|
||||
{"REGEXP", 'o'},
|
||||
{"REGEXP_MATCHES", 'f'},
|
||||
{"REGEXP_REPLACE", 'f'},
|
||||
{"REGEXP_SPLIT_TO_ARRAY", 'f'},
|
||||
{"REGEXP_SPLIT_TO_TABLE", 'f'},
|
||||
{"RELEASE", 'k'},
|
||||
{"RELEASE_LOCK", 'f'},
|
||||
{"RENAME", 'k'},
|
||||
{"REPEAT", 'k'},
|
||||
{"REPLACE", 'k'},
|
||||
{"REPLICATE", 'f'},
|
||||
{"REQUIRE", 'k'},
|
||||
{"RESIGNAL", 'k'},
|
||||
{"RESTRICT", 'k'},
|
||||
{"RETURN", 'k'},
|
||||
{"REVERSE", 'f'},
|
||||
{"REVOKE", 'k'},
|
||||
{"RIGHT", 'n'},
|
||||
{"RLIKE", 'o'},
|
||||
{"ROUND", 'f'},
|
||||
{"ROW", 'f'},
|
||||
{"ROW_COUNT", 'f'},
|
||||
{"ROW_NUMBER", 'f'},
|
||||
{"ROW_TO_JSON", 'f'},
|
||||
{"RPAD", 'f'},
|
||||
{"RTRIM", 'f'},
|
||||
{"SCHAMA_NAME", 'f'},
|
||||
{"SCHEMA", 'k'},
|
||||
{"SCHEMAS", 'k'},
|
||||
{"SCHEMA_ID", 'f'},
|
||||
{"SCOPE_IDENTITY", 'f'},
|
||||
{"SECOND_MICROSECOND", 'k'},
|
||||
{"SEC_TO_TIME", 'f'},
|
||||
{"SELECT", 'k'},
|
||||
{"SENSITIVE", 'k'},
|
||||
{"SEPARATOR", 'k'},
|
||||
{"SESSION_USER", 'f'},
|
||||
{"SET", 'k'},
|
||||
{"SETATTR", 'f'},
|
||||
{"SETSEED", 'f'},
|
||||
{"SETVAL", 'f'},
|
||||
{"SET_BIT", 'f'},
|
||||
{"SET_BYTE", 'f'},
|
||||
{"SET_CONFIG", 'f'},
|
||||
{"SET_MASKLEN", 'f'},
|
||||
{"SHA", 'f'},
|
||||
{"SHA1", 'f'},
|
||||
{"SHA2", 'f'},
|
||||
{"SHOW", 'n'},
|
||||
{"SHUTDOWN", 'k'},
|
||||
{"SIGN", 'f'},
|
||||
{"SIGNAL", 'k'},
|
||||
{"SIGNBYASMKEY", 'f'},
|
||||
{"SIGNBYCERT", 'f'},
|
||||
{"SIMILAR", 'k'},
|
||||
{"SIN", 'f'},
|
||||
{"SLEEP", 'f'},
|
||||
{"SMALLDATETIMEFROMPARTS", 'f'},
|
||||
{"SMALLINT", 'k'},
|
||||
{"SOUNDEX", 'f'},
|
||||
{"SOUNDS", 'o'},
|
||||
{"SPACE", 'f'},
|
||||
{"SPATIAL", 'k'},
|
||||
{"SPECIFIC", 'k'},
|
||||
{"SPLIT_PART", 'f'},
|
||||
{"SQL", 'k'},
|
||||
{"SQLEXCEPTION", 'k'},
|
||||
{"SQLSTATE", 'k'},
|
||||
{"SQLWARNING", 'k'},
|
||||
{"SQL_BIG_RESULT", 'k'},
|
||||
{"SQL_CALC_FOUND_ROWS", 'k'},
|
||||
{"SQL_SMALL_RESULT", 'k'},
|
||||
{"SQL_VARIANT_PROPERTY", 'f'},
|
||||
{"SQRT", 'f'},
|
||||
{"SSL", 'k'},
|
||||
{"STARTING", 'k'},
|
||||
{"STATEMENT_TIMESTAMP", 'f'},
|
||||
{"STATS_DATE", 'f'},
|
||||
{"STDDEV", 'p'},
|
||||
{"STDDEV_POP", 'f'},
|
||||
{"STDDEV_SAMP", 'f'},
|
||||
{"STRAIGHT_JOIN", 'k'},
|
||||
{"STRCMP", 'f'},
|
||||
{"STRCONV", 'f'},
|
||||
{"STRING_AGG", 'f'},
|
||||
{"STRING_TO_ARRAY", 'f'},
|
||||
{"STRPOS", 'f'},
|
||||
{"STR_TO_DATE", 'f'},
|
||||
{"STUFF", 'f'},
|
||||
{"SUBDATE", 'f'},
|
||||
{"SUBSTR", 'f'},
|
||||
{"SUBSTRING", 'f'},
|
||||
{"SUBSTRING_INDEX", 'f'},
|
||||
{"SUBTIME", 'f'},
|
||||
{"SUM", 'f'},
|
||||
{"SUSER_ID", 'f'},
|
||||
{"SUSER_NAME", 'f'},
|
||||
{"SUSER_SID", 'f'},
|
||||
{"SUSER_SNAME", 'f'},
|
||||
{"SWITCHOFFET", 'f'},
|
||||
{"SYS.FN_BUILTIN_PERMISSIONS", 'f'},
|
||||
{"SYS.FN_GET_AUDIT_FILE", 'f'},
|
||||
{"SYS.FN_MY_PERMISSIONS", 'f'},
|
||||
{"SYS.STRAGG", 'f'},
|
||||
{"SYSCOLUMNS", 'k'},
|
||||
{"SYSDATE", 'f'},
|
||||
{"SYSDATETIME", 'f'},
|
||||
{"SYSDATETIMEOFFSET", 'f'},
|
||||
{"SYSOBJECTS", 'k'},
|
||||
{"SYSTEM_USER", 'f'},
|
||||
{"SYSUSERS", 'k'},
|
||||
{"SYSUTCDATETME", 'f'},
|
||||
{"TABLE", 'k'},
|
||||
{"TAN", 'f'},
|
||||
{"TERMINATED", 'k'},
|
||||
{"TERTIARY_WEIGHTS", 'f'},
|
||||
{"TEXTPTR", 'f'},
|
||||
{"TEXTVALID", 'f'},
|
||||
{"THEN", 'k'},
|
||||
{"TIME", 'k'},
|
||||
{"TIMEDIFF", 'f'},
|
||||
{"TIMEFROMPARTS", 'f'},
|
||||
{"TIMEOFDAY", 'f'},
|
||||
{"TIMESERIAL", 'f'},
|
||||
{"TIMESTAMP", 'f'},
|
||||
{"TIMESTAMPADD", 'f'},
|
||||
{"TIMEVALUE", 'f'},
|
||||
{"TIME_FORMAT", 'f'},
|
||||
{"TIME_TO_SEC", 'f'},
|
||||
{"TINYBLOB", 'k'},
|
||||
{"TINYINT", 'k'},
|
||||
{"TINYTEXT", 'k'},
|
||||
{"TODATETIMEOFFSET", 'f'},
|
||||
{"TOP", 'k'},
|
||||
{"TO_ASCII", 'f'},
|
||||
{"TO_CHAR", 'f'},
|
||||
{"TO_DATE", 'f'},
|
||||
{"TO_DAYS", 'f'},
|
||||
{"TO_HEX", 'f'},
|
||||
{"TO_NUMBER", 'f'},
|
||||
{"TO_SECONDS", 'f'},
|
||||
{"TO_TIMESTAMP", 'f'},
|
||||
{"TRAILING", 'n'},
|
||||
{"TRANSACTION_TIMESTAMP", 'f'},
|
||||
{"TRANSLATE", 'f'},
|
||||
{"TRIGGER", 'k'},
|
||||
{"TRIGGER_NESTLEVEL", 'f'},
|
||||
{"TRIM", 'f'},
|
||||
{"TRUE", '1'},
|
||||
{"TRUNC", 'f'},
|
||||
{"TRUNCATE", 'f'},
|
||||
{"TRY_CAST", 'f'},
|
||||
{"TRY_CONVERT", 'f'},
|
||||
{"TRY_PARSE", 'f'},
|
||||
{"TYPEPROPERTY", 'f'},
|
||||
{"TYPE_ID", 'f'},
|
||||
{"TYPE_NAME", 'f'},
|
||||
{"UCASE", 'f'},
|
||||
{"UNCOMPRESS", 'f'},
|
||||
{"UNCOMPRESS_LENGTH", 'f'},
|
||||
{"UNDO", 'k'},
|
||||
{"UNHEX", 'f'},
|
||||
{"UNION", 'U'},
|
||||
{"UNIQUE", 'n'},
|
||||
{"UNIX_TIMESTAMP", 'f'},
|
||||
{"UNI_ON", 'U'},
|
||||
{"UNKNOWN", 'k'},
|
||||
{"UNLOCK", 'k'},
|
||||
{"UNNEST", 'f'},
|
||||
{"UNSIGNED", 'k'},
|
||||
{"UPDATE", 'k'},
|
||||
{"UPDATEXML", 'f'},
|
||||
{"UPPER", 'f'},
|
||||
{"UPPER_INC", 'f'},
|
||||
{"UPPER_INF", 'f'},
|
||||
{"USAGE", 'k'},
|
||||
{"USE", 'k'},
|
||||
{"USER_ID", 'n'},
|
||||
{"USER_NAME", 'f'},
|
||||
{"USING", 'f'},
|
||||
{"UTC_DATE", 'k'},
|
||||
{"UTC_TIME", 'k'},
|
||||
{"UTC_TIMESTAMP", 'k'},
|
||||
{"UTL_INADDR.GET_HOST_ADDRESS", 'f'},
|
||||
{"UUID", 'f'},
|
||||
{"UUID_SHORT", 'f'},
|
||||
{"VALUES", 'k'},
|
||||
{"VAR", 'f'},
|
||||
{"VARBINARY", 'k'},
|
||||
{"VARCHAR", 'k'},
|
||||
{"VARCHARACTER", 'k'},
|
||||
{"VARIANCE", 'f'},
|
||||
{"VARP", 'f'},
|
||||
{"VARYING", 'k'},
|
||||
{"VAR_POP", 'f'},
|
||||
{"VAR_SAMP", 'f'},
|
||||
{"VERIFYSIGNEDBYASMKEY", 'f'},
|
||||
{"VERIFYSIGNEDBYCERT", 'f'},
|
||||
{"VERSION", 'f'},
|
||||
{"WAITFOR", 'k'},
|
||||
{"WEEK", 'f'},
|
||||
{"WEEKDAY", 'f'},
|
||||
{"WEEKDAYNAME", 'f'},
|
||||
{"WEEKOFYEAR", 'f'},
|
||||
{"WHEN", 'k'},
|
||||
{"WHERE", 'k'},
|
||||
{"WHILE", 'k'},
|
||||
{"WIDTH_BUCKET", 'f'},
|
||||
{"WITH", 'k'},
|
||||
{"XMLAGG", 'f'},
|
||||
{"XMLCOMMENT", 'f'},
|
||||
{"XMLCONCAT", 'f'},
|
||||
{"XMLELEMENT", 'f'},
|
||||
{"XMLEXISTS", 'f'},
|
||||
{"XMLFOREST", 'f'},
|
||||
{"XMLFORMAT", 'f'},
|
||||
{"XMLPI", 'f'},
|
||||
{"XMLROOT", 'f'},
|
||||
{"XMLTYPE", 'f'},
|
||||
{"XML_IS_WELL_FORMED", 'f'},
|
||||
{"XOR", 'o'},
|
||||
{"XPATH", 'f'},
|
||||
{"XPATH_EXISTS", 'f'},
|
||||
{"XP_EXECRESULTSET", 'k'},
|
||||
{"YEAR", 'f'},
|
||||
{"YEARWEEK", 'f'},
|
||||
{"YEAR_MONTH", 'k'},
|
||||
{"ZEROFILL", 'k'},
|
||||
};
|
||||
static const size_t sql_keywords_sz = 737;
|
||||
static const char* multikeywords_start[] = {
|
||||
"ALTER",
|
||||
"AT",
|
||||
"AT TIME",
|
||||
"CROSS",
|
||||
"FULL",
|
||||
"GROUP",
|
||||
"IN",
|
||||
"IN BOOLEAN",
|
||||
"INTERSECT",
|
||||
"IS",
|
||||
"IS DISTINCT",
|
||||
"IS NOT",
|
||||
"LEFT",
|
||||
"LOCK",
|
||||
"NATURAL",
|
||||
"NEXT",
|
||||
"NEXT VALUE",
|
||||
"NOT",
|
||||
"NOT SIMILAR",
|
||||
"ORDER",
|
||||
"OWN3D",
|
||||
"READ",
|
||||
"RIGHT",
|
||||
"SELECT",
|
||||
"SIMILAR",
|
||||
"SOUNDS",
|
||||
"UNION",
|
||||
};
|
||||
static const size_t multikeywords_start_sz = 27;
|
||||
static const keyword_t multikeywords[] = {
|
||||
{"ALTER DOMAIN", 'k'},
|
||||
{"ALTER TABLE", 'k'},
|
||||
{"AT TIME", 'n'},
|
||||
{"AT TIME ZONE", 'k'},
|
||||
{"CROSS JOIN", 'k'},
|
||||
{"FULL OUTER", 'k'},
|
||||
{"GROUP BY", 'B'},
|
||||
{"IN BOOLEAN", 'n'},
|
||||
{"IN BOOLEAN MODE", 'k'},
|
||||
{"INTERSECT ALL", 'o'},
|
||||
{"IS DISTINCT", 'n'},
|
||||
{"IS DISTINCT FROM", 'k'},
|
||||
{"IS NOT", 'o'},
|
||||
{"IS NOT DISTINCT", 'n'},
|
||||
{"IS NOT DISTINCT FROM", 'k'},
|
||||
{"LEFT JOIN", 'k'},
|
||||
{"LEFT OUTER", 'k'},
|
||||
{"LOCK TABLE", 'k'},
|
||||
{"LOCK TABLES", 'k'},
|
||||
{"NATURAL FULL", 'k'},
|
||||
{"NATURAL INNER", 'k'},
|
||||
{"NATURAL JOIN", 'k'},
|
||||
{"NATURAL LEFT", 'k'},
|
||||
{"NATURAL OUTER", 'k'},
|
||||
{"NATURAL RIGHT", 'k'},
|
||||
{"NEXT VALUE", 'n'},
|
||||
{"NEXT VALUE FOR", 'k'},
|
||||
{"NOT BETWEEN", 'o'},
|
||||
{"NOT IN", 'o'},
|
||||
{"NOT LIKE", 'o'},
|
||||
{"NOT REGEXP", 'o'},
|
||||
{"NOT RLIKE", 'o'},
|
||||
{"NOT SIMILAR", 'o'},
|
||||
{"NOT SIMILAR TO", 'o'},
|
||||
{"ORDER BY", 'B'},
|
||||
{"OWN3D BY", 'B'},
|
||||
{"READ WRITE", 'k'},
|
||||
{"RIGHT JOIN", 'k'},
|
||||
{"RIGHT OUTER", 'k'},
|
||||
{"SELECT ALL", 'k'},
|
||||
{"SIMILAR TO", 'o'},
|
||||
{"SOUNDS LIKE", 'o'},
|
||||
{"UNION ALL", 'U'},
|
||||
};
|
||||
static const size_t multikeywords_sz = 43;
|
||||
|
||||
typedef size_t (*pt2Function)(sfilter *sf);
|
||||
static const pt2Function char_parse_map[] = {
|
||||
&parse_white, /* 0 */
|
||||
&parse_white, /* 1 */
|
||||
&parse_white, /* 2 */
|
||||
&parse_white, /* 3 */
|
||||
&parse_white, /* 4 */
|
||||
&parse_white, /* 5 */
|
||||
&parse_white, /* 6 */
|
||||
&parse_white, /* 7 */
|
||||
&parse_white, /* 8 */
|
||||
&parse_white, /* 9 */
|
||||
&parse_white, /* 10 */
|
||||
&parse_white, /* 11 */
|
||||
&parse_white, /* 12 */
|
||||
&parse_white, /* 13 */
|
||||
&parse_white, /* 14 */
|
||||
&parse_white, /* 15 */
|
||||
&parse_white, /* 16 */
|
||||
&parse_white, /* 17 */
|
||||
&parse_white, /* 18 */
|
||||
&parse_white, /* 19 */
|
||||
&parse_white, /* 20 */
|
||||
&parse_white, /* 21 */
|
||||
&parse_white, /* 22 */
|
||||
&parse_white, /* 23 */
|
||||
&parse_white, /* 24 */
|
||||
&parse_white, /* 25 */
|
||||
&parse_white, /* 26 */
|
||||
&parse_white, /* 27 */
|
||||
&parse_white, /* 28 */
|
||||
&parse_white, /* 29 */
|
||||
&parse_white, /* 30 */
|
||||
&parse_white, /* 31 */
|
||||
&parse_white, /* 32 */
|
||||
&parse_operator2, /* 33 */
|
||||
&parse_string, /* 34 */
|
||||
&parse_eol_comment, /* 35 */
|
||||
&parse_money, /* 36 */
|
||||
&parse_operator1, /* 37 */
|
||||
&parse_operator2, /* 38 */
|
||||
&parse_string, /* 39 */
|
||||
&parse_char, /* 40 */
|
||||
&parse_char, /* 41 */
|
||||
&parse_operator2, /* 42 */
|
||||
&parse_operator1, /* 43 */
|
||||
&parse_char, /* 44 */
|
||||
&parse_dash, /* 45 */
|
||||
&parse_number, /* 46 */
|
||||
&parse_slash, /* 47 */
|
||||
&parse_number, /* 48 */
|
||||
&parse_number, /* 49 */
|
||||
&parse_number, /* 50 */
|
||||
&parse_number, /* 51 */
|
||||
&parse_number, /* 52 */
|
||||
&parse_number, /* 53 */
|
||||
&parse_number, /* 54 */
|
||||
&parse_number, /* 55 */
|
||||
&parse_number, /* 56 */
|
||||
&parse_number, /* 57 */
|
||||
&parse_char, /* 58 */
|
||||
&parse_char, /* 59 */
|
||||
&parse_operator2, /* 60 */
|
||||
&parse_operator2, /* 61 */
|
||||
&parse_operator2, /* 62 */
|
||||
&parse_other, /* 63 */
|
||||
&parse_var, /* 64 */
|
||||
&parse_word, /* 65 */
|
||||
&parse_word, /* 66 */
|
||||
&parse_word, /* 67 */
|
||||
&parse_word, /* 68 */
|
||||
&parse_word, /* 69 */
|
||||
&parse_word, /* 70 */
|
||||
&parse_word, /* 71 */
|
||||
&parse_word, /* 72 */
|
||||
&parse_word, /* 73 */
|
||||
&parse_word, /* 74 */
|
||||
&parse_word, /* 75 */
|
||||
&parse_word, /* 76 */
|
||||
&parse_word, /* 77 */
|
||||
&parse_word, /* 78 */
|
||||
&parse_word, /* 79 */
|
||||
&parse_word, /* 80 */
|
||||
&parse_word, /* 81 */
|
||||
&parse_word, /* 82 */
|
||||
&parse_word, /* 83 */
|
||||
&parse_word, /* 84 */
|
||||
&parse_word, /* 85 */
|
||||
&parse_word, /* 86 */
|
||||
&parse_word, /* 87 */
|
||||
&parse_word, /* 88 */
|
||||
&parse_word, /* 89 */
|
||||
&parse_word, /* 90 */
|
||||
&parse_other, /* 91 */
|
||||
&parse_backslash, /* 92 */
|
||||
&parse_other, /* 93 */
|
||||
&parse_operator1, /* 94 */
|
||||
&parse_word, /* 95 */
|
||||
&parse_word, /* 96 */
|
||||
&parse_word, /* 97 */
|
||||
&parse_word, /* 98 */
|
||||
&parse_word, /* 99 */
|
||||
&parse_word, /* 100 */
|
||||
&parse_word, /* 101 */
|
||||
&parse_word, /* 102 */
|
||||
&parse_word, /* 103 */
|
||||
&parse_word, /* 104 */
|
||||
&parse_word, /* 105 */
|
||||
&parse_word, /* 106 */
|
||||
&parse_word, /* 107 */
|
||||
&parse_word, /* 108 */
|
||||
&parse_word, /* 109 */
|
||||
&parse_word, /* 110 */
|
||||
&parse_word, /* 111 */
|
||||
&parse_word, /* 112 */
|
||||
&parse_word, /* 113 */
|
||||
&parse_word, /* 114 */
|
||||
&parse_word, /* 115 */
|
||||
&parse_word, /* 116 */
|
||||
&parse_word, /* 117 */
|
||||
&parse_word, /* 118 */
|
||||
&parse_word, /* 119 */
|
||||
&parse_word, /* 120 */
|
||||
&parse_word, /* 121 */
|
||||
&parse_word, /* 122 */
|
||||
&parse_other, /* 123 */
|
||||
&parse_operator2, /* 124 */
|
||||
&parse_other, /* 125 */
|
||||
&parse_operator1, /* 126 */
|
||||
&parse_white, /* 127 */
|
||||
};
|
||||
|
||||
#endif
|
70
apache2/libinjection/sqlparse_private.h
Normal file
70
apache2/libinjection/sqlparse_private.h
Normal file
@ -0,0 +1,70 @@
|
||||
/**
|
||||
* Copyright 2012, Nick Galbreath
|
||||
* nickg@client9.com
|
||||
* BSD License - see COPYING.txt for details
|
||||
*
|
||||
* (setq-default indent-tabs-mode nil)
|
||||
* (setq c-default-style "k&r"
|
||||
* c-basic-offset 4)
|
||||
* indent -kr -nut
|
||||
*/
|
||||
#ifndef _SQLPARSE_PRIVATE_H
|
||||
#define _SQLPARSE_PRIVATE_H
|
||||
|
||||
#include "sqlparse.h"
|
||||
|
||||
typedef struct {
|
||||
const char *word;
|
||||
char type;
|
||||
} keyword_t;
|
||||
|
||||
char bsearch_keyword_type(const char *key, const keyword_t keywords[],
|
||||
size_t len);
|
||||
|
||||
int is_operator2(const char *key);
|
||||
|
||||
int is_sqli_pattern(const char *key);
|
||||
|
||||
size_t parse_none(sfilter * sf);
|
||||
size_t parse_money(sfilter * sf);
|
||||
size_t parse_other(sfilter * sf);
|
||||
size_t parse_white(sfilter * sf);
|
||||
size_t parse_operator1(sfilter *sf);
|
||||
size_t parse_char(sfilter *sf);
|
||||
size_t parse_eol_comment(sfilter *sf);
|
||||
size_t parse_dash(sfilter *sf);
|
||||
size_t is_mysql_comment(const char *cs, const size_t len, size_t pos);
|
||||
size_t parse_slash(sfilter *sf);
|
||||
size_t parse_backslash(sfilter * sf);
|
||||
size_t parse_operator2(sfilter *sf);
|
||||
size_t parse_string_core(const char *cs, const size_t len, size_t pos,
|
||||
stoken_t * st, char delim, size_t offset);
|
||||
size_t parse_string(sfilter *sf);
|
||||
size_t parse_word(sfilter * sf);
|
||||
size_t parse_var(sfilter * sf);
|
||||
|
||||
size_t parse_number(sfilter * sf);
|
||||
|
||||
int parse_token(sfilter * sf);
|
||||
|
||||
/**
|
||||
* Looks at syntax_last and syntax_current to see
|
||||
* if they can be merged into a multi-keyword
|
||||
*/
|
||||
int syntax_merge_words(stoken_t * a, stoken_t * b);
|
||||
|
||||
void sfilter_reset(sfilter * sf, const char *s, size_t slen);
|
||||
|
||||
/**
|
||||
* Takes a raw stream of SQL tokens and does the following:
|
||||
* * Merge mutliple strings into one "foo", "bar" --> "foo bar"
|
||||
* * Remove comments except last one 1, +, -- foo, 1 ->> 1,+,1
|
||||
* * Merge multi-word keywords and operators into one
|
||||
* e.g. "UNION", "ALL" --> "UNION ALL"
|
||||
*/
|
||||
int sqli_tokenize(sfilter * sf, stoken_t * sout);
|
||||
|
||||
int filter_fold(sfilter * sf, stoken_t * sout);
|
||||
|
||||
|
||||
#endif /* _SQLPARSE_PRIVATE_H */
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
@ -391,11 +391,9 @@ apr_status_t modsecurity_tx_init(modsec_rec *msr) {
|
||||
if (msr->matched_vars == NULL) return -1;
|
||||
apr_table_clear(msr->matched_vars);
|
||||
|
||||
if(msr->txcfg->max_rule_time > 0) {
|
||||
msr->perf_rules = apr_table_make(msr->mp, 8);
|
||||
if (msr->perf_rules == NULL) return -1;
|
||||
apr_table_clear(msr->perf_rules);
|
||||
}
|
||||
msr->perf_rules = apr_table_make(msr->mp, 8);
|
||||
if (msr->perf_rules == NULL) return -1;
|
||||
apr_table_clear(msr->perf_rules);
|
||||
|
||||
/* Locate the cookie headers and parse them */
|
||||
arr = apr_table_elts(msr->request_headers);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
@ -442,6 +442,8 @@ struct modsec_rec {
|
||||
lua_State *L;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int msc_sdbm_delete_error;
|
||||
};
|
||||
|
||||
struct directory_config {
|
||||
@ -579,7 +581,7 @@ struct directory_config {
|
||||
|
||||
/* Hash */
|
||||
apr_array_header_t *hash_method;
|
||||
const char *crypto_key;
|
||||
const char *crypto_key;
|
||||
int crypto_key_len;
|
||||
const char *crypto_param_name;
|
||||
int hash_is_enabled;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
@ -38,7 +38,7 @@
|
||||
|
||||
#define MODSEC_VERSION_MAJOR "2"
|
||||
#define MODSEC_VERSION_MINOR "7"
|
||||
#define MODSEC_VERSION_MAINT "3"
|
||||
#define MODSEC_VERSION_MAINT "4"
|
||||
#define MODSEC_VERSION_TYPE ""
|
||||
#define MODSEC_VERSION_RELEASE ""
|
||||
|
||||
@ -53,10 +53,10 @@
|
||||
#define MODSEC_MODULE_NAME "ModSecurity for IIS (STABLE)"
|
||||
#else
|
||||
#ifdef VERSION_NGINX
|
||||
#define MODSEC_MODULE_NAME "ModSecurity for nginx (RC)"
|
||||
#define MODSEC_MODULE_NAME "ModSecurity for nginx (STABLE)"
|
||||
#else
|
||||
#ifdef VERSION_STANDALONE
|
||||
#define MODSEC_MODULE_NAME "ModSecurity Standalone (RC)"
|
||||
#define MODSEC_MODULE_NAME "ModSecurity Standalone (STABLE)"
|
||||
#else
|
||||
#define MODSEC_MODULE_NAME "ModSecurity for Apache"
|
||||
#endif
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
@ -170,6 +170,7 @@ static apr_status_t modsecurity_request_body_store_memory(modsec_rec *msr,
|
||||
|
||||
/* Would storing this chunk mean going over the limit? */
|
||||
if ((msr->msc_reqbody_spilltodisk)
|
||||
&& (msr->txcfg->reqbody_buffering != REQUEST_BODY_FORCEBUF_ON)
|
||||
&& (msr->msc_reqbody_length + length > (apr_size_t)msr->txcfg->reqbody_inmemory_limit))
|
||||
{
|
||||
msc_data_chunk **chunks;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
@ -220,6 +220,7 @@ static apr_table_t *collection_retrieve_ex(apr_sdbm_t *existing_dbm, modsec_rec
|
||||
msr_log(msr, 1, "collection_retrieve_ex: Failed deleting collection (name \"%s\", "
|
||||
"key \"%s\"): %s", log_escape(msr->mp, col_name),
|
||||
log_escape_ex(msr->mp, col_key, col_key_len), get_apr_error(msr->mp, rc));
|
||||
msr->msc_sdbm_delete_error = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@ -467,7 +468,7 @@ int collection_store(modsec_rec *msr, apr_table_t *col) {
|
||||
|
||||
var->value = apr_psprintf(msr->mp, "%d", newval);
|
||||
var->value_len = strlen(var->value);
|
||||
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "collection_store: Delta applied for %s.%s %d->%d (%d): %d + (%d) = %d [%s,%d]",
|
||||
log_escape_ex(msr->mp, var_name->value, var_name->value_len),
|
||||
@ -490,7 +491,12 @@ int collection_store(modsec_rec *msr, apr_table_t *col) {
|
||||
/* Now generate the binary object. */
|
||||
blob = apr_pcalloc(msr->mp, blob_size);
|
||||
if (blob == NULL) {
|
||||
goto error;
|
||||
if (dbm != NULL) {
|
||||
apr_sdbm_unlock(dbm);
|
||||
apr_sdbm_close(dbm);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
blob[0] = 0x49;
|
||||
@ -542,10 +548,16 @@ int collection_store(modsec_rec *msr, apr_table_t *col) {
|
||||
rc = apr_sdbm_store(dbm, key, value, APR_SDBM_REPLACE);
|
||||
if (rc != APR_SUCCESS) {
|
||||
msr_log(msr, 1, "collection_store: Failed to write to DBM file \"%s\": %s", dbm_filename,
|
||||
get_apr_error(msr->mp, rc));
|
||||
goto error;
|
||||
get_apr_error(msr->mp, rc));
|
||||
if (dbm != NULL) {
|
||||
apr_sdbm_unlock(dbm);
|
||||
apr_sdbm_close(dbm);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
apr_sdbm_unlock(dbm);
|
||||
apr_sdbm_close(dbm);
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 4) {
|
||||
@ -557,11 +569,6 @@ int collection_store(modsec_rec *msr, apr_table_t *col) {
|
||||
return 0;
|
||||
|
||||
error:
|
||||
|
||||
if (dbm) {
|
||||
apr_sdbm_close(dbm);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -672,9 +679,10 @@ int collections_remove_stale(modsec_rec *msr, const char *col_name) {
|
||||
msr_log(msr, 1, "collections_remove_stale: Failed deleting collection (name \"%s\", "
|
||||
"key \"%s\"): %s", log_escape(msr->mp, col_name),
|
||||
log_escape_ex(msr->mp, key.dptr, key.dsize - 1), get_apr_error(msr->mp, rc));
|
||||
msr->msc_sdbm_delete_error = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 4) {
|
||||
msr_log(msr, 4, "collections_remove_stale: Removed stale collection (name \"%s\", "
|
||||
"key \"%s\").", log_escape(msr->mp, col_name),
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
12
apache2/re.c
12
apache2/re.c
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
@ -2604,12 +2604,16 @@ static int execute_operator(msre_var *var, msre_rule *rule, modsec_rec *msr,
|
||||
rt_time = apr_table_get(msr->perf_rules, rule->actionset->id);
|
||||
if(rt_time == NULL) {
|
||||
rt_time = apr_psprintf(msr->mp, "%" APR_TIME_T_FMT, (t1 - time_before_op));
|
||||
apr_table_setn(msr->perf_rules, rule->actionset->id, rt_time);
|
||||
rule_time = (apr_time_t)atoi(rt_time);
|
||||
if(rule_time >= msr->txcfg->max_rule_time)
|
||||
apr_table_setn(msr->perf_rules, rule->actionset->id, rt_time);
|
||||
} else {
|
||||
rule_time = (apr_time_t)atoi(rt_time);
|
||||
rule_time += (t1 - time_before_op);
|
||||
rt_time = apr_psprintf(msr->mp, "%" APR_TIME_T_FMT, rule_time);
|
||||
apr_table_setn(msr->perf_rules, rule->actionset->id, rt_time);
|
||||
if(rule_time >= msr->txcfg->max_rule_time) {
|
||||
rt_time = apr_psprintf(msr->mp, "%" APR_TIME_T_FMT, rule_time);
|
||||
apr_table_setn(msr->perf_rules, rule->actionset->id, rt_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
@ -27,6 +27,9 @@
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include "libinjection/sqlparse.h"
|
||||
#include "libinjection/sqli_fingerprints.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@ -369,7 +372,7 @@ static int msre_op_ipmatchFromFile_execute(modsec_rec *msr, msre_rule *rule, msr
|
||||
/* rsub */
|
||||
|
||||
static char *param_remove_escape(msre_rule *rule, char *str, int len) {
|
||||
char *parm = apr_palloc(rule->ruleset->mp, len);
|
||||
char *parm = apr_pcalloc(rule->ruleset->mp, len);
|
||||
char *ret = parm;
|
||||
|
||||
for(;*str!='\0';str++) {
|
||||
@ -2129,6 +2132,42 @@ static int msre_op_contains_execute(modsec_rec *msr, msre_rule *rule, msre_var *
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** libinjection detectSQLi
|
||||
* links against files in libinjection directory
|
||||
* See www.client9.com/libinjection for details
|
||||
* `is_sqli_pattern` right now is a hardwired set of sqli fingerprints.
|
||||
* In future, change to read from file.
|
||||
*/
|
||||
static int msre_op_detectSQLi_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
|
||||
char **error_msg) {
|
||||
sfilter sf;
|
||||
int issqli = is_sqli(&sf, var->value, var->value_len, is_sqli_pattern);
|
||||
int capture = apr_table_get(rule->actionset->actions, "capture") ? 1 : 0;
|
||||
|
||||
if (error_msg == NULL) return -1;
|
||||
*error_msg = NULL;
|
||||
|
||||
if (issqli) {
|
||||
set_match_to_tx(msr, capture, sf.pat, 0);
|
||||
|
||||
*error_msg = apr_psprintf(msr->mp, "detected SQLi using libinjection fingerprint '%s' at %s",
|
||||
sf.pat, var->name);
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "detectSQLi: libinjection fingerprint '%s' matched input '%s'",
|
||||
sf.pat,
|
||||
log_escape_ex(msr->mp, var->value, var->value_len));
|
||||
}
|
||||
} else {
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "detectSQLi: no sql, libinjection no match input '%s' at '%s'",
|
||||
log_escape_ex(msr->mp, var->value, var->value_len), var->name);
|
||||
}
|
||||
}
|
||||
|
||||
return issqli;
|
||||
}
|
||||
|
||||
/* containsWord */
|
||||
|
||||
static int msre_op_containsWord_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, char **error_msg) {
|
||||
@ -4502,7 +4541,14 @@ void msre_engine_register_default_operators(msre_engine *engine) {
|
||||
msre_op_containsWord_execute
|
||||
);
|
||||
|
||||
/* is */
|
||||
/* detectSQLi */
|
||||
msre_engine_op_register(engine,
|
||||
"detectSQLi",
|
||||
NULL,
|
||||
msre_op_detectSQLi_execute
|
||||
);
|
||||
|
||||
/* streq */
|
||||
msre_engine_op_register(engine,
|
||||
"streq",
|
||||
NULL, /* ENH init function to flag var substitution */
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
@ -511,6 +511,19 @@ static int var_reqbody_processor_generate(modsec_rec *msr, msre_var *var, msre_r
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* SDBM_DELETE_ERROR */
|
||||
static int var_sdbm_delete_error_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
||||
apr_table_t *vartab, apr_pool_t *mptmp)
|
||||
{
|
||||
msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
||||
|
||||
rvar->value = apr_psprintf(mptmp, "%d", msr->msc_sdbm_delete_error);
|
||||
rvar->value_len = strlen(rvar->value);
|
||||
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* REQBODY_ERROR */
|
||||
|
||||
static int var_reqbody_processor_error_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
||||
@ -700,13 +713,20 @@ static int var_useragent_ip_generate(modsec_rec *msr, msre_var *var, msre_rule *
|
||||
static int var_remote_addr_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
||||
apr_table_t *vartab, apr_pool_t *mptmp)
|
||||
{
|
||||
#if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER > 3
|
||||
if (ap_find_linked_module("mod_remoteip.c") != NULL) {
|
||||
if(msr->r->useragent_ip != NULL) msr->remote_addr = apr_pstrdup(msr->mp, msr->r->useragent_ip);
|
||||
return var_simple_generate(var, vartab, mptmp, msr->remote_addr);
|
||||
}
|
||||
#endif
|
||||
|
||||
return var_simple_generate(var, vartab, mptmp, msr->remote_addr);
|
||||
}
|
||||
|
||||
/* REMOTE_HOST */
|
||||
|
||||
static int var_remote_host_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
||||
apr_table_t *vartab, apr_pool_t *mptmp)
|
||||
apr_table_t *vartab, apr_pool_t *mptmp)
|
||||
{
|
||||
const char *value1 = ap_get_remote_host(msr->r->connection, msr->r->per_dir_config,
|
||||
REMOTE_NAME, NULL);
|
||||
@ -3117,6 +3137,16 @@ void msre_engine_register_default_variables(msre_engine *engine) {
|
||||
PHASE_REQUEST_HEADERS
|
||||
);
|
||||
|
||||
msre_engine_variable_register(engine,
|
||||
"SDBM_DELETE_ERROR",
|
||||
VAR_SIMPLE,
|
||||
0, 0,
|
||||
NULL,
|
||||
var_sdbm_delete_error_generate,
|
||||
VAR_DONT_CACHE, /* dynamic */
|
||||
PHASE_REQUEST_BODY
|
||||
);
|
||||
|
||||
/* REQBODY_PROCESSOR_ERROR - Deprecated */
|
||||
msre_engine_variable_register(engine,
|
||||
"REQBODY_PROCESSOR_ERROR",
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -11,7 +11,8 @@ APR_CFLAGS=""
|
||||
APR_CPPFLAGS=""
|
||||
APR_LDFLAGS=""
|
||||
APR_LDADD=""
|
||||
|
||||
APR_INCLUDEDIR=""
|
||||
APR_LINKLD=""
|
||||
AC_DEFUN([CHECK_APR],
|
||||
[dnl
|
||||
|
||||
@ -63,6 +64,10 @@ if test -n "${apr_path}"; then
|
||||
if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(apr LDFLAGS: $APR_LDFLAGS); fi
|
||||
APR_LDADD="`${APR_CONFIG} --link-libtool`"
|
||||
if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(apr LDADD: $APR_LDADD); fi
|
||||
APR_INCLUDEDIR="`${APR_CONFIG} --includedir`"
|
||||
if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(apr INCLUDEDIR: $APR_INCLUDEDIR); fi
|
||||
APR_LINKLD="`${APR_CONFIG} --link-ld`"
|
||||
if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(apr LINKLD: $APR_LINKLD); fi
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
@ -73,6 +78,8 @@ AC_SUBST(APR_CFLAGS)
|
||||
AC_SUBST(APR_CPPFLAGS)
|
||||
AC_SUBST(APR_LDFLAGS)
|
||||
AC_SUBST(APR_LDADD)
|
||||
AC_SUBST(APR_INCLUDEDIR)
|
||||
AC_SUBST(APR_LINKLD)
|
||||
|
||||
if test -z "${APR_VERSION}"; then
|
||||
AC_MSG_NOTICE([*** apr library not found.])
|
||||
|
@ -10,6 +10,8 @@ APU_CONFIG=""
|
||||
APU_CFLAGS=""
|
||||
APU_LDFLAGS=""
|
||||
APU_LDADD=""
|
||||
APU_INCLUDEDIR=""
|
||||
APU_LINKLD=""
|
||||
|
||||
AC_DEFUN([CHECK_APU],
|
||||
[dnl
|
||||
@ -18,7 +20,7 @@ AC_ARG_WITH(
|
||||
apu,
|
||||
[AC_HELP_STRING([--with-apu=PATH],[Path to apu prefix or config script])],
|
||||
[test_paths="${with_apu}"],
|
||||
[test_paths="/usr/local/libapr-util /usr/local/apr-util /usr/local/libapu /usr/local/apu /usr/local /opt/libapr-util /opt/apr-util /opt/libapu /opt/apu /opt /usr"])
|
||||
[test_paths="/usr/local/libapr-util /usr/local/apr-util /usr/local/libapu /usr/local/apu /usr/local/apr /usr/local /opt/libapr-util /opt/apr-util /opt/libapu /opt/apu /opt /usr"])
|
||||
|
||||
AC_MSG_CHECKING([for libapu config script])
|
||||
|
||||
@ -60,6 +62,10 @@ if test -n "${apu_path}"; then
|
||||
if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(apu LDFLAGS: $APU_LDFLAGS); fi
|
||||
APU_LDADD="`${APU_CONFIG} --link-libtool`"
|
||||
if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(apu LDADD: $APU_LDADD); fi
|
||||
APU_INCLUDEDIR="`${APU_CONFIG} --includedir`"
|
||||
if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(apu INCLUDEDIR: $APU_INCLUDEDIR); fi
|
||||
APU_LINKLD="`${APU_CONFIG} --link-ld`"
|
||||
if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(apu LINKLD: $APU_LINKLD); fi
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
@ -69,6 +75,8 @@ AC_SUBST(APU_VERSION)
|
||||
AC_SUBST(APU_CFLAGS)
|
||||
AC_SUBST(APU_LDFLAGS)
|
||||
AC_SUBST(APU_LDADD)
|
||||
AC_SUBST(APU_INCLUDEDIR)
|
||||
AC_SUBST(APU_LINKLD)
|
||||
|
||||
if test -z "${APU_VERSION}"; then
|
||||
AC_MSG_NOTICE([*** apu library not found.])
|
||||
|
@ -374,7 +374,7 @@ AC_ARG_ENABLE(htaccess-config,
|
||||
# Enable phase-1 in post_read_request
|
||||
AC_ARG_ENABLE(request-early,
|
||||
AS_HELP_STRING([--enable-request-early],
|
||||
[Place phase1 into post_read_request hook.]),
|
||||
[Place phase1 into post_read_request hook. default is hook_request_early]),
|
||||
[
|
||||
if test "$enableval" != "no"; then
|
||||
request_early="-DREQUEST_EARLY"
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!@PERL@
|
||||
#
|
||||
# ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
# Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
# Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
#
|
||||
# You may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -77,7 +77,7 @@ FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'"
|
||||
# Did we see anything that might be a boundary?
|
||||
#
|
||||
SecRule MULTIPART_UNMATCHED_BOUNDARY "!@eq 0" \
|
||||
"id:'200003',phase:2,t:none,log,deny,status:44,msg:'Multipart parser detected a possible unmatched boundary.'"
|
||||
"id:'200003',phase:2,t:none,log,deny,msg:'Multipart parser detected a possible unmatched boundary.'"
|
||||
|
||||
# PCRE Tuning
|
||||
# We want to avoid a potential RegEx DoS condition
|
||||
|
@ -3,5 +3,5 @@ CORE_MODULES="$CORE_MODULES ngx_pool_context_module"
|
||||
HTTP_AUX_FILTER_MODULES="ngx_http_modsecurity $HTTP_AUX_FILTER_MODULES"
|
||||
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_modsecurity.c $ngx_addon_dir/apr_bucket_nginx.c $ngx_addon_dir/ngx_pool_context.c"
|
||||
NGX_ADDON_DEPS="$NGX_ADDON_DEPS $ngx_addon_dir/apr_bucket_nginx.h $ngx_addon_dir/ngx_pool_context.h"
|
||||
CORE_LIBS="$CORE_LIBS $ngx_addon_dir/../../standalone/.libs/standalone.a -lapr-1 -laprutil-1 -lxml2 -lm "
|
||||
CORE_INCS="$CORE_INCS /usr/include/apache2 /usr/include/apr-1.0 /usr/include/httpd /usr/include/apr-1 $ngx_addon_dir $ngx_addon_dir/../../standalone $ngx_addon_dir/../../apache2 /usr/include/libxml2 "
|
||||
CORE_LIBS="$CORE_LIBS $ngx_addon_dir/../../standalone/.libs/standalone.a -L/usr/local/apr/lib -lapr-1 -L/usr/local/apr/lib -laprutil-1 -lpcre -lxml2 -lz -lm -ldl "
|
||||
CORE_INCS="$CORE_INCS $ngx_addon_dir $ngx_addon_dir/../../standalone $ngx_addon_dir/../../apache2 /usr/include/libxml2 /usr/local/apache2/include /usr/local/apr/include/apr-1 /usr/local/apr/include/apr-1"
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
@ -52,7 +52,6 @@ static ngx_int_t ngx_http_modsecurity_body_filter(ngx_http_request_t *r, ngx_cha
|
||||
static ngx_int_t ngx_http_modsecurity_preconfiguration(ngx_conf_t *cf);
|
||||
static ngx_int_t ngx_http_modsecurity_init(ngx_conf_t *cf);
|
||||
static ngx_int_t ngx_http_modsecurity_init_process(ngx_cycle_t *cycle);
|
||||
static void ngx_http_modsecurity_exit_process(ngx_cycle_t *cycle);
|
||||
static void *ngx_http_modsecurity_create_loc_conf(ngx_conf_t *cf);
|
||||
static char *ngx_http_modsecurity_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child);
|
||||
static char *ngx_http_modsecurity_config(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
|
||||
@ -60,6 +59,7 @@ static char *ngx_http_modsecurity_enable(ngx_conf_t *cf, ngx_command_t *cmd, voi
|
||||
|
||||
static ngx_http_modsecurity_ctx_t * ngx_http_modsecurity_create_ctx(ngx_http_request_t *r);
|
||||
static int ngx_http_modsecurity_drop_action(request_rec *r);
|
||||
static void ngx_http_modsecurity_finalize(void *data);
|
||||
static void ngx_http_modsecurity_cleanup(void *data);
|
||||
|
||||
static int ngx_http_modsecurity_save_headers_in_visitor(void *data, const char *key, const char *value);
|
||||
@ -113,8 +113,8 @@ ngx_module_t ngx_http_modsecurity = {
|
||||
ngx_http_modsecurity_init_process, /* init process */
|
||||
NULL, /* init thread */
|
||||
NULL, /* exit thread */
|
||||
ngx_http_modsecurity_exit_process, /* exit process */
|
||||
ngx_http_modsecurity_exit_process, /* exit master */
|
||||
NULL, /* exit process */
|
||||
NULL, /* exit master */
|
||||
NGX_MODULE_V1_PADDING
|
||||
};
|
||||
|
||||
@ -156,7 +156,8 @@ ngx_pstrdup0(ngx_pool_t *pool, ngx_str_t *src)
|
||||
}
|
||||
|
||||
|
||||
static inline int ngx_http_modsecurity_method_number(unsigned int nginx)
|
||||
static inline int
|
||||
ngx_http_modsecurity_method_number(unsigned int nginx)
|
||||
{
|
||||
/*
|
||||
* http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightMultLookup
|
||||
@ -246,7 +247,7 @@ ngx_http_modsecurity_load_request(ngx_http_request_t *r)
|
||||
}
|
||||
#endif
|
||||
|
||||
req->parsed_uri.path = req->path_info;
|
||||
req->parsed_uri.path = (char *)ngx_pstrdup0(r->pool, &r->uri);
|
||||
req->parsed_uri.is_initialized = 1;
|
||||
|
||||
str.data = r->port_start;
|
||||
@ -254,7 +255,7 @@ ngx_http_modsecurity_load_request(ngx_http_request_t *r)
|
||||
req->parsed_uri.port = ngx_atoi(str.data, str.len);
|
||||
req->parsed_uri.port_str = (char *)ngx_pstrdup0(r->pool, &str);
|
||||
|
||||
req->parsed_uri.query = req->args;
|
||||
req->parsed_uri.query = r->args.len ? req->args : NULL;
|
||||
req->parsed_uri.dns_looked_up = 0;
|
||||
req->parsed_uri.dns_resolved = 0;
|
||||
|
||||
@ -786,6 +787,29 @@ ngx_http_modsecurity_save_headers_out_visitor(void *data, const char *key, const
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static ngx_inline ngx_int_t
|
||||
ngx_http_modsecurity_status(ngx_http_request_t *r, int status)
|
||||
{
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "ModSecurity: status %d", status);
|
||||
|
||||
if (status == DECLINED || status == APR_SUCCESS) {
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
/* nginx known status */
|
||||
if ( (status >= 300 && status < 308) /* 3XX */
|
||||
|| (status >= 400 && status < 417) /* 4XX */
|
||||
|| (status >= 500 && status < 508) /* 5XX */
|
||||
|| (status == NGX_HTTP_CREATED || status == NGX_HTTP_NO_CONTENT) ) {
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
|
||||
/* create loc conf struct */
|
||||
static void *
|
||||
ngx_http_modsecurity_create_loc_conf(ngx_conf_t *cf)
|
||||
@ -858,7 +882,8 @@ modsec_pcre_free(void *ptr)
|
||||
static ngx_int_t
|
||||
ngx_http_modsecurity_preconfiguration(ngx_conf_t *cf)
|
||||
{
|
||||
server_rec *s;
|
||||
server_rec *s;
|
||||
ngx_pool_cleanup_t *cln;
|
||||
|
||||
/* XXX: temporary hack, nginx uses pcre as well and hijacks these two */
|
||||
pcre_malloc = modsec_pcre_malloc;
|
||||
@ -873,6 +898,12 @@ ngx_http_modsecurity_preconfiguration(ngx_conf_t *cf)
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
cln = ngx_pool_cleanup_add(cf->pool, 0);
|
||||
if (cln == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
cln->handler = ngx_http_modsecurity_finalize;
|
||||
|
||||
/* set host name */
|
||||
s->server_hostname = ngx_palloc(cf->pool, ngx_cycle->hostname.len + 1);
|
||||
if (s->server_hostname == NULL) {
|
||||
@ -886,6 +917,12 @@ ngx_http_modsecurity_preconfiguration(ngx_conf_t *cf)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_http_modsecurity_finalize(void *data)
|
||||
{
|
||||
modsecTerminate();
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_modsecurity_init(ngx_conf_t *cf)
|
||||
@ -896,9 +933,6 @@ ngx_http_modsecurity_init(ngx_conf_t *cf)
|
||||
modsecFinalizeConfig();
|
||||
|
||||
cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
|
||||
if (cmcf == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
h = ngx_array_push(&cmcf->phases[NGX_HTTP_PREACCESS_PHASE].handlers);
|
||||
if (h == NULL) {
|
||||
@ -921,17 +955,12 @@ ngx_http_modsecurity_init(ngx_conf_t *cf)
|
||||
static ngx_int_t
|
||||
ngx_http_modsecurity_init_process(ngx_cycle_t *cycle)
|
||||
{
|
||||
/* must set log hook here cf->log maybe changed */
|
||||
modsecSetLogHook(cycle->log, modsecLog);
|
||||
modsecInitProcess();
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
ngx_http_modsecurity_exit_process(ngx_cycle_t *cycle)
|
||||
{
|
||||
modsecTerminate();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** [ENTRY POINT] does : this function called by nginx from the request handler
|
||||
@ -952,18 +981,18 @@ ngx_http_modsecurity_handler(ngx_http_request_t *r)
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "modSecurity: handler");
|
||||
|
||||
/* create / retrive request ctx */
|
||||
if (r->internal) {
|
||||
/* we have already processed the request headers with previous loc conf */
|
||||
|
||||
/* TODO: do we need update ctx and process headers again? */
|
||||
|
||||
ctx = ngx_http_get_module_pool_ctx(r, ngx_http_modsecurity);
|
||||
|
||||
if (ctx) {
|
||||
/* we have already processed the request headers */
|
||||
ngx_http_set_ctx(r, ctx, ngx_http_modsecurity);
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "modSecurity: get internel request ctx failed");
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "modSecurity: request pool ctx empty");
|
||||
}
|
||||
|
||||
ctx = ngx_http_modsecurity_create_ctx(r);
|
||||
@ -978,52 +1007,34 @@ ngx_http_modsecurity_handler(ngx_http_request_t *r)
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_http_modsecurity_load_request(r);
|
||||
|
||||
if (ngx_http_modsecurity_load_headers_in(r) != NGX_OK) {
|
||||
/* load request to request rec */
|
||||
if (ngx_http_modsecurity_load_request(r) != NGX_OK
|
||||
|| ngx_http_modsecurity_load_headers_in(r) != NGX_OK) {
|
||||
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
/* processing request headers */
|
||||
rc = modsecProcessRequestHeaders(ctx->req);
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "ModSecurity: modsecProcessRequestHeaders %d", rc);
|
||||
rc = ngx_http_modsecurity_status(r, modsecProcessRequestHeaders(ctx->req));
|
||||
|
||||
if (rc == DECLINED) {
|
||||
|
||||
if (modsecIsRequestBodyAccessEnabled(ctx->req)
|
||||
&& r->method == NGX_HTTP_POST) {
|
||||
|
||||
/* Processing POST request body, should we process PUT? */
|
||||
rc = ngx_http_read_client_request_body(r, ngx_http_modsecurity_body_handler);
|
||||
if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
return NGX_DONE;
|
||||
}
|
||||
/* other method */
|
||||
rc = modsecProcessRequestBody(ctx->req);
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "ModSecurity: modsecProcessRequestBody %d", rc);
|
||||
}
|
||||
|
||||
if (rc != DECLINED) {
|
||||
|
||||
/* Nginx and Apache share same response code */
|
||||
if (rc < NGX_HTTP_SPECIAL_RESPONSE || rc >= 600) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
if (rc != NGX_DECLINED) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
if (ngx_http_modsecurity_save_headers_in(r) != NGX_OK) {
|
||||
if (r->method == NGX_HTTP_POST
|
||||
&& modsecIsRequestBodyAccessEnabled(ctx->req) ) {
|
||||
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
/* read POST request body, should we process PUT? */
|
||||
rc = ngx_http_read_client_request_body(r, ngx_http_modsecurity_body_handler);
|
||||
if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
return NGX_DONE;
|
||||
}
|
||||
*/
|
||||
|
||||
return NGX_DECLINED;
|
||||
|
||||
/* other method */
|
||||
return ngx_http_modsecurity_status(r, modsecProcessRequestBody(ctx->req));
|
||||
}
|
||||
|
||||
|
||||
@ -1038,19 +1049,12 @@ ngx_http_modsecurity_body_handler(ngx_http_request_t *r)
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity);
|
||||
|
||||
if (ngx_http_modsecurity_load_request_body(r) != NGX_OK) {
|
||||
|
||||
return ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
rc = modsecProcessRequestBody(ctx->req);
|
||||
rc = ngx_http_modsecurity_status(r, modsecProcessRequestBody(ctx->req));
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "ModSecurity: modsecProcessRequestBody %d", rc);
|
||||
|
||||
if (rc != DECLINED) {
|
||||
/* Nginx and Apache share same response code */
|
||||
if (rc < NGX_HTTP_SPECIAL_RESPONSE || rc >= 600) {
|
||||
rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
if (rc != NGX_DECLINED) {
|
||||
return ngx_http_finalize_request(r, rc);
|
||||
}
|
||||
|
||||
@ -1070,18 +1074,48 @@ static ngx_int_t
|
||||
ngx_http_modsecurity_header_filter(ngx_http_request_t *r) {
|
||||
ngx_http_modsecurity_loc_conf_t *cf;
|
||||
ngx_http_modsecurity_ctx_t *ctx;
|
||||
const char *location;
|
||||
ngx_table_elt_t *h;
|
||||
ngx_int_t rc;
|
||||
|
||||
|
||||
cf = ngx_http_get_module_loc_conf(r, ngx_http_modsecurity);
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity);
|
||||
|
||||
if (r != r->main || !cf->enable || ctx->complete) {
|
||||
/* already processed, checking redirect action. */
|
||||
if (ctx && ctx->complete
|
||||
&& r->err_status >= NGX_HTTP_MOVED_PERMANENTLY
|
||||
&& r->err_status < 308) {
|
||||
|
||||
/* 3XX load redirect location header so that we can do redirect in phase 3,4 */
|
||||
location = apr_table_get(ctx->req->headers_out, "Location");
|
||||
|
||||
if (location == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
h = ngx_list_push(&r->headers_out.headers);
|
||||
if (h == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
h->hash = 1;
|
||||
h->key.data = (u_char *)"Location";
|
||||
h->key.len = ngx_strlen("Location");
|
||||
h->value.data = (u_char *)location;
|
||||
h->value.len = ngx_strlen(location);
|
||||
|
||||
return ngx_http_next_header_filter(r);
|
||||
}
|
||||
|
||||
if (r != r->main || !cf->enable || ctx == NULL ||ctx->complete) {
|
||||
return ngx_http_next_header_filter(r);
|
||||
}
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "modSecurity: header filter");
|
||||
|
||||
if (r->method == NGX_HTTP_HEAD || r->header_only) {
|
||||
/* header only or SecResponseBodyAccess off */
|
||||
if (r->header_only || (!modsecIsResponseBodyAccessEnabled(ctx->req)) ) {
|
||||
|
||||
ctx->complete = 1;
|
||||
|
||||
@ -1091,26 +1125,26 @@ ngx_http_modsecurity_header_filter(ngx_http_request_t *r) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
rc = modsecProcessResponse(ctx->req);
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "ModSecurity: modsecProcessResponse %d", rc);
|
||||
rc = ngx_http_modsecurity_status(r, modsecProcessResponse(ctx->req));
|
||||
|
||||
if (rc == DECLINED || rc == APR_SUCCESS) {
|
||||
|
||||
if (ngx_http_modsecurity_save_headers_in(r) != NGX_OK
|
||||
|| ngx_http_modsecurity_save_headers_out(r) != NGX_OK) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
return ngx_http_next_header_filter(r);
|
||||
if (rc != NGX_DECLINED) {
|
||||
return ngx_http_filter_finalize_request(r, &ngx_http_modsecurity, rc);
|
||||
}
|
||||
|
||||
if (rc < NGX_HTTP_SPECIAL_RESPONSE || rc >= 600) {
|
||||
rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
if (ngx_http_modsecurity_save_headers_in(r) != NGX_OK
|
||||
|| ngx_http_modsecurity_save_headers_out(r) != NGX_OK) {
|
||||
return ngx_http_filter_finalize_request(r, &ngx_http_modsecurity, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
return rc;
|
||||
return ngx_http_next_header_filter(r);
|
||||
}
|
||||
|
||||
/* SecResponseBodyAccess on, process rules in body filter */
|
||||
|
||||
/* pretend we are ngx_http_header_filter */
|
||||
r->header_sent = 1;
|
||||
|
||||
r->filter_need_in_memory = 1;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
@ -1126,74 +1160,70 @@ ngx_http_modsecurity_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
||||
cf = ngx_http_get_module_loc_conf(r, ngx_http_modsecurity);
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity);
|
||||
|
||||
if (r != r->main || !cf->enable || ctx->complete) {
|
||||
if (r != r->main || !cf->enable || ctx == NULL || ctx->complete) {
|
||||
return ngx_http_next_body_filter(r, in);
|
||||
}
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "modSecurity: body filter");
|
||||
|
||||
if (in == NULL) {
|
||||
/* waiting for more buffer */
|
||||
r->buffered |= NGX_HTTP_SSI_BUFFERED;
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
rc = move_chain_to_brigade(in, ctx->brigade, r->pool, 0);
|
||||
if (rc != NGX_OK) {
|
||||
/* waiting for more buffer */
|
||||
r->buffered |= NGX_HTTP_SSI_BUFFERED;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* last buf has been saved */
|
||||
r->buffered &= ~NGX_HTTP_SSI_BUFFERED;
|
||||
|
||||
ctx->complete = 1;
|
||||
modsecSetResponseBrigade(ctx->req, ctx->brigade);
|
||||
|
||||
// TODO: do we need reload headers_in ?
|
||||
//
|
||||
if (ngx_http_modsecurity_load_headers_in(r) != NGX_OK
|
||||
|| ngx_http_modsecurity_load_headers_out(r) != NGX_OK) {
|
||||
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
rc = modsecProcessResponse(ctx->req);
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "ModSecurity: modsecProcessResponse %d", rc);
|
||||
rc = ngx_http_modsecurity_status(r, modsecProcessResponse(ctx->req));
|
||||
|
||||
if (rc == DECLINED || rc == APR_SUCCESS) {
|
||||
|
||||
in = NULL;
|
||||
|
||||
apr_brigade_length(ctx->brigade, 0, &content_length);
|
||||
|
||||
rc = move_brigade_to_chain(ctx->brigade, &in, r->pool);
|
||||
if (rc == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (ngx_http_modsecurity_save_headers_in(r) != NGX_OK
|
||||
||ngx_http_modsecurity_save_headers_out(r) != NGX_OK) {
|
||||
|
||||
return ngx_http_filter_finalize_request(r, &ngx_http_modsecurity, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
if (r->headers_out.content_length_n != -1) {
|
||||
|
||||
r->headers_out.content_length_n = content_length;
|
||||
r->headers_out.content_length = NULL; /* header filter will set this */
|
||||
}
|
||||
|
||||
rc = ngx_http_next_header_filter(r);
|
||||
|
||||
if (rc == NGX_ERROR || rc > NGX_OK) {
|
||||
return ngx_http_filter_finalize_request(r, &ngx_http_modsecurity, rc);
|
||||
}
|
||||
|
||||
return ngx_http_next_body_filter(r, in);
|
||||
if (rc != NGX_DECLINED) {
|
||||
return ngx_http_filter_finalize_request(r, &ngx_http_modsecurity, rc);
|
||||
}
|
||||
|
||||
if (rc < NGX_HTTP_SPECIAL_RESPONSE || rc >= 600) {
|
||||
rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
apr_brigade_length(ctx->brigade, 0, &content_length);
|
||||
|
||||
rc = move_brigade_to_chain(ctx->brigade, &in, r->pool);
|
||||
if (rc == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return ngx_http_filter_finalize_request(r, &ngx_http_modsecurity, rc);
|
||||
if (ngx_http_modsecurity_save_headers_in(r) != NGX_OK
|
||||
||ngx_http_modsecurity_save_headers_out(r) != NGX_OK) {
|
||||
|
||||
return ngx_http_filter_finalize_request(r, &ngx_http_modsecurity, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
if (r->headers_out.content_length_n != -1) {
|
||||
|
||||
r->headers_out.content_length_n = content_length;
|
||||
r->headers_out.content_length = NULL; /* header filter will set this */
|
||||
}
|
||||
|
||||
r->header_sent = 0;
|
||||
rc = ngx_http_next_header_filter(r);
|
||||
|
||||
if (rc == NGX_ERROR || rc > NGX_OK) {
|
||||
return ngx_http_filter_finalize_request(r, &ngx_http_modsecurity, rc);
|
||||
}
|
||||
|
||||
return ngx_http_next_body_filter(r, in);
|
||||
}
|
||||
|
||||
|
||||
|
@ -196,7 +196,7 @@ ngx_pool_context_init_conf(ngx_cycle_t *cycle, void *conf)
|
||||
{
|
||||
ngx_pool_context_conf_t *pcf = conf;
|
||||
|
||||
ngx_conf_init_uint_value(pcf->size, NGX_POOL_CTX_SIZE);
|
||||
ngx_conf_init_uint_value(pcf->size, cycle->connection_n);
|
||||
|
||||
ngx_pool_context_hash_size = pcf->size;
|
||||
|
||||
|
@ -13,7 +13,7 @@ standalone_la_SOURCES = ../apache2/mod_security2.c \
|
||||
../apache2/msc_util.c ../apache2/msc_pcre.c ../apache2/persist_dbm.c ../apache2/msc_reqbody.c \
|
||||
../apache2/msc_geo.c ../apache2/msc_gsb.c ../apache2/msc_unicode.c \
|
||||
../apache2/acmp.c ../apache2/msc_lua.c ../apache2/msc_release.c \
|
||||
../apache2/msc_crypt.c ../apache2/msc_tree.c \
|
||||
../apache2/msc_crypt.c ../apache2/msc_tree.c ../apache2/libinjection/sqlparse.c \
|
||||
api.c buckets.c \
|
||||
config.c filters.c \
|
||||
hooks.c \
|
||||
@ -72,6 +72,10 @@ standalone_la_LDFLAGS = -no-undefined -module -avoid-version \
|
||||
@PCRE_LDFLAGS@ @LIBXML2_LDFLAGS@ @LUA_LDFLAGS@
|
||||
endif
|
||||
|
||||
standalone_INCS = `echo "@LIBXML2_CFLAGS@ @LUA_CFLAGS@" | sed -n 's/ *-I *\([^ ]*\) /\1 /gp'` \
|
||||
@APXS_INCLUDEDIR@ @APR_INCLUDEDIR@ @APU_INCLUDEDIR@
|
||||
standalone_LIBS = @APR_LINKLD@ @APU_LINKLD@ @APXS_LDFLAGS@ \
|
||||
@PCRE_LDADD@ @LIBXML2_LDADD@ @LUA_LDADD@
|
||||
install-exec-hook: $(pkglib_LTLIBRARIES)
|
||||
@echo "Creating Nginx config file..."; \
|
||||
rm -f ../nginx/modsecurity/config; \
|
||||
@ -79,9 +83,9 @@ install-exec-hook: $(pkglib_LTLIBRARIES)
|
||||
echo "CORE_MODULES=\"\$$CORE_MODULES ngx_pool_context_module\"" >> ../nginx/modsecurity/config; \
|
||||
echo "HTTP_AUX_FILTER_MODULES=\"ngx_http_modsecurity \$$HTTP_AUX_FILTER_MODULES\"" >> ../nginx/modsecurity/config; \
|
||||
echo "NGX_ADDON_SRCS=\"\$$NGX_ADDON_SRCS \$$ngx_addon_dir/ngx_http_modsecurity.c \$$ngx_addon_dir/apr_bucket_nginx.c \$$ngx_addon_dir/ngx_pool_context.c\"" >> ../nginx/modsecurity/config;\
|
||||
echo "NGX_ADDON_DEPS=\"\$$NGX_ADDON_DEPS \$$ngx_addon_dir/apr_bucket_nginx.h \$$ngx_addon_dir/ngx_pool_context.h\"" >> ../nginx/modsecurity/config; \
|
||||
echo "CORE_LIBS=\"\$$CORE_LIBS \$$ngx_addon_dir/../../standalone/.libs/standalone.a -lapr-1 -laprutil-1 -lxml2 -lm @LUA_LDADD@\"" >> ../nginx/modsecurity/config; \
|
||||
echo "CORE_INCS=\"\$$CORE_INCS /usr/include/apache2 /usr/include/apr-1.0 /usr/include/httpd /usr/include/apr-1 \$$ngx_addon_dir \$$ngx_addon_dir/../../standalone \$$ngx_addon_dir/../../apache2 /usr/include/libxml2 `echo @LUA_CFLAGS@ | cut -d "I" -f3`\"" >> ../nginx/modsecurity/config; \
|
||||
echo "NGX_ADDON_DEPS=\"\$$NGX_ADDON_DEPS \$$ngx_addon_dir/apr_bucket_nginx.h \$$ngx_addon_dir/ngx_pool_context.h \$$ngx_addon_dir/ngx_http_modsecurity.c \$$ngx_addon_dir/apr_bucket_nginx.c \$$ngx_addon_dir/ngx_pool_context.c\"" >> ../nginx/modsecurity/config; \
|
||||
echo "CORE_LIBS=\"\$$CORE_LIBS \$$ngx_addon_dir/../../standalone/.libs/standalone.a $(standalone_LIBS) \"" >> ../nginx/modsecurity/config; \
|
||||
echo "CORE_INCS=\"\$$CORE_INCS \$$ngx_addon_dir \$$ngx_addon_dir/../../standalone \$$ngx_addon_dir/../../apache2 $(standalone_INCS)\"" >> ../nginx/modsecurity/config; \
|
||||
echo "Removing unused static libraries..."; \
|
||||
for m in $(pkglib_LTLIBRARIES); do \
|
||||
base=`echo $$m | sed 's/\..*//'`; \
|
||||
|
@ -1,9 +1,8 @@
|
||||
# Makefile.in generated by automake 1.11.6 from Makefile.am.
|
||||
# Makefile.in generated by automake 1.12.2 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||
# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
|
||||
# Foundation, Inc.
|
||||
# Copyright (C) 1994-2012 Free Software Foundation, Inc.
|
||||
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
@ -51,7 +50,8 @@ POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
subdir = standalone
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
|
||||
$(top_srcdir)/build/depcomp
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/build/find_apr.m4 \
|
||||
$(top_srcdir)/build/find_apu.m4 \
|
||||
@ -149,13 +149,17 @@ AMTAR = @AMTAR@
|
||||
APR_CFLAGS = @APR_CFLAGS@
|
||||
APR_CONFIG = @APR_CONFIG@
|
||||
APR_CPPFLAGS = @APR_CPPFLAGS@
|
||||
APR_INCLUDEDIR = @APR_INCLUDEDIR@
|
||||
APR_LDADD = @APR_LDADD@
|
||||
APR_LDFLAGS = @APR_LDFLAGS@
|
||||
APR_LINKLD = @APR_LINKLD@
|
||||
APR_VERSION = @APR_VERSION@
|
||||
APU_CFLAGS = @APU_CFLAGS@
|
||||
APU_CONFIG = @APU_CONFIG@
|
||||
APU_INCLUDEDIR = @APU_INCLUDEDIR@
|
||||
APU_LDADD = @APU_LDADD@
|
||||
APU_LDFLAGS = @APU_LDFLAGS@
|
||||
APU_LINKLD = @APU_LINKLD@
|
||||
APU_VERSION = @APU_VERSION@
|
||||
APXS = @APXS@
|
||||
APXS_BINDIR = @APXS_BINDIR@
|
||||
@ -381,6 +385,12 @@ standalone_la_LIBADD = @APR_LDADD@ @APU_LDADD@ @PCRE_LDADD@ @LIBXML2_LDADD@ @LUA
|
||||
@SOLARIS_TRUE@ @APR_LDFLAGS@ @APU_LDFLAGS@ @APXS_LDFLAGS@ \
|
||||
@SOLARIS_TRUE@ @PCRE_LDFLAGS@ @LIBXML2_LDFLAGS@ @LUA_LDFLAGS@
|
||||
|
||||
standalone_INCS = `echo "@LIBXML2_CFLAGS@ @LUA_CFLAGS@" | sed -n 's/ *-I *\([^ ]*\) /\1 /gp'` \
|
||||
@APXS_INCLUDEDIR@ @APR_INCLUDEDIR@ @APU_INCLUDEDIR@
|
||||
|
||||
standalone_LIBS = @APR_LINKLD@ @APU_LINKLD@ @APXS_LDFLAGS@ \
|
||||
@PCRE_LDADD@ @LIBXML2_LDADD@ @LUA_LDADD@
|
||||
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
@ -441,12 +451,14 @@ uninstall-pkglibLTLIBRARIES:
|
||||
|
||||
clean-pkglibLTLIBRARIES:
|
||||
-test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES)
|
||||
@list='$(pkglib_LTLIBRARIES)'; for p in $$list; do \
|
||||
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
|
||||
test "$$dir" != "$$p" || dir=.; \
|
||||
echo "rm -f \"$${dir}/so_locations\""; \
|
||||
rm -f "$${dir}/so_locations"; \
|
||||
done
|
||||
@list='$(pkglib_LTLIBRARIES)'; \
|
||||
locs=`for p in $$list; do echo $$p; done | \
|
||||
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
|
||||
sort -u`; \
|
||||
test -z "$$locs" || { \
|
||||
echo rm -f $${locs}; \
|
||||
rm -f $${locs}; \
|
||||
}
|
||||
standalone.la: $(standalone_la_OBJECTS) $(standalone_la_DEPENDENCIES) $(EXTRA_standalone_la_DEPENDENCIES)
|
||||
$(standalone_la_LINK) -rpath $(pkglibdir) $(standalone_la_OBJECTS) $(standalone_la_LIBADD) $(LIBS)
|
||||
|
||||
@ -797,6 +809,20 @@ GTAGS:
|
||||
&& $(am__cd) $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) "$$here"
|
||||
|
||||
cscopelist: $(HEADERS) $(SOURCES) $(LISP)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP)'; \
|
||||
case "$(srcdir)" in \
|
||||
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
|
||||
*) sdir=$(subdir)/$(srcdir) ;; \
|
||||
esac; \
|
||||
for i in $$list; do \
|
||||
if test -f "$$i"; then \
|
||||
echo "$(subdir)/$$i"; \
|
||||
else \
|
||||
echo "$$sdir/$$i"; \
|
||||
fi; \
|
||||
done >> $(top_builddir)/cscope.files
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
|
||||
@ -942,32 +968,30 @@ uninstall-am: uninstall-pkglibLTLIBRARIES
|
||||
.MAKE: install-am install-exec-am install-strip
|
||||
|
||||
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
|
||||
clean-libtool clean-pkglibLTLIBRARIES ctags distclean \
|
||||
distclean-compile distclean-generic distclean-libtool \
|
||||
distclean-tags distdir dvi dvi-am html html-am info info-am \
|
||||
install install-am install-data install-data-am install-dvi \
|
||||
install-dvi-am install-exec install-exec-am install-exec-hook \
|
||||
install-html install-html-am install-info install-info-am \
|
||||
install-man install-pdf install-pdf-am \
|
||||
install-pkglibLTLIBRARIES install-ps install-ps-am \
|
||||
install-strip installcheck installcheck-am installdirs \
|
||||
maintainer-clean maintainer-clean-generic mostlyclean \
|
||||
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
|
||||
pdf pdf-am ps ps-am tags uninstall uninstall-am \
|
||||
uninstall-pkglibLTLIBRARIES
|
||||
|
||||
clean-libtool clean-pkglibLTLIBRARIES cscopelist ctags \
|
||||
distclean distclean-compile distclean-generic \
|
||||
distclean-libtool distclean-tags distdir dvi dvi-am html \
|
||||
html-am info info-am install install-am install-data \
|
||||
install-data-am install-dvi install-dvi-am install-exec \
|
||||
install-exec-am install-exec-hook install-html install-html-am \
|
||||
install-info install-info-am install-man install-pdf \
|
||||
install-pdf-am install-pkglibLTLIBRARIES install-ps \
|
||||
install-ps-am install-strip installcheck installcheck-am \
|
||||
installdirs maintainer-clean maintainer-clean-generic \
|
||||
mostlyclean mostlyclean-compile mostlyclean-generic \
|
||||
mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \
|
||||
uninstall-am uninstall-pkglibLTLIBRARIES
|
||||
|
||||
install-exec-hook: $(pkglib_LTLIBRARIES)
|
||||
@echo "Creating Nginx config file..."; \
|
||||
rm -f ../nginx/modsecurity/config; \
|
||||
echo "ngx_addon_name=ngx_http_modsecurity" >> ../nginx/modsecurity/config; \
|
||||
echo "# HTTP_MODULES=\"\$$HTTP_MODULES ngx_http_modsecurity\"" >> ../nginx/modsecurity/config; \
|
||||
echo "HTTP_HEADERS_FILTER_MODULE=\"ngx_http_modsecurity \$$HTTP_HEADERS_FILTER_MODULE\"" >> ../nginx/modsecurity/config; \
|
||||
echo "NGX_ADDON_SRCS=\"\$$NGX_ADDON_SRCS \$$ngx_addon_dir/ngx_http_modsecurity.c \$$ngx_addon_dir/apr_bucket_nginx.c\"" >> ../nginx/modsecurity/config;\
|
||||
echo "NGX_ADDON_DEPS=\"\$$NGX_ADDON_DEPS\"" >> ../nginx/modsecurity/config; \
|
||||
echo "CORE_LIBS=\"\$$CORE_LIBS \$$ngx_addon_dir/../../standalone/.libs/standalone.a -lapr-1 -laprutil-1 -lxml2 -lm @LUA_LDADD@\"" >> ../nginx/modsecurity/config; \
|
||||
echo "CORE_INCS=\"\$$CORE_INCS /usr/include/apache2 /usr/include/apr-1.0 /usr/include/httpd /usr/include/apr-1 \$$ngx_addon_dir \$$ngx_addon_dir/../../standalone \$$ngx_addon_dir/../../apache2 /usr/include/libxml2 `echo @LUA_CFLAGS@ | cut -d "I" -f3`\"" >> ../nginx/modsecurity/config; \
|
||||
echo "have=REQUEST_EARLY . auto/have" >> ../nginx/modsecurity/config;\
|
||||
echo "CORE_MODULES=\"\$$CORE_MODULES ngx_pool_context_module\"" >> ../nginx/modsecurity/config; \
|
||||
echo "HTTP_AUX_FILTER_MODULES=\"ngx_http_modsecurity \$$HTTP_AUX_FILTER_MODULES\"" >> ../nginx/modsecurity/config; \
|
||||
echo "NGX_ADDON_SRCS=\"\$$NGX_ADDON_SRCS \$$ngx_addon_dir/ngx_http_modsecurity.c \$$ngx_addon_dir/apr_bucket_nginx.c \$$ngx_addon_dir/ngx_pool_context.c\"" >> ../nginx/modsecurity/config;\
|
||||
echo "NGX_ADDON_DEPS=\"\$$NGX_ADDON_DEPS \$$ngx_addon_dir/apr_bucket_nginx.h \$$ngx_addon_dir/ngx_pool_context.h \$$ngx_addon_dir/ngx_http_modsecurity.c \$$ngx_addon_dir/apr_bucket_nginx.c \$$ngx_addon_dir/ngx_pool_context.c \"" >> ../nginx/modsecurity/config; \
|
||||
echo "CORE_LIBS=\"\$$CORE_LIBS \$$ngx_addon_dir/../../standalone/.libs/standalone.a $(standalone_LIBS) \"" >> ../nginx/modsecurity/config; \
|
||||
echo "CORE_INCS=\"\$$CORE_INCS \$$ngx_addon_dir \$$ngx_addon_dir/../../standalone \$$ngx_addon_dir/../../apache2 $(standalone_INCS)\"" >> ../nginx/modsecurity/config; \
|
||||
echo "Removing unused static libraries..."; \
|
||||
for m in $(pkglib_LTLIBRARIES); do \
|
||||
base=`echo $$m | sed 's/\..*//'`; \
|
||||
|
193
standalone/api.c
193
standalone/api.c
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
@ -223,40 +223,10 @@ apr_status_t ap_http_in_filter(ap_filter_t *f, apr_bucket_brigade *bb_out,
|
||||
}
|
||||
|
||||
apr_status_t ap_http_out_filter(ap_filter_t *f, apr_bucket_brigade *b) {
|
||||
modsec_rec *msr = (modsec_rec *)f->ctx;
|
||||
apr_status_t rc;
|
||||
apr_bucket_brigade *bb_out;
|
||||
|
||||
bb_out = modsecGetResponseBrigade(f->r);
|
||||
|
||||
|
||||
if (bb_out) {
|
||||
APR_BRIGADE_CONCAT(bb_out, b);
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
// is there a way to tell whether the response body was modified or not?
|
||||
//
|
||||
if((msr->txcfg->content_injection_enabled || msr->content_prepend_len != 0 || msr->content_append_len != 0)
|
||||
&& msr->txcfg->resbody_access) {
|
||||
|
||||
if (modsecWriteResponse != NULL) {
|
||||
char *data = NULL;
|
||||
apr_size_t length;
|
||||
|
||||
rc = apr_brigade_pflatten(msr->of_brigade, &data, &length, msr->mp);
|
||||
|
||||
if (rc != APR_SUCCESS) {
|
||||
msr_log(msr, 1, "Output filter: Failed to flatten brigade (%d): %s", rc,
|
||||
get_apr_error(msr->mp, rc));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* TODO: return ?*/
|
||||
modsecWriteResponse(msr->r, data, msr->stream_output_length);
|
||||
}
|
||||
}
|
||||
apr_bucket_brigade *bb_out = (apr_bucket_brigade *)f->ctx;
|
||||
|
||||
APR_BRIGADE_CONCAT(bb_out, b);
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
@ -551,74 +521,117 @@ int modsecIsResponseBodyAccessEnabled(request_rec *r)
|
||||
}
|
||||
|
||||
int modsecProcessResponse(request_rec *r) {
|
||||
int status = DECLINED;
|
||||
int status;
|
||||
modsec_rec *msr;
|
||||
apr_bucket *e;
|
||||
ap_filter_t *f;
|
||||
apr_bucket_brigade *bb_in, *bb_out, *bb;
|
||||
|
||||
if(r->output_filters != NULL) {
|
||||
modsec_rec *msr = (modsec_rec *)r->output_filters->ctx;
|
||||
char buf[8192];
|
||||
char *tmp = NULL;
|
||||
apr_bucket *e = NULL;
|
||||
if(r->output_filters == NULL) {
|
||||
return DECLINED;
|
||||
}
|
||||
|
||||
msr = (modsec_rec *)r->output_filters->ctx;
|
||||
if (msr == NULL) {
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r->server,
|
||||
"ModSecurity: Internal Error: msr is null in output filter.");
|
||||
ap_remove_output_filter(r->output_filters);
|
||||
return APR_EGENERAL;
|
||||
}
|
||||
|
||||
msr->r = r;
|
||||
|
||||
/* create input response brigade */
|
||||
bb_in = apr_brigade_create(msr->mp, r->connection->bucket_alloc);
|
||||
|
||||
if (bb_in == NULL) {
|
||||
msr_log(msr, 1, "Process response: Failed to create brigade.");
|
||||
return APR_EGENERAL;
|
||||
}
|
||||
|
||||
/* get input response brigade */
|
||||
bb = modsecGetResponseBrigade(r);
|
||||
if (bb != NULL) {
|
||||
APR_BRIGADE_CONCAT(bb_in, bb);
|
||||
if (!APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb_in))) {
|
||||
e = apr_bucket_eos_create(bb_in->bucket_alloc);
|
||||
APR_BRIGADE_INSERT_TAIL(bb_in, e);
|
||||
}
|
||||
} else if (modsecReadResponse != NULL) {
|
||||
unsigned int readcnt = 0;
|
||||
int is_eos = 0;
|
||||
ap_filter_t *f = NULL;
|
||||
apr_bucket_brigade *bb_in, *bb = NULL;
|
||||
char buf[8192];
|
||||
while(!is_eos) {
|
||||
modsecReadResponse(r, buf, 8192, &readcnt, &is_eos);
|
||||
|
||||
if (msr == NULL) {
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r->server,
|
||||
"ModSecurity: Internal Error: msr is null in output filter.");
|
||||
ap_remove_output_filter(r->output_filters);
|
||||
return send_error_bucket(msr, r->output_filters, HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
bb = apr_brigade_create(msr->mp, r->connection->bucket_alloc);
|
||||
|
||||
if (bb == NULL) {
|
||||
msr_log(msr, 1, "Process response: Failed to create brigade.");
|
||||
return APR_EGENERAL;
|
||||
}
|
||||
|
||||
msr->r = r;
|
||||
|
||||
bb_in = modsecGetResponseBrigade(r);
|
||||
|
||||
if (bb_in != NULL) {
|
||||
APR_BRIGADE_CONCAT(bb, bb_in);
|
||||
if (!APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) {
|
||||
e = apr_bucket_eos_create(bb->bucket_alloc);
|
||||
APR_BRIGADE_INSERT_TAIL(bb, e);
|
||||
if(readcnt > 0) {
|
||||
char *tmp = (char *)apr_palloc(r->pool, readcnt);
|
||||
memcpy(tmp, buf, readcnt);
|
||||
e = apr_bucket_pool_create(tmp, readcnt, r->pool, r->connection->bucket_alloc);
|
||||
APR_BRIGADE_INSERT_TAIL(bb_in, e);
|
||||
}
|
||||
} else if (modsecReadResponse != NULL) {
|
||||
while(!is_eos) {
|
||||
modsecReadResponse(r, buf, 8192, &readcnt, &is_eos);
|
||||
}
|
||||
|
||||
if(readcnt > 0) {
|
||||
tmp = (char *)apr_palloc(r->pool, readcnt);
|
||||
memcpy(tmp, buf, readcnt);
|
||||
e = apr_bucket_pool_create(tmp, readcnt, r->pool, r->connection->bucket_alloc);
|
||||
APR_BRIGADE_INSERT_TAIL(bb, e);
|
||||
}
|
||||
e = apr_bucket_eos_create(r->connection->bucket_alloc);
|
||||
APR_BRIGADE_INSERT_TAIL(bb_in, e);
|
||||
} else {
|
||||
/* cannot read response body process header only */
|
||||
|
||||
e = apr_bucket_eos_create(r->connection->bucket_alloc);
|
||||
APR_BRIGADE_INSERT_TAIL(bb_in, e);
|
||||
}
|
||||
|
||||
bb_out = bb ? bb : apr_brigade_create(msr->mp, r->connection->bucket_alloc);
|
||||
|
||||
if (bb_out == NULL) {
|
||||
msr_log(msr, 1, "Process response: Failed to create brigade.");
|
||||
return APR_EGENERAL;
|
||||
}
|
||||
|
||||
/* concat output bucket to bb_out */
|
||||
f = ap_add_output_filter("HTTP_OUT", bb_out, r, r->connection);
|
||||
status = ap_pass_brigade(r->output_filters, bb_in);
|
||||
ap_remove_output_filter(f);
|
||||
|
||||
if (status == APR_EGENERAL) {
|
||||
/* retrive response status from bb_out */
|
||||
for(e = APR_BRIGADE_FIRST(bb_out);
|
||||
e != APR_BRIGADE_SENTINEL(bb_out);
|
||||
e = APR_BUCKET_NEXT(e)) {
|
||||
if (AP_BUCKET_IS_ERROR(e)) {
|
||||
return ((ap_bucket_error*) e->data)->status;
|
||||
}
|
||||
|
||||
e = apr_bucket_eos_create(r->connection->bucket_alloc);
|
||||
APR_BRIGADE_INSERT_TAIL(bb, e);
|
||||
} else {
|
||||
/* cannot read response body process header only */
|
||||
|
||||
e = apr_bucket_eos_create(r->connection->bucket_alloc);
|
||||
APR_BRIGADE_INSERT_TAIL(bb, e);
|
||||
}
|
||||
|
||||
f = ap_add_output_filter("HTTP_OUT", msr, r, r->connection);
|
||||
status = ap_pass_brigade(r->output_filters, bb);
|
||||
ap_remove_output_filter(f);
|
||||
if(status > 0
|
||||
&& msr->intercept_actionset->intercept_status != 0) {
|
||||
status = msr->intercept_actionset->intercept_status;
|
||||
}
|
||||
return APR_EGENERAL;
|
||||
}
|
||||
|
||||
if (status != DECLINED) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return status;
|
||||
/* copy bb_out */
|
||||
// is there a way to tell whether the response body was modified or not?
|
||||
if (modsecWriteResponse != NULL
|
||||
&& (msr->txcfg->content_injection_enabled || msr->content_prepend_len != 0 || msr->content_append_len != 0)
|
||||
&& msr->txcfg->resbody_access) {
|
||||
|
||||
char *data = NULL;
|
||||
apr_size_t length;
|
||||
|
||||
status = apr_brigade_pflatten(msr->of_brigade, &data, &length, msr->mp);
|
||||
|
||||
if (status != APR_SUCCESS) {
|
||||
msr_log(msr, 1, "Output filter: Failed to flatten brigade (%d): %s", status,
|
||||
get_apr_error(msr->mp, status));
|
||||
return APR_EGENERAL;
|
||||
}
|
||||
|
||||
if ( modsecWriteResponse(msr->r, data, msr->stream_output_length) != APR_SUCCESS) {
|
||||
return APR_EGENERAL;
|
||||
}
|
||||
}
|
||||
|
||||
return DECLINED;
|
||||
}
|
||||
|
||||
int modsecFinishRequest(request_rec *r) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
@ -21,7 +21,8 @@ msc_test_SOURCES = msc_test.c \
|
||||
$(top_srcdir)/apache2/msc_gsb.c \
|
||||
$(top_srcdir)/apache2/acmp.c \
|
||||
$(top_srcdir)/apache2/msc_lua.c \
|
||||
$(top_srcdir)/apache2/msc_release.c
|
||||
$(top_srcdir)/apache2/msc_release.c \
|
||||
$(top_srcdir)/apache2/libinjection/sqlparse.c
|
||||
msc_test_CFLAGS = @APXS_CFLAGS@ @APR_CFLAGS@ @APU_CFLAGS@ \
|
||||
@PCRE_CFLAGS@ @LIBXML2_CFLAGS@ @MODSEC_EXTRA_CFLAGS@ @LUA_CFLAGS@
|
||||
msc_test_CPPFLAGS = -I$(top_srcdir)/apache2 \
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
|
18
tests/op/detectSQLi.t
Normal file
18
tests/op/detectSQLi.t
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
type => "op",
|
||||
name => "detectSQLi",
|
||||
input => "",
|
||||
ret => 0
|
||||
},
|
||||
{
|
||||
type => "op",
|
||||
name => "detectSQLi",
|
||||
input => "this is not isqli",
|
||||
ret => 0
|
||||
},
|
||||
{
|
||||
type => "op",
|
||||
name => "detectSQLi",
|
||||
input => "ascii(substring(version() from 1 for 1))",
|
||||
ret => 1
|
||||
}
|
0
tests/regression/nginx/conf/empty.conf
Normal file
0
tests/regression/nginx/conf/empty.conf
Normal file
22
tests/regression/nginx/conf/nginx.conf.template
Normal file
22
tests/regression/nginx/conf/nginx.conf.template
Normal file
@ -0,0 +1,22 @@
|
||||
|
||||
user root;
|
||||
worker_processes 1;
|
||||
daemon on;
|
||||
error_log logs/error.log debug;
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
ModSecurityEnabled [% enable %];
|
||||
ModSecurityConfig [% config %];
|
||||
server {
|
||||
|
||||
listen [% listen %];
|
||||
server_name localhost;
|
||||
location / {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
736
tests/run-regression-tests-nginx.pl
Normal file
736
tests/run-regression-tests-nginx.pl
Normal file
@ -0,0 +1,736 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
# Run regression tests.
|
||||
#
|
||||
# Syntax: run-regression-tests.pl [options] [file [N]]
|
||||
#
|
||||
# All: run-regression-tests.pl
|
||||
# All in file: run-regression-tests.pl file
|
||||
# Nth in file: run-regression-tests.pl file N
|
||||
#
|
||||
use strict;
|
||||
use Time::HiRes qw(gettimeofday sleep);
|
||||
use POSIX qw(WIFEXITED WEXITSTATUS WIFSIGNALED WTERMSIG);
|
||||
use File::Spec qw(rel2abs);
|
||||
use File::Basename qw(basename dirname);
|
||||
use File::Path qw(make_path);
|
||||
use FileHandle;
|
||||
use IPC::Open2 qw(open2);
|
||||
use IPC::Open3 qw(open3);
|
||||
use Getopt::Std;
|
||||
use Data::Dumper;
|
||||
use IO::Socket;
|
||||
use LWP::UserAgent;
|
||||
use Cwd 'abs_path';
|
||||
use Template;
|
||||
use File::Copy::Recursive qw(dircopy);
|
||||
|
||||
my @TYPES = qw(action config misc rule target);
|
||||
my $SCRIPT = basename($0);
|
||||
my $SCRIPT_DIR = File::Spec->rel2abs(dirname($0));
|
||||
my $REG_DIR = "$SCRIPT_DIR/regression";
|
||||
my $NGINX_DIR = "$REG_DIR/nginx";
|
||||
my $NGINX_CONF_TEMP = "$REG_DIR/nginx/conf/nginx.conf.template";
|
||||
my $NGINX = q(/usr/local/nginx/sbin/nginx);
|
||||
|
||||
my $PASSED = 0;
|
||||
my $TOTAL = 0;
|
||||
my $BUFSIZ = 32768;
|
||||
my %C = ();
|
||||
my %FILE = ();
|
||||
my $UA_NAME = "ModSecurity Regression Tests/1.2.3";
|
||||
my $UA = LWP::UserAgent->new;
|
||||
$UA->agent($UA_NAME);
|
||||
|
||||
$SIG{TERM} = $SIG{INT} = \&handle_interrupt;
|
||||
|
||||
my %opt;
|
||||
getopts('A:E:D:C:T:H:a:p:dvh', \%opt);
|
||||
|
||||
if ($opt{d}) {
|
||||
$Data::Dumper::Indent = 1;
|
||||
$Data::Dumper::Terse = 1;
|
||||
$Data::Dumper::Pad = "";
|
||||
$Data::Dumper::Quotekeys = 0;
|
||||
}
|
||||
|
||||
sub usage {
|
||||
print stderr <<"EOT";
|
||||
@_
|
||||
Usage: $SCRIPT [options] [file [N]]
|
||||
|
||||
Options:
|
||||
-P path Specify nginx prefix path (default: $NGINX_DIR)
|
||||
-a file Specify nginx binary (default: $NGINX)
|
||||
-p port Specify nginx port (default: 8088)
|
||||
-v Enable verbose output (details on failure).
|
||||
-d Enable debugging output.
|
||||
-h This help.
|
||||
EOT
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
usage() if ($opt{h});
|
||||
|
||||
### Check nginx binary
|
||||
if (defined $opt{a}) {
|
||||
$NGINX = $opt{a};
|
||||
}
|
||||
else {
|
||||
$opt{a} = $NGINX;
|
||||
}
|
||||
usage("Invalid Apache startup script: $NGINX\n") unless (-e $NGINX);
|
||||
|
||||
|
||||
### Defaults
|
||||
$opt{P} = "$NGINX_DIR" unless (defined $opt{P});
|
||||
|
||||
my $CONF_DIR = "$opt{P}/conf";
|
||||
my $FILES_DIR = "$opt{P}/logs";
|
||||
my $PID_FILE = "$FILES_DIR/nginx.pid";
|
||||
|
||||
$opt{A} = "$FILES_DIR/modsec_audit.log";
|
||||
$opt{D} = "$FILES_DIR/modsec_debug.log";
|
||||
$opt{E} = "$FILES_DIR/error.log";
|
||||
$opt{C} = "$CONF_DIR/nginx.conf";
|
||||
$opt{p} = 8088 unless (defined $opt{p});
|
||||
$opt{v} = 1 if ($opt{d});
|
||||
|
||||
if ( !-d "$opt{P}" ) {
|
||||
make_path($opt{P}) or die $!;
|
||||
}
|
||||
|
||||
if ( !-d "$opt{P}/logs" ) {
|
||||
make_path("$opt{P}/logs") or die $!;
|
||||
}
|
||||
|
||||
if ( !-d "$opt{P}/html" ) {
|
||||
make_path("$opt{P}/html") or die $!;
|
||||
}
|
||||
|
||||
dircopy("$REG_DIR/server_root/htdocs","$opt{P}/html") or die $!;
|
||||
|
||||
%ENV = (
|
||||
%ENV,
|
||||
$NGINX_DIR => $opt{P},
|
||||
SERVER_PORT => $opt{p},
|
||||
SERVER_NAME => "localhost",
|
||||
# TEST_NGX_PREFIX => $NGINX_DIR,
|
||||
# DATA_DIR => $DATA_DIR,
|
||||
# TEMP_DIR => $TEMP_DIR,
|
||||
# UPLOAD_DIR => $UPLOAD_DIR,
|
||||
CONF_DIR => $CONF_DIR,
|
||||
# MODULES_DIR => $MODULES_DIR,
|
||||
LOGS_DIR => $FILES_DIR,
|
||||
SCRIPT_DIR => $SCRIPT_DIR,
|
||||
REGRESSION_DIR => $REG_DIR,
|
||||
DIST_ROOT => File::Spec->rel2abs(dirname("$SCRIPT_DIR/../../..")),
|
||||
AUDIT_LOG => $opt{A},
|
||||
DEBUG_LOG => $opt{D},
|
||||
ERROR_LOG => $opt{E},
|
||||
NGINX_CONF => $opt{C},
|
||||
# HTDOCS => $opt{H},
|
||||
USER_AGENT => $UA_NAME,
|
||||
);
|
||||
|
||||
#dbg("OPTIONS: ", \%opt);
|
||||
|
||||
if (-e "$PID_FILE") {
|
||||
msg("Shutting down previous instance: $PID_FILE");
|
||||
nginx_stop();
|
||||
}
|
||||
|
||||
if (defined $ARGV[0]) {
|
||||
runfile(dirname($ARGV[0]), basename($ARGV[0]), $ARGV[1]);
|
||||
done();
|
||||
}
|
||||
|
||||
for my $type (@TYPES) {
|
||||
my $dir = "$SCRIPT_DIR/regression/$type";
|
||||
my @cfg = ();
|
||||
|
||||
# Get test names
|
||||
opendir(DIR, "$dir") or quit(1, "Failed to open \"$dir\": $!");
|
||||
@cfg = grep { /\.t$/ && -f "$dir/$_" } readdir(DIR);
|
||||
closedir(DIR);
|
||||
|
||||
for my $cfg (sort @cfg) {
|
||||
runfile($dir, $cfg);
|
||||
}
|
||||
}
|
||||
done();
|
||||
|
||||
|
||||
sub runfile {
|
||||
my($dir, $cfg, $testnum) = @_;
|
||||
my $fn = "$dir/$cfg";
|
||||
my @data = ();
|
||||
my $edata;
|
||||
my @C = ();
|
||||
my @test = ();
|
||||
my $teststr;
|
||||
my $n = 0;
|
||||
my $pass = 0;
|
||||
|
||||
open(CFG, "<$fn") or quit(1, "Failed to open \"$fn\": $!");
|
||||
@data = <CFG>;
|
||||
|
||||
$edata = q/@C = (/ . join("", @data) . q/)/;
|
||||
eval $edata;
|
||||
quit(1, "Failed to read test data \"$cfg\": $@") if ($@);
|
||||
|
||||
unless (@C) {
|
||||
msg("\nNo tests defined for $fn");
|
||||
return;
|
||||
}
|
||||
|
||||
msg("\nLoaded ".@C." tests from $fn");
|
||||
for my $t (@C) {
|
||||
$n++;
|
||||
next if (defined $testnum and $n != $testnum);
|
||||
|
||||
my $nginx_up = 0;
|
||||
my %t = %{$t || {}};
|
||||
my $id = sprintf("%3d", $n);
|
||||
my $out = "";
|
||||
my $rc = 0;
|
||||
my $conf_fn;
|
||||
|
||||
# Startup nginx with optionally included conf.
|
||||
if (exists $t{conf} and defined $t{conf}) {
|
||||
$conf_fn = sprintf "%s/%s_%s_%06d.conf",
|
||||
$CONF_DIR, $t{type}, $cfg, $n;
|
||||
#dbg("Writing test config to: $conf_fn");
|
||||
open(CONF, ">$conf_fn") or die "Failed to open conf \"$conf_fn\": $!\n";
|
||||
print CONF (ref $t{conf} eq "CODE" ? eval { &{$t{conf}} } : $t{conf});
|
||||
msg("$@") if ($@);
|
||||
close CONF;
|
||||
my %conf=(config => $conf_fn, enable => "on");
|
||||
$nginx_up = nginx_start($t, \%conf) ? 0 : 1;
|
||||
}
|
||||
else {
|
||||
$nginx_up = nginx_start($t) ? 0 : 1;
|
||||
}
|
||||
|
||||
# Run any prerun setup
|
||||
if ($rc == 0 and exists $t{prerun} and defined $t{prerun}) {
|
||||
vrb("Executing perl prerun...");
|
||||
$rc = &{$t{prerun}};
|
||||
vrb("Perl prerun returned: $rc");
|
||||
}
|
||||
|
||||
if ($nginx_up) {
|
||||
# Perform the request and check response
|
||||
if (exists $t{request}) {
|
||||
my $resp = do_request($t{request});
|
||||
if (!$resp) {
|
||||
msg("invalid response");
|
||||
vrb("RESPONSE: ", $resp);
|
||||
$rc = 1;
|
||||
}
|
||||
else {
|
||||
for my $key (keys %{ $t{match_response} || {}}) {
|
||||
my($neg,$mtype) = ($key =~ m/^(-?)(.*)$/);
|
||||
my $m = $t{match_response}{$key};
|
||||
my $match = match_response($mtype, $resp, $m);
|
||||
if ($neg and defined $match) {
|
||||
$rc = 1;
|
||||
msg("response $mtype matched: $m");
|
||||
vrb($resp);
|
||||
last;
|
||||
}
|
||||
elsif (!$neg and !defined $match) {
|
||||
$rc = 1;
|
||||
msg("response $mtype failed to match: $m");
|
||||
vrb($resp);
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Run any arbitrary perl tests
|
||||
if ($rc == 0 and exists $t{test} and defined $t{test}) {
|
||||
dbg("Executing perl test(s)...");
|
||||
$rc = eval { &{$t{test}} };
|
||||
if (! defined $rc) {
|
||||
msg("Error running test: $@");
|
||||
$rc = -1;
|
||||
}
|
||||
dbg("Perl tests returned: $rc");
|
||||
}
|
||||
|
||||
# Search for all log matches
|
||||
if ($rc == 0 and exists $t{match_log} and defined $t{match_log}) {
|
||||
for my $key (keys %{ $t{match_log} || {}}) {
|
||||
my($neg,$mtype) = ($key =~ m/^(-?)(.*)$/);
|
||||
my $m = $t{match_log}{$key};
|
||||
my $match = match_log($mtype, @{$m || []});
|
||||
if ($neg and defined $match) {
|
||||
$rc = 1;
|
||||
msg("$mtype log matched: $m->[0]");
|
||||
last;
|
||||
}
|
||||
elsif (!$neg and !defined $match) {
|
||||
$rc = 1;
|
||||
msg("$mtype log failed to match: $m->[0]");
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Search for all file matches
|
||||
if ($rc == 0 and exists $t{match_file} and defined $t{match_file}) {
|
||||
sleep 1; # Make sure the file exists
|
||||
for my $key (keys %{ $t{match_file} || {}}) {
|
||||
my($neg,$fn) = ($key =~ m/^(-?)(.*)$/);
|
||||
my $m = $t{match_file}{$key};
|
||||
my $match = match_file($fn, $m);
|
||||
if ($neg and defined $match) {
|
||||
$rc = 1;
|
||||
msg("$fn file matched: $m");
|
||||
last;
|
||||
}
|
||||
elsif (!$neg and !defined $match) {
|
||||
$rc = 1;
|
||||
msg("$fn file failed match: $m");
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
msg("Failed to start nginx.");
|
||||
$rc = 1;
|
||||
}
|
||||
|
||||
if ($rc == 0) {
|
||||
$pass++;
|
||||
}
|
||||
else {
|
||||
vrb("Test Config: $conf_fn");
|
||||
vrb("Debug Log: $FILE{debug}{fn}");
|
||||
dbg(escape("$FILE{debug}{buf}"));
|
||||
vrb("Error Log: $FILE{error}{fn}");
|
||||
dbg(escape("$FILE{error}{buf}"));
|
||||
}
|
||||
|
||||
msg(sprintf("%s) %s%s: %s%s", $id, $t{type}, (exists($t{comment}) ? " - $t{comment}" : ""), ($rc ? "failed" : "passed"), ((defined($out) && $out ne "")? " ($out)" : "")));
|
||||
|
||||
if ($nginx_up) {
|
||||
$nginx_up = nginx_stop(\%t) ? 0 : 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$TOTAL += $testnum ? 1 : $n;
|
||||
$PASSED += $pass;
|
||||
|
||||
msg(sprintf("Passed: %2d; Failed: %2d", $pass, $testnum ? (1 - $pass) : ($n - $pass)));
|
||||
}
|
||||
|
||||
# Take out any indenting and translate LF -> CRLF
|
||||
sub normalize_raw_request_data {
|
||||
my $r = $_[0];
|
||||
|
||||
# Allow for indenting in test file
|
||||
$r =~ s/^[ \t]*\x0d?\x0a//s;
|
||||
my($indention) = ($r =~ m/^([ \t]*)/s); # indention taken from first line
|
||||
$r =~ s/^$indention//mg;
|
||||
$r =~ s/(\x0d?\x0a)[ \t]+$/$1/s;
|
||||
|
||||
# Translate LF to CRLF
|
||||
$r =~ s/^\x0a/\x0d\x0a/mg;
|
||||
$r =~ s/([^\x0d])\x0a/$1\x0d\x0a/mg;
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
sub do_raw_request {
|
||||
my $sock = new IO::Socket::INET(
|
||||
Proto => "tcp",
|
||||
PeerAddr => "localhost",
|
||||
PeerPort => $opt{p},
|
||||
) or msg("Failed to connect to localhost:$opt{p}: $@");
|
||||
return unless ($sock);
|
||||
|
||||
# Join togeather the request
|
||||
my $r = join("", @_);
|
||||
dbg($r);
|
||||
|
||||
# Write to socket
|
||||
print $sock "$r";
|
||||
$sock->shutdown(1);
|
||||
|
||||
# Read from socket
|
||||
my @resp = <$sock>;
|
||||
$sock->close();
|
||||
|
||||
return HTTP::Response->parse(join("", @resp));
|
||||
}
|
||||
|
||||
sub do_request {
|
||||
my $r = $_[0];
|
||||
|
||||
# Allow test to execute code
|
||||
if (ref $r eq "CODE") {
|
||||
$r = eval { &$r };
|
||||
msg("$@") unless (defined $r);
|
||||
}
|
||||
|
||||
if (ref $r eq "HTTP::Request") {
|
||||
my $resp = $UA->request($r);
|
||||
dbg($resp->request()->as_string()) if ($opt{d});
|
||||
return $resp
|
||||
}
|
||||
else {
|
||||
return do_raw_request($r);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
sub match_response {
|
||||
my($name, $resp, $re) = @_;
|
||||
|
||||
msg("Warning: Empty regular expression.") if (!defined $re or $re eq "");
|
||||
|
||||
if ($name eq "status") {
|
||||
return $& if ($resp->code =~ m/$re/);
|
||||
}
|
||||
elsif ($name eq "content") {
|
||||
return $& if ($resp->content =~ m/$re/m);
|
||||
}
|
||||
elsif ($name eq "raw") {
|
||||
return $& if ($resp->as_string =~ m/$re/m);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
sub read_log {
|
||||
my($name, $timeout, $graph) = @_;
|
||||
return match_log($name, undef, $timeout, $graph);
|
||||
}
|
||||
|
||||
sub match_log {
|
||||
my($name, $re, $timeout, $graph) = @_;
|
||||
my $t0 = gettimeofday;
|
||||
my($fh,$rbuf) = ($FILE{$name}{fd}, \$FILE{$name}{buf});
|
||||
my $n = length($$rbuf);
|
||||
my $rc = undef;
|
||||
|
||||
unless (defined $fh) {
|
||||
msg("Error: File \"$name\" is not opened for matching.");
|
||||
return;
|
||||
}
|
||||
|
||||
$timeout = 0 unless (defined $timeout);
|
||||
|
||||
my $i = 0;
|
||||
my $graphed = 0;
|
||||
READ: {
|
||||
do {
|
||||
my $nbytes = $fh->sysread($$rbuf, $BUFSIZ, $n);
|
||||
if (!defined($nbytes)) {
|
||||
msg("Error: Could not read \"$name\" log: $!");
|
||||
last;
|
||||
}
|
||||
elsif (!defined($re) and $nbytes == 0) {
|
||||
last;
|
||||
}
|
||||
|
||||
# Remove APR pool debugging
|
||||
$$rbuf =~ s/POOL DEBUG:[^\n]+PALLOC[^\n]+\n//sg;
|
||||
|
||||
$n = length($$rbuf);
|
||||
|
||||
#dbg("Match \"$re\" in $name \"$$rbuf\" ($n)");
|
||||
if ($$rbuf =~ m/$re/m) {
|
||||
$rc = $&;
|
||||
last;
|
||||
}
|
||||
# TODO: Use select()/poll()
|
||||
sleep 0.1 unless ($nbytes == $BUFSIZ);
|
||||
if ($graph and $opt{d}) {
|
||||
$i++;
|
||||
if ($i == 10) {
|
||||
$graphed++;
|
||||
$i=0;
|
||||
print STDERR $graph if ($graphed == 1);
|
||||
print STDERR "."
|
||||
}
|
||||
}
|
||||
} while (gettimeofday - $t0 < $timeout);
|
||||
}
|
||||
print STDERR "\n" if ($graphed);
|
||||
|
||||
return $rc;
|
||||
}
|
||||
|
||||
sub match_file {
|
||||
my($neg,$fn) = ($_[0] =~ m/^(-?)(.*)$/);
|
||||
unless (exists $FILE{$fn}) {
|
||||
eval {
|
||||
$FILE{$fn}{fn} = $fn;
|
||||
$FILE{$fn}{fd} = new FileHandle($fn, O_RDONLY) or die "$!\n";
|
||||
$FILE{$fn}{fd}->blocking(0);
|
||||
$FILE{$fn}{buf} = "";
|
||||
};
|
||||
if ($@) {
|
||||
msg("Warning: Failed to open file \"$fn\": $@");
|
||||
return;
|
||||
}
|
||||
}
|
||||
return match_log($_[0], $_[1]); # timeout makes no sense
|
||||
}
|
||||
|
||||
sub quote_shell {
|
||||
my($s) = @_;
|
||||
return $s unless ($s =~ m|[^\w!%+,\-./:@^]|);
|
||||
$s =~ s/(['\\])/\\$1/g;
|
||||
return "'$s'";
|
||||
}
|
||||
|
||||
sub escape {
|
||||
my @new = ();
|
||||
for my $c (split(//, $_[0])) {
|
||||
my $oc = ord($c);
|
||||
push @new, ((($oc >= 0x20 and $oc <= 0x7e) or $oc == 0x0a or $oc == 0x0d) ? $c : sprintf("\\x%02x", ord($c)));
|
||||
}
|
||||
join('', @new);
|
||||
}
|
||||
|
||||
sub dbg {
|
||||
return unless(@_ and $opt{d});
|
||||
my $out = join "", map {
|
||||
(ref $_ ne "" ? Dumper($_) : $_)
|
||||
} @_;
|
||||
$out =~ s/^/DBG: /mg;
|
||||
print STDOUT "$out\n";
|
||||
}
|
||||
|
||||
sub vrb {
|
||||
return unless(@_ and $opt{v});
|
||||
msg(@_);
|
||||
}
|
||||
|
||||
sub msg {
|
||||
return unless(@_);
|
||||
my $out = join "", map {
|
||||
(ref $_ ne "" ? Dumper($_) : $_)
|
||||
} @_;
|
||||
print STDOUT "$out\n";
|
||||
}
|
||||
|
||||
sub handle_interrupt {
|
||||
$SIG{TERM} = $SIG{INT} = \&handle_interrupt;
|
||||
|
||||
msg("Interrupted via SIG$_[0]. Shutting down tests...");
|
||||
nginx_stop();
|
||||
|
||||
quit(1);
|
||||
}
|
||||
|
||||
sub quit {
|
||||
my($ec,$msg) = @_;
|
||||
$ec = 0 unless (defined $_[0]);
|
||||
|
||||
msg("$msg") if (defined $msg);
|
||||
|
||||
exit $ec;
|
||||
}
|
||||
|
||||
sub done {
|
||||
if ($PASSED != $TOTAL) {
|
||||
quit(1, "\n$PASSED/$TOTAL tests passed.");
|
||||
}
|
||||
|
||||
quit(0, "\nAll tests passed ($TOTAL).");
|
||||
}
|
||||
|
||||
sub nginx_stop {
|
||||
my $t = shift;
|
||||
my @p = (
|
||||
$NGINX,
|
||||
-p => $opt{P},
|
||||
-s => "quit",
|
||||
);
|
||||
|
||||
my $nginx_out;
|
||||
my $nginx_pid = open3(undef, $nginx_out, undef, @p) or quit(1);
|
||||
my $out = join("\\n", grep(!/POOL DEBUG/, (<$nginx_out>)));
|
||||
close $nginx_out;
|
||||
waitpid($nginx_pid, 0);
|
||||
|
||||
my $rc = $?;
|
||||
if ( WIFEXITED($rc) ) {
|
||||
$rc = WEXITSTATUS($rc);
|
||||
vrb("Nginx stop returned with $rc.") if ($rc);
|
||||
}
|
||||
elsif( WIFSIGNALED($rc) ) {
|
||||
msg("Nginx stop failed with signal " . WTERMSIG($rc) . ".");
|
||||
$rc = -1;
|
||||
}
|
||||
else {
|
||||
msg("Nginx stop failed with unknown error.");
|
||||
$rc = -1;
|
||||
}
|
||||
|
||||
sleep 0.5;
|
||||
if (-e $PID_FILE) {
|
||||
msg("Nginx stop failed: $PID_FILE still exists");
|
||||
}
|
||||
|
||||
return $rc;
|
||||
}
|
||||
|
||||
|
||||
sub nginx_reset_fd {
|
||||
my($t) = @_;
|
||||
|
||||
# Cleanup
|
||||
for my $key (keys %FILE) {
|
||||
if (exists $FILE{$key}{fd} and defined $FILE{$key}{fd}) {
|
||||
$FILE{$key}{fd}->close();
|
||||
}
|
||||
delete $FILE{$key};
|
||||
}
|
||||
|
||||
# Error
|
||||
eval {
|
||||
$FILE{error}{fn} = $opt{E};
|
||||
$FILE{error}{fd} = new FileHandle($opt{E}, O_RDWR|O_CREAT) or die "$!\n";
|
||||
$FILE{error}{fd}->blocking(0);
|
||||
$FILE{error}{fd}->sysseek(0, 2);
|
||||
$FILE{error}{buf} = "";
|
||||
};
|
||||
if ($@) {
|
||||
msg("Warning: Failed to open file \"$opt{E}\": $@");
|
||||
return undef;
|
||||
}
|
||||
|
||||
# Audit
|
||||
eval {
|
||||
$FILE{audit}{fn} = $opt{A};
|
||||
$FILE{audit}{fd} = new FileHandle($opt{A}, O_RDWR|O_CREAT) or die "$!\n";
|
||||
$FILE{audit}{fd}->blocking(0);
|
||||
$FILE{audit}{fd}->sysseek(0, 2);
|
||||
$FILE{audit}{buf} = "";
|
||||
};
|
||||
if ($@) {
|
||||
msg("Warning: Failed to open file \"$opt{A}\": $@");
|
||||
return undef;
|
||||
}
|
||||
|
||||
# Debug
|
||||
eval {
|
||||
$FILE{debug}{fn} = $opt{D};
|
||||
$FILE{debug}{fd} = new FileHandle($opt{D}, O_RDWR|O_CREAT) or die "$!\n";
|
||||
$FILE{debug}{fd}->blocking(0);
|
||||
$FILE{debug}{fd}->sysseek(0, 2);
|
||||
$FILE{debug}{buf} = "";
|
||||
};
|
||||
if ($@) {
|
||||
msg("Warning: Failed to open file \"$opt{D}\": $@");
|
||||
return undef;
|
||||
}
|
||||
|
||||
# Any extras listed in "match_log"
|
||||
if ($t and exists $t->{match_log}) {
|
||||
for my $k (keys %{ $t->{match_log} || {} }) {
|
||||
my($neg,$fn) = ($k =~ m/^(-?)(.*)$/);
|
||||
next if (!$fn or exists $FILE{$fn});
|
||||
eval {
|
||||
$FILE{$fn}{fn} = $fn;
|
||||
$FILE{$fn}{fd} = new FileHandle($fn, O_RDWR|O_CREAT) or die "$!\n";
|
||||
$FILE{$fn}{fd}->blocking(0);
|
||||
$FILE{$fn}{fd}->sysseek(0, 2);
|
||||
$FILE{$fn}{buf} = "";
|
||||
};
|
||||
if ($@) {
|
||||
msg("Warning: Failed to open file \"$fn\": $@");
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub encode_chunked {
|
||||
my($data, $size) = @_;
|
||||
$size = 128 unless ($size);
|
||||
my $chunked = "";
|
||||
|
||||
my $n = 0;
|
||||
my $bytes = length($data);
|
||||
while ($bytes >= $size) {
|
||||
$chunked .= sprintf "%x\x0d\x0a%s\x0d\x0a", $size, substr($data, $n, $size);
|
||||
$n += $size;
|
||||
$bytes -= $size;
|
||||
}
|
||||
if ($bytes) {
|
||||
$chunked .= sprintf "%x\x0d\x0a%s\x0d\x0a", $bytes, substr($data, $n, $bytes);
|
||||
}
|
||||
$chunked .= "0\x0d\x0a\x0d\x0a"
|
||||
}
|
||||
|
||||
sub nginx_start {
|
||||
my ($t) = shift;
|
||||
my($C) = shift;
|
||||
|
||||
my %conf = (
|
||||
listen => "$opt{p}",
|
||||
config => "$REG_DIR/nginx/conf/empty.conf",
|
||||
enable => "off",
|
||||
);
|
||||
|
||||
while(my($k,$v)= each %$C){
|
||||
$conf{$k}=$v;
|
||||
}
|
||||
|
||||
my ($tt) = Template->new(INCLUDE_PATH => "$REG_DIR/nginx/conf/");
|
||||
my ($output);
|
||||
$tt->process("nginx.conf.template", \%conf, \$output) || die $tt->error;
|
||||
|
||||
open (OUTFILE, ">$opt{C}");
|
||||
print OUTFILE "$output";
|
||||
close(OUTFILE);
|
||||
|
||||
nginx_reset_fd($t);
|
||||
|
||||
my @p = ($NGINX, -p => $opt{P});
|
||||
|
||||
my $nginx_out;
|
||||
my $nginx_pid = open3(undef, $nginx_out, undef, @p) or quit(1);
|
||||
my $out = join("\\n", grep(!/POOL DEBUG/, (<$nginx_out>)));
|
||||
close $nginx_out;
|
||||
waitpid($nginx_pid, 0);
|
||||
|
||||
my $rc = $?;
|
||||
if ( WIFEXITED($rc) ) {
|
||||
$rc = WEXITSTATUS($rc);
|
||||
vrb("Nginx start returned with $rc.") if ($rc);
|
||||
}
|
||||
elsif( WIFSIGNALED($rc) ) {
|
||||
msg("Nginx start failed with signal " . WTERMSIG($rc) . ".");
|
||||
$rc = -1;
|
||||
}
|
||||
else {
|
||||
msg("Nginx start failed with unknown error.");
|
||||
$rc = -1;
|
||||
}
|
||||
|
||||
# Look for startup msg
|
||||
# unless (defined match_log("error", qr/start worker process/, 60, "Waiting on nginx to start: ")) {
|
||||
# vrb(join(" ", map { quote_shell($_) } @p));
|
||||
# vrb(match_log("error", qr/(^.*ModSecurity: .*)/sm, 10));
|
||||
# msg("Nginx server failed to start.");
|
||||
# nginx_stop();
|
||||
# return -1;
|
||||
# }
|
||||
|
||||
return $rc;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user