mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-14 05:45:59 +03:00
commit
876d4f5f95
24
CHANGES
24
CHANGES
@ -1,3 +1,27 @@
|
||||
23 Jul 2013 - 2.7.5
|
||||
-------------------
|
||||
Improvements:
|
||||
|
||||
* SecUnicodeCodePage is deprecated. SecUnicodeMapFile now accepts the code page as a second parameter.
|
||||
|
||||
* Updated Libinjection to version 3.4.1. Many improvements were made.
|
||||
|
||||
* Severity action now supports strings (emergency, alert, critical, error, warning, notice, info, debug).
|
||||
|
||||
Bug Fixes:
|
||||
|
||||
* Fixed utf8toUnicode tfn null byte conversion.
|
||||
|
||||
* Fixed NGINX crash when issue reload command.
|
||||
|
||||
* Fixed flush output buffer before inject modified hashed response body.
|
||||
|
||||
* Fixed url normalization for Hash Engine.
|
||||
|
||||
* Fixed NGINX ap_unixd_set_global_perms_mutex compilation error with apache 2.4 devel files.
|
||||
|
||||
Security Issues:
|
||||
|
||||
10 May 2013 - 2.7.4
|
||||
-------------------
|
||||
Improvements:
|
||||
|
@ -11,7 +11,8 @@ 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 libinjection/sqlparse.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/libinjection_sqli.c
|
||||
|
||||
mod_security2_la_CFLAGS = @APXS_CFLAGS@ @APR_CFLAGS@ @APU_CFLAGS@ \
|
||||
@PCRE_CFLAGS@ @LIBXML2_CFLAGS@ @LUA_CFLAGS@ @MODSEC_EXTRA_CFLAGS@ @CURL_CFLAGS@
|
||||
@ -72,7 +73,7 @@ install-exec-hook: $(pkglib_LTLIBRARIES)
|
||||
for m in $(pkglib_LTLIBRARIES); do \
|
||||
base=`echo $$m | sed 's/\..*//'`; \
|
||||
rm -f $(DESTDIR)$(pkglibdir)/$$base.*a; \
|
||||
install -D -m444 $(DESTDIR)$(pkglibdir)/$$base.so $(DESTDIR)$(APXS_MODULES); \
|
||||
install -D -m444 $(DESTDIR)$(pkglibdir)/$$base.so $(DESTDIR)$(APXS_MODULES)/$$base.so; \
|
||||
done
|
||||
else
|
||||
install-exec-hook: $(pkglib_LTLIBRARIES)
|
||||
|
@ -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 libinjection\sqlparse.obj
|
||||
msc_release.obj libinjection\libinjection_sqli.obj
|
||||
|
||||
all: $(DLL)
|
||||
|
||||
|
@ -2656,6 +2656,8 @@ static const char *cmd_geo_lookup_db(cmd_parms *cmd, void *_dcfg,
|
||||
/**
|
||||
* \brief Add SecUnicodeCodePage configuration option
|
||||
*
|
||||
* Depcrecated
|
||||
*
|
||||
* \param cmd Pointer to configuration data
|
||||
* \param _dcfg Pointer to directory configuration
|
||||
* \param p1 Pointer to configuration option
|
||||
@ -2688,13 +2690,24 @@ static const char *cmd_unicode_codepage(cmd_parms *cmd,
|
||||
* \retval NULL On success
|
||||
*/
|
||||
static const char *cmd_unicode_map(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
const char *p1, const char *p2)
|
||||
{
|
||||
const char *filename = resolve_relative_path(cmd->pool, cmd->directive->filename, p1);
|
||||
char *error_msg;
|
||||
long val = 0;
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
if (dcfg == NULL) return NULL;
|
||||
|
||||
if(p2 != NULL) {
|
||||
val = atol(p2);
|
||||
if (val <= 0) {
|
||||
return apr_psprintf(cmd->pool, "ModSecurity: Invalid setting for "
|
||||
"SecUnicodeMapFile: %s", p2);
|
||||
}
|
||||
|
||||
unicode_codepage = (unsigned long int)val;
|
||||
}
|
||||
|
||||
if (unicode_map_init(dcfg, filename, &error_msg) <= 0) {
|
||||
return error_msg;
|
||||
}
|
||||
@ -3069,7 +3082,7 @@ const command_rec module_directives[] = {
|
||||
"Unicode CodePage"
|
||||
),
|
||||
|
||||
AP_INIT_TAKE1 (
|
||||
AP_INIT_TAKE12 (
|
||||
"SecUnicodeMapFile",
|
||||
cmd_unicode_map,
|
||||
NULL,
|
||||
|
@ -588,7 +588,7 @@ static int flatten_response_body(modsec_rec *msr) {
|
||||
}
|
||||
|
||||
memset(msr->stream_output_data, 0, msr->stream_output_length+1);
|
||||
strncpy(msr->stream_output_data, msr->resbody_data, msr->stream_output_length);
|
||||
memcpy(msr->stream_output_data, msr->resbody_data, msr->stream_output_length);
|
||||
msr->stream_output_data[msr->stream_output_length] = '\0';
|
||||
} else if (msr->txcfg->stream_outbody_inspection && msr->txcfg->hash_is_enabled == HASH_ENABLED) {
|
||||
int retval = 0;
|
||||
@ -617,7 +617,7 @@ static int flatten_response_body(modsec_rec *msr) {
|
||||
}
|
||||
|
||||
memset(msr->stream_output_data, 0, msr->stream_output_length+1);
|
||||
strncpy(msr->stream_output_data, msr->resbody_data, msr->stream_output_length);
|
||||
memcpy(msr->stream_output_data, msr->resbody_data, msr->stream_output_length);
|
||||
msr->stream_output_data[msr->stream_output_length] = '\0';
|
||||
}
|
||||
}
|
||||
|
286
apache2/libinjection/libinjection.h
Normal file
286
apache2/libinjection/libinjection.h
Normal file
@ -0,0 +1,286 @@
|
||||
/**
|
||||
* Copyright 2012, 2013 Nick Galbreath
|
||||
* nickg@client9.com
|
||||
* BSD License -- see COPYING.txt for details
|
||||
*
|
||||
* https://libinjection.client9.com/
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _LIBINJECTION_H
|
||||
#define _LIBINJECTION_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 "3.4.1"
|
||||
|
||||
/**
|
||||
* Libinjection's sqli module makes a "normalized"
|
||||
* value of the token. This is the maximum size
|
||||
* Token with values larger than this will be truncated
|
||||
*/
|
||||
#ifndef LIBINJECTION_SQLI_TOKEN_SIZE
|
||||
#define LIBINJECTION_SQLI_TOKEN_SIZE 32
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Number of tokens used to create a fingerprint
|
||||
*/
|
||||
#ifndef LIBINJECTION_SQLI_MAX_TOKENS
|
||||
#define LIBINJECTION_SQLI_MAX_TOKENS 5
|
||||
#endif
|
||||
|
||||
enum lookup_type {
|
||||
FLAG_NONE = 0,
|
||||
FLAG_QUOTE_NONE = 1 << 1,
|
||||
FLAG_QUOTE_SINGLE = 1 << 2,
|
||||
FLAG_QUOTE_DOUBLE = 1 << 3,
|
||||
|
||||
FLAG_SQL_ANSI = 1 << 4,
|
||||
FLAG_SQL_MYSQL = 1 << 5,
|
||||
|
||||
LOOKUP_WORD,
|
||||
LOOKUP_TYPE,
|
||||
LOOKUP_OPERATOR,
|
||||
LOOKUP_FINGERPRINT
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
#ifdef SWIG
|
||||
%immutable;
|
||||
#endif
|
||||
char type;
|
||||
char str_open;
|
||||
char str_close;
|
||||
|
||||
/*
|
||||
* position and length of token
|
||||
* in original string
|
||||
*/
|
||||
size_t pos;
|
||||
size_t len;
|
||||
|
||||
/* count:
|
||||
* in type 'v', used for number of opening '@'
|
||||
* but maybe unsed in other contexts
|
||||
*/
|
||||
int count;
|
||||
|
||||
char val[LIBINJECTION_SQLI_TOKEN_SIZE];
|
||||
} stoken_t;
|
||||
|
||||
|
||||
/**
|
||||
* Pointer to function, takes cstr input,
|
||||
* returns '\0' for no match, else a char
|
||||
*/
|
||||
struct libinjection_sqli_state;
|
||||
typedef char (*ptr_lookup_fn)(struct libinjection_sqli_state*, int lookuptype, const char* word, size_t len);
|
||||
|
||||
typedef struct libinjection_sqli_state {
|
||||
#ifdef SWIG
|
||||
%immutable;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* input, does not need to be null terminated.
|
||||
* it is also not modified.
|
||||
*/
|
||||
const char *s;
|
||||
|
||||
/*
|
||||
* input length
|
||||
*/
|
||||
size_t slen;
|
||||
|
||||
/*
|
||||
* How to lookup a word or fingerprint
|
||||
*/
|
||||
ptr_lookup_fn lookup;
|
||||
void* userdata;
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
int flags;
|
||||
|
||||
/*
|
||||
* pos is index in string we are at when tokenizing
|
||||
*/
|
||||
size_t pos;
|
||||
|
||||
/* MAX TOKENS + 1 since we use one extra token
|
||||
* to determine the type of the previous token
|
||||
*/
|
||||
stoken_t tokenvec[LIBINJECTION_SQLI_MAX_TOKENS + 1];
|
||||
|
||||
/*
|
||||
* Pointer to token position in tokenvec, above
|
||||
*/
|
||||
stoken_t *current;
|
||||
|
||||
/*
|
||||
* fingerprint pattern c-string
|
||||
* +1 for ending null
|
||||
*/
|
||||
char fingerprint[LIBINJECTION_SQLI_MAX_TOKENS + 1];
|
||||
|
||||
/*
|
||||
* Line number of code that said decided if the input was SQLi or
|
||||
* not. Most of the time it's line that said "it's not a matching
|
||||
* fingerprint" but there is other logic that sometimes approves
|
||||
* an input. This is only useful for debugging.
|
||||
*
|
||||
*/
|
||||
int reason;
|
||||
|
||||
/* Number of ddw (dash-dash-white) comments
|
||||
* These comments are in the form of
|
||||
* '--[whitespace]' or '--[EOF]'
|
||||
*
|
||||
* All databases treat this as a comment.
|
||||
*/
|
||||
int stats_comment_ddw;
|
||||
|
||||
/* Number of ddx (dash-dash-[notwhite]) comments
|
||||
*
|
||||
* ANSI SQL treats these are comments, MySQL treats this as
|
||||
* two unary operators '-' '-'
|
||||
*
|
||||
* If you are parsing result returns FALSE and
|
||||
* stats_comment_dd > 0, you should reparse with
|
||||
* COMMENT_MYSQL
|
||||
*
|
||||
*/
|
||||
int stats_comment_ddx;
|
||||
|
||||
/*
|
||||
* c-style comments found /x .. x/
|
||||
*/
|
||||
int stats_comment_c;
|
||||
|
||||
/* '#' operators or mysql EOL comments found
|
||||
*
|
||||
*/
|
||||
int stats_comment_hash;
|
||||
|
||||
/*
|
||||
* number of tokens folded away
|
||||
*/
|
||||
int stats_folds;
|
||||
|
||||
/*
|
||||
* total tokens processed
|
||||
*/
|
||||
int stats_tokens;
|
||||
|
||||
} sfilter;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void libinjection_sqli_init(sfilter* sql_state,
|
||||
const char* s, size_t slen,
|
||||
int flags);
|
||||
|
||||
/**
|
||||
* Main API: tests for SQLi in three possible contexts, no quotes,
|
||||
* single quote and double quote
|
||||
*
|
||||
* \param sql_state
|
||||
* \param s
|
||||
* \param slen
|
||||
* \param fn a pointer to a function that determines if a fingerprint
|
||||
* is a match or not. If NULL, then a hardwired list is
|
||||
* used. Useful for loading fingerprints data from custom
|
||||
* sources.
|
||||
*
|
||||
* \return 1 (true) if SQLi, 0 (false) if benign
|
||||
*/
|
||||
int libinjection_is_sqli(sfilter * sql_state);
|
||||
|
||||
/* FOR H@CKERS ONLY
|
||||
*
|
||||
*/
|
||||
void libinjection_sqli_callback(sfilter* sql_state, ptr_lookup_fn fn, void* userdata);
|
||||
|
||||
|
||||
/*
|
||||
* Resets state, but keeps initial string and callbacks
|
||||
*/
|
||||
void libinjection_sqli_reset(sfilter* sql_state, int flags);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* This detects SQLi in a single context, mostly useful for custom
|
||||
* logic and debugging.
|
||||
*
|
||||
* \param sql_state
|
||||
*
|
||||
* \returns a pointer to sfilter.fingerprint as convenience
|
||||
* do not free!
|
||||
*
|
||||
*/
|
||||
const char* libinjection_sqli_fingerprint(sfilter * sql_state, int flags);
|
||||
|
||||
/**
|
||||
* The default "word" to token-type or fingerprint function. This
|
||||
* uses a ASCII case-insensitive binary tree.
|
||||
*/
|
||||
char libinjection_sqli_lookup_word(sfilter *sql_state, int lookup_type,
|
||||
const char* s, size_t slen);
|
||||
|
||||
/* Streaming tokenization interface.
|
||||
*
|
||||
* sql_state->current is updated with the current token.
|
||||
*
|
||||
* \returns 1, has a token, keep going, or 0 no tokens
|
||||
*
|
||||
*/
|
||||
int libinjection_sqli_tokenize(sfilter * sql_state);
|
||||
|
||||
/**
|
||||
* parses and folds input, up to 5 tokens
|
||||
*
|
||||
*/
|
||||
int libinjection_sqli_fold(sfilter * sql_state);
|
||||
|
||||
/** The built-in default function to match fingerprints
|
||||
* and do false negative/positive analysis. This calls the following
|
||||
* two functions. With this, you over-ride one part or the other.
|
||||
*
|
||||
* return libinjection_sqli_blacklist(sql_state) &&
|
||||
* libinject_sqli_not_whitelist(sql_state);
|
||||
*
|
||||
* \param sql_state should be filled out after libinjection_sqli_fingerprint is called
|
||||
*/
|
||||
int libinjection_sqli_check_fingerprint(sfilter *sql_state);
|
||||
|
||||
/* Given a pattern determine if it's a SQLi pattern.
|
||||
*
|
||||
* \return TRUE if sqli, false otherwise
|
||||
*/
|
||||
int libinjection_sqli_blacklist(sfilter* sql_state);
|
||||
|
||||
/* Given a positive match for a pattern (i.e. pattern is SQLi), this function
|
||||
* does additional analysis to reduce false positives.
|
||||
*
|
||||
* \return TRUE if sqli, false otherwise
|
||||
*/
|
||||
int libinjection_sqli_not_whitelist(sfilter* sql_state);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LIBINJECTION_H */
|
2082
apache2/libinjection/libinjection_sqli.c
Normal file
2082
apache2/libinjection/libinjection_sqli.c
Normal file
File diff suppressed because it is too large
Load Diff
10228
apache2/libinjection/libinjection_sqli_data.h
Normal file
10228
apache2/libinjection/libinjection_sqli_data.h
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,113 +0,0 @@
|
||||
/**
|
||||
* 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 */
|
@ -1,983 +0,0 @@
|
||||
#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
|
@ -1,70 +0,0 @@
|
||||
/**
|
||||
* 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 */
|
@ -68,10 +68,26 @@ char *normalize_path(modsec_rec *msr, char *input) {
|
||||
char *Uri = NULL;
|
||||
int bytes = 0;
|
||||
int i;
|
||||
char *relative_link = NULL;
|
||||
char *filename = NULL;
|
||||
char *relative_path = NULL;
|
||||
char *relative_uri = NULL;
|
||||
|
||||
xmlNormalizeURIPath(uri->path);
|
||||
Uri = apr_pstrdup(msr->mp, uri->path);
|
||||
filename = file_basename(msr->mp, msr->r->parsed_uri.path);
|
||||
|
||||
if(filename == NULL || (strlen(msr->r->parsed_uri.path) - strlen(filename) < 0))
|
||||
return NULL;
|
||||
|
||||
relative_path = apr_pstrndup(msr->mp, msr->r->parsed_uri.path, strlen(msr->r->parsed_uri.path) - strlen(filename));
|
||||
relative_uri = apr_pstrcat(msr->mp, relative_path, uri->path, NULL);
|
||||
|
||||
relative_link = apr_pstrdup(msr->mp, relative_uri);
|
||||
|
||||
xmlNormalizeURIPath(relative_link);
|
||||
|
||||
Uri = apr_pstrdup(msr->mp, relative_link);
|
||||
|
||||
/*
|
||||
for(i = 0; i < (int)strlen(Uri); i++) {
|
||||
if(Uri[i] != '.' && Uri[i] != '/') {
|
||||
if (i - 1 < 0)
|
||||
@ -88,12 +104,15 @@ char *normalize_path(modsec_rec *msr, char *input) {
|
||||
|
||||
if(bytes >= (int)strlen(uri->path))
|
||||
return NULL;
|
||||
*/
|
||||
|
||||
content = apr_psprintf(msr->mp, "%s", Uri);
|
||||
|
||||
content = apr_psprintf(msr->mp, "%s", uri->path+bytes);
|
||||
if(parsed_content)
|
||||
parsed_content = apr_pstrcat(msr->mp, parsed_content, content, NULL);
|
||||
else
|
||||
parsed_content = apr_pstrcat(msr->mp, content, NULL);
|
||||
|
||||
}
|
||||
|
||||
if(uri->query_raw) {
|
||||
@ -629,6 +648,7 @@ int do_hash_method(modsec_rec *msr, char *link, int type) {
|
||||
int hash_response_body_links(modsec_rec *msr) {
|
||||
int lsize = 0, fsize = 0, lcount = 0, fcount = 0, i;
|
||||
int isize = 0, icount = 0, frsize = 0, frcount = 0;
|
||||
int bytes = 0;
|
||||
xmlXPathContextPtr xpathCtx = NULL;
|
||||
xmlXPathObjectPtr xpathObj = NULL;
|
||||
xmlChar *content_option = NULL;
|
||||
@ -687,6 +707,7 @@ int hash_response_body_links(modsec_rec *msr) {
|
||||
if(mac_link != NULL) {
|
||||
xmlSetProp(cur, (const xmlChar *) "href", (const xmlChar *) mac_link);
|
||||
lcount++;
|
||||
bytes += strlen(mac_link);
|
||||
msr->of_stream_changed = 1;
|
||||
}
|
||||
mac_link = NULL;
|
||||
@ -703,6 +724,7 @@ int hash_response_body_links(modsec_rec *msr) {
|
||||
if(mac_link != NULL) {
|
||||
xmlSetProp(cur, (const xmlChar *) "href", (const xmlChar *) mac_link);
|
||||
lcount++;
|
||||
bytes += strlen(mac_link);
|
||||
msr->of_stream_changed = 1;
|
||||
}
|
||||
mac_link = NULL;
|
||||
@ -758,6 +780,7 @@ int hash_response_body_links(modsec_rec *msr) {
|
||||
if(mac_link != NULL) {
|
||||
xmlSetProp(cur, (const xmlChar *) "action", (const xmlChar *) mac_link);
|
||||
fcount++;
|
||||
bytes += strlen(mac_link);
|
||||
msr->of_stream_changed = 1;
|
||||
}
|
||||
mac_link = NULL;
|
||||
@ -774,6 +797,7 @@ int hash_response_body_links(modsec_rec *msr) {
|
||||
if(mac_link != NULL) {
|
||||
xmlSetProp(cur, (const xmlChar *) "action", (const xmlChar *) mac_link);
|
||||
fcount++;
|
||||
bytes += strlen(mac_link);
|
||||
msr->of_stream_changed = 1;
|
||||
}
|
||||
mac_link = NULL;
|
||||
@ -828,6 +852,7 @@ int hash_response_body_links(modsec_rec *msr) {
|
||||
if(mac_link != NULL) {
|
||||
xmlSetProp(cur, (const xmlChar *) "src", (const xmlChar *) mac_link);
|
||||
icount++;
|
||||
bytes += strlen(mac_link);
|
||||
msr->of_stream_changed = 1;
|
||||
}
|
||||
mac_link = NULL;
|
||||
@ -844,6 +869,7 @@ int hash_response_body_links(modsec_rec *msr) {
|
||||
if(mac_link != NULL) {
|
||||
xmlSetProp(cur, (const xmlChar *) "src", (const xmlChar *) mac_link);
|
||||
icount++;
|
||||
bytes += strlen(mac_link);
|
||||
msr->of_stream_changed = 1;
|
||||
}
|
||||
mac_link = NULL;
|
||||
@ -893,6 +919,7 @@ int hash_response_body_links(modsec_rec *msr) {
|
||||
if(mac_link != NULL) {
|
||||
xmlSetProp(cur, (const xmlChar *) "src", (const xmlChar *) mac_link);
|
||||
frcount++;
|
||||
bytes += strlen(mac_link);
|
||||
msr->of_stream_changed = 1;
|
||||
}
|
||||
mac_link = NULL;
|
||||
@ -909,6 +936,7 @@ int hash_response_body_links(modsec_rec *msr) {
|
||||
if(mac_link != NULL) {
|
||||
xmlSetProp(cur, (const xmlChar *) "src", (const xmlChar *) mac_link);
|
||||
frcount++;
|
||||
bytes += strlen(mac_link);
|
||||
msr->of_stream_changed = 1;
|
||||
}
|
||||
mac_link = NULL;
|
||||
@ -953,7 +981,7 @@ int hash_response_body_links(modsec_rec *msr) {
|
||||
if((elts >= INT32_MAX) || (elts < 0))
|
||||
return 0;
|
||||
|
||||
return elts;
|
||||
return bytes;
|
||||
|
||||
obj_error:
|
||||
if(xpathCtx != NULL)
|
||||
@ -1044,6 +1072,7 @@ int inject_hashed_response_body(modsec_rec *msr, int elts) {
|
||||
}
|
||||
|
||||
htmlDocContentDumpFormatOutput(output_buf, msr->crypto_html_tree, NULL, 0);
|
||||
xmlOutputBufferFlush(output_buf);
|
||||
|
||||
#ifdef LIBXML2_NEW_BUFFER
|
||||
|
||||
@ -1133,10 +1162,11 @@ int inject_hashed_response_body(modsec_rec *msr, int elts) {
|
||||
}
|
||||
|
||||
memset(msr->stream_output_data, 0x0, msr->stream_output_length+1);
|
||||
memcpy(msr->stream_output_data, output_buf->buffer->content, msr->stream_output_length);
|
||||
memcpy(msr->stream_output_data, (char *)xmlBufferContent(output_buf->buffer), msr->stream_output_length);
|
||||
//memcpy(msr->stream_output_data, output_buf->buffer->content, msr->stream_output_length);
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 4)
|
||||
msr_log(msr, 4, "inject_hashed_response_body: Copying XML tree from CONTENT to stream buffer [%d] bytes.", output_buf->buffer->use);
|
||||
msr_log(msr, 4, "inject_hashed_response_body: Copying XML tree from CONTENT to stream buffer [%d] bytes.", msr->stream_output_length);
|
||||
|
||||
} else {
|
||||
|
||||
@ -1162,10 +1192,11 @@ int inject_hashed_response_body(modsec_rec *msr, int elts) {
|
||||
}
|
||||
|
||||
memset(msr->stream_output_data, 0x0, msr->stream_output_length+1);
|
||||
memcpy(msr->stream_output_data, output_buf->conv->content, msr->stream_output_length);
|
||||
memcpy(msr->stream_output_data, (char *)xmlBufferContent(output_buf->conv), msr->stream_output_length);
|
||||
//memcpy(msr->stream_output_data, output_buf->conv->content, msr->stream_output_length);
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 4)
|
||||
msr_log(msr, 4, "inject_hashed_response_body: Copying XML tree from CONV to stream buffer [%d] bytes.", output_buf->conv->use);
|
||||
msr_log(msr, 4, "inject_hashed_response_body: Copying XML tree from CONV to stream buffer [%d] bytes.", msr->stream_output_length);
|
||||
|
||||
}
|
||||
|
||||
@ -1209,14 +1240,15 @@ char *do_hash_link(modsec_rec *msr, char *link, int type) {
|
||||
if(strlen(link) > 7 && strncmp("http:",(char*)link,5)==0){
|
||||
path_chunk = strchr(link+7,'/');
|
||||
if(path_chunk != NULL) {
|
||||
if (msr->txcfg->debuglog_level >= 4)
|
||||
if (msr->txcfg->debuglog_level >= 4) {
|
||||
msr_log(msr, 4, "Signing data [%s]", path_chunk+1);
|
||||
}
|
||||
|
||||
if(msr->txcfg->crypto_key_add == HASH_KEYONLY)
|
||||
hash_value = hmac(msr, msr->txcfg->crypto_key, msr->txcfg->crypto_key_len, (unsigned char *) path_chunk+1, strlen((char*)path_chunk)-1);
|
||||
|
||||
if(msr->txcfg->crypto_key_add == HASH_SESSIONID) {
|
||||
if(strlen(msr->sessionid) == 0) {
|
||||
if(msr->sessionid == NULL || strlen(msr->sessionid) == 0) {
|
||||
#if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER > 2
|
||||
const char *new_pwd = apr_psprintf(msr->mp,"%s%s", msr->txcfg->crypto_key, msr->r->connection->client_ip);
|
||||
#else
|
||||
@ -1251,14 +1283,15 @@ char *do_hash_link(modsec_rec *msr, char *link, int type) {
|
||||
if(strlen(link) > 8 && strncmp("https",(char*)link,5)==0){
|
||||
path_chunk = strchr(link+8,'/');
|
||||
if(path_chunk != NULL) {
|
||||
if (msr->txcfg->debuglog_level >= 4)
|
||||
if (msr->txcfg->debuglog_level >= 4) {
|
||||
msr_log(msr, 4, "Signing data [%s]", path_chunk+1);
|
||||
}
|
||||
|
||||
if(msr->txcfg->crypto_key_add == HASH_KEYONLY)
|
||||
hash_value = hmac(msr, msr->txcfg->crypto_key, msr->txcfg->crypto_key_len, (unsigned char *) path_chunk+1, strlen((char*)path_chunk)-1);
|
||||
|
||||
if(msr->txcfg->crypto_key_add == HASH_SESSIONID) {
|
||||
if(strlen(msr->sessionid) == 0) {
|
||||
if(msr->sessionid == NULL || strlen(msr->sessionid) == 0) {
|
||||
#if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER > 2
|
||||
const char *new_pwd = apr_psprintf(msr->mp,"%s%s", msr->txcfg->crypto_key, msr->r->connection->client_ip);
|
||||
#else
|
||||
@ -1291,14 +1324,15 @@ char *do_hash_link(modsec_rec *msr, char *link, int type) {
|
||||
}
|
||||
}
|
||||
else if(*link=='/'){
|
||||
if (msr->txcfg->debuglog_level >= 4)
|
||||
if (msr->txcfg->debuglog_level >= 4) {
|
||||
msr_log(msr, 4, "Signing data [%s]", link+1);
|
||||
}
|
||||
|
||||
if(msr->txcfg->crypto_key_add == HASH_KEYONLY)
|
||||
hash_value = hmac(msr, msr->txcfg->crypto_key, msr->txcfg->crypto_key_len, (unsigned char *) link+1, strlen((char*)link)-1);
|
||||
|
||||
if(msr->txcfg->crypto_key_add == HASH_SESSIONID) {
|
||||
if(strlen(msr->sessionid) == 0) {
|
||||
if(msr->sessionid == NULL || strlen(msr->sessionid) == 0) {
|
||||
#if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER > 2
|
||||
const char *new_pwd = apr_psprintf(msr->mp,"%s%s", msr->txcfg->crypto_key, msr->r->connection->client_ip);
|
||||
#else
|
||||
@ -1344,14 +1378,15 @@ char *do_hash_link(modsec_rec *msr, char *link, int type) {
|
||||
|
||||
relative_link = relative_uri+1;
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 4)
|
||||
if (msr->txcfg->debuglog_level >= 4) {
|
||||
msr_log(msr, 4, "Signing data [%s] size %d", relative_link, strlen(relative_link));
|
||||
}
|
||||
|
||||
if(msr->txcfg->crypto_key_add == HASH_KEYONLY)
|
||||
hash_value = hmac(msr, msr->txcfg->crypto_key, msr->txcfg->crypto_key_len, (unsigned char *) relative_link, strlen((char*)relative_link));
|
||||
|
||||
if(msr->txcfg->crypto_key_add == HASH_SESSIONID) {
|
||||
if(strlen(msr->sessionid) == 0) {
|
||||
if(msr->sessionid == NULL || strlen(msr->sessionid) == 0) {
|
||||
#if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER > 2
|
||||
const char *new_pwd = apr_psprintf(msr->mp,"%s%s", msr->txcfg->crypto_key, msr->r->connection->client_ip);
|
||||
#else
|
||||
@ -1379,6 +1414,9 @@ char *do_hash_link(modsec_rec *msr, char *link, int type) {
|
||||
msr->txcfg->crypto_key_len = strlen(new_pwd);
|
||||
hash_value = hmac(msr, new_pwd, msr->txcfg->crypto_key_len, (unsigned char *) relative_link, strlen((char*)relative_link));
|
||||
}
|
||||
|
||||
link = relative_uri;
|
||||
|
||||
}
|
||||
|
||||
if(hash_value == NULL) return NULL;
|
||||
|
@ -38,7 +38,7 @@
|
||||
|
||||
#define MODSEC_VERSION_MAJOR "2"
|
||||
#define MODSEC_VERSION_MINOR "7"
|
||||
#define MODSEC_VERSION_MAINT "4"
|
||||
#define MODSEC_VERSION_MAINT "5"
|
||||
#define MODSEC_VERSION_TYPE ""
|
||||
#define MODSEC_VERSION_RELEASE ""
|
||||
|
||||
|
@ -130,8 +130,10 @@ static int unicode_map_create(directory_config *dcfg, char **error_msg)
|
||||
|
||||
apr_file_close(u_map->map);
|
||||
|
||||
free(buf);
|
||||
buf = NULL;
|
||||
if(buf) {
|
||||
free(buf);
|
||||
buf = NULL;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -120,8 +120,13 @@ char *utf8_unicode_inplace_ex(apr_pool_t *mp, unsigned char *input, long int inp
|
||||
if ((c & 0x80) == 0) {
|
||||
/* single byte unicode (7 bit ASCII equivilent) has no validation */
|
||||
count++;
|
||||
if(count <= len)
|
||||
*data++ = c;
|
||||
if(count <= len) {
|
||||
if(c == 0)
|
||||
*data = x2c(&c);
|
||||
else
|
||||
*data++ = c;
|
||||
}
|
||||
|
||||
}
|
||||
/* If first byte begins with binary 110 it is two byte encoding*/
|
||||
else if ((c & 0xE0) == 0xC0) {
|
||||
|
@ -489,9 +489,27 @@ static apr_status_t msre_action_ver_init(msre_engine *engine,
|
||||
/* severity */
|
||||
|
||||
static apr_status_t msre_action_severity_init(msre_engine *engine,
|
||||
msre_actionset *actionset, msre_action *action)
|
||||
msre_actionset *actionset, msre_action *action)
|
||||
{
|
||||
actionset->severity = atoi(action->param);
|
||||
if (strcasecmp(action->param, "emergency") == 0) {
|
||||
actionset->severity = 0;
|
||||
} else if (strcasecmp(action->param, "alert") == 0) {
|
||||
actionset->severity = 1;
|
||||
} else if (strcasecmp(action->param, "critical") == 0) {
|
||||
actionset->severity = 2;
|
||||
} else if (strcasecmp(action->param, "error") == 0) {
|
||||
actionset->severity = 3;
|
||||
} else if (strcasecmp(action->param, "warning") == 0) {
|
||||
actionset->severity = 4;
|
||||
} else if (strcasecmp(action->param, "notice") == 0) {
|
||||
actionset->severity = 5;
|
||||
} else if (strcasecmp(action->param, "info") == 0) {
|
||||
actionset->severity = 6;
|
||||
} else if (strcasecmp(action->param, "debug") == 0) {
|
||||
actionset->severity = 7;
|
||||
} else {
|
||||
actionset->severity = atoi(action->param);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -27,8 +27,7 @@
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include "libinjection/sqlparse.h"
|
||||
#include "libinjection/sqli_fingerprints.h"
|
||||
#include "libinjection/libinjection.h"
|
||||
|
||||
/**
|
||||
*
|
||||
@ -696,7 +695,7 @@ nextround:
|
||||
|
||||
msr->of_stream_changed = 1;
|
||||
|
||||
strncpy(msr->stream_output_data, data, size);
|
||||
memcpy(msr->stream_output_data, data, size);
|
||||
msr->stream_output_data[size] = '\0';
|
||||
|
||||
var->value_len = size;
|
||||
@ -720,7 +719,7 @@ nextround:
|
||||
|
||||
msr->if_stream_changed = 1;
|
||||
|
||||
strncpy(msr->stream_input_data, data, size);
|
||||
memcpy(msr->stream_input_data, data, size);
|
||||
msr->stream_input_data[size] = '\0';
|
||||
|
||||
var->value_len = size;
|
||||
@ -2133,35 +2132,34 @@ static int msre_op_contains_execute(modsec_rec *msr, msre_rule *rule, msre_var *
|
||||
}
|
||||
|
||||
/** libinjection detectSQLi
|
||||
* links against files in libinjection directory
|
||||
* 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;
|
||||
struct libinjection_sqli_state sqli_state;
|
||||
int issqli;
|
||||
int capture;
|
||||
|
||||
libinjection_sqli_init(&sqli_state, var->value, var->value_len, 0);
|
||||
issqli = libinjection_is_sqli(&sqli_state);
|
||||
capture = apr_table_get(rule->actionset->actions, "capture") ? 1 : 0;
|
||||
|
||||
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);
|
||||
set_match_to_tx(msr, capture, sqli_state.fingerprint, 0);
|
||||
|
||||
*error_msg = apr_psprintf(msr->mp, "detected SQLi using libinjection with fingerprint '%s'",
|
||||
sqli_state.fingerprint);
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "detectSQLi: libinjection fingerprint '%s' matched input '%s'",
|
||||
sf.pat,
|
||||
msr_log(msr, 9, "ISSQL: libinjection fingerprint '%s' matched input '%s'",
|
||||
sqli_state.fingerprint,
|
||||
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);
|
||||
msr_log(msr, 9, "ISSQL: not sqli, no libinjection sqli fingerprint matched input '%s'",
|
||||
log_escape_ex(msr->mp, var->value, var->value_len));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ OBJS1 = mod_security2.obj apache2_config.obj apache2_io.obj apache2_util.obj \
|
||||
msc_release.obj msc_crypt.obj msc_tree.obj
|
||||
OBJS2 = api.obj buckets.obj config.obj filters.obj hooks.obj regex.obj server.obj
|
||||
OBJS3 = main.obj moduleconfig.obj mymodule.obj
|
||||
OBJS4 = sqlparse.obj
|
||||
OBJS4 = libinjection_sqli.obj
|
||||
|
||||
all: $(DLL)
|
||||
|
||||
|
@ -61,7 +61,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_terminate(ngx_cycle_t *cycle);
|
||||
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);
|
||||
@ -115,8 +115,8 @@ ngx_module_t ngx_http_modsecurity = {
|
||||
ngx_http_modsecurity_init_process, /* init process */
|
||||
NULL, /* init thread */
|
||||
NULL, /* exit thread */
|
||||
NULL, /* exit process */
|
||||
NULL, /* exit master */
|
||||
ngx_http_modsecurity_terminate, /* exit process */
|
||||
ngx_http_modsecurity_terminate, /* exit master */
|
||||
NGX_MODULE_V1_PADDING
|
||||
};
|
||||
|
||||
@ -881,12 +881,11 @@ modsec_pcre_free(void *ptr)
|
||||
{
|
||||
}
|
||||
|
||||
static server_rec *modsec_server = NULL;
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_modsecurity_preconfiguration(ngx_conf_t *cf)
|
||||
{
|
||||
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;
|
||||
pcre_free = modsec_pcre_free;
|
||||
@ -895,24 +894,18 @@ ngx_http_modsecurity_preconfiguration(ngx_conf_t *cf)
|
||||
modsecSetDropAction(ngx_http_modsecurity_drop_action);
|
||||
|
||||
/* TODO: server_rec per server conf */
|
||||
s = modsecInit();
|
||||
if (s == NULL) {
|
||||
modsec_server = modsecInit();
|
||||
if (modsec_server == NULL) {
|
||||
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) {
|
||||
modsec_server->server_hostname = ngx_palloc(cf->pool, ngx_cycle->hostname.len + 1);
|
||||
if (modsec_server->server_hostname == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
ngx_memcpy(s->server_hostname, ngx_cycle->hostname.data, ngx_cycle->hostname.len);
|
||||
s->server_hostname[ ngx_cycle->hostname.len] = '\0';
|
||||
ngx_memcpy(modsec_server->server_hostname, ngx_cycle->hostname.data, ngx_cycle->hostname.len);
|
||||
modsec_server->server_hostname[ ngx_cycle->hostname.len] = '\0';
|
||||
|
||||
modsecStartConfig();
|
||||
return NGX_OK;
|
||||
@ -920,9 +913,12 @@ ngx_http_modsecurity_preconfiguration(ngx_conf_t *cf)
|
||||
|
||||
|
||||
static void
|
||||
ngx_http_modsecurity_finalize(void *data)
|
||||
ngx_http_modsecurity_terminate(ngx_cycle_t *cycle)
|
||||
{
|
||||
modsecTerminate();
|
||||
if (modsec_server) {
|
||||
modsecTerminate();
|
||||
modsec_server = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1359,7 +1355,7 @@ ngx_http_modsecurity_create_ctx(ngx_http_request_t *r)
|
||||
}
|
||||
}
|
||||
|
||||
salt[i] = '\0';
|
||||
salt[TXID_SIZE-1] = '\0';
|
||||
|
||||
apr_table_setn(ctx->req->subprocess_env, "UNIQUE_ID", apr_psprintf(ctx->req->pool, "%s", salt));
|
||||
|
||||
|
@ -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/libinjection/sqlparse.c \
|
||||
../apache2/msc_crypt.c ../apache2/msc_tree.c ../apache2/libinjection/libinjection_sqli.c \
|
||||
api.c buckets.c \
|
||||
config.c filters.c \
|
||||
hooks.c \
|
||||
|
@ -893,7 +893,11 @@ AP_DECLARE(void) ap_add_common_vars(request_rec *r)
|
||||
|
||||
#ifndef WIN32
|
||||
|
||||
#if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER < 3
|
||||
unixd_config_rec unixd_config;
|
||||
#else
|
||||
unixd_config_rec ap_unixd_config;
|
||||
#endif
|
||||
const char *ap_server_argv0 = "nginx";
|
||||
|
||||
#ifdef HAVE_GETPWNAM
|
||||
@ -936,13 +940,18 @@ AP_DECLARE(void) unixd_pre_config(apr_pool_t *ptemp)
|
||||
{
|
||||
apr_finfo_t wrapper;
|
||||
|
||||
#if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER < 3
|
||||
unixd_config.user_name = DEFAULT_USER;
|
||||
unixd_config.user_id = ap_uname2id(DEFAULT_USER);
|
||||
unixd_config.group_id = ap_gname2id(DEFAULT_GROUP);
|
||||
/* unixd_config.chroot_dir = NULL; none */
|
||||
|
||||
/* Check for suexec */
|
||||
unixd_config.suexec_enabled = 0;
|
||||
#else
|
||||
ap_unixd_config.user_name = DEFAULT_USER;
|
||||
ap_unixd_config.user_id = ap_uname2id(DEFAULT_USER);
|
||||
ap_unixd_config.group_id = ap_gname2id(DEFAULT_GROUP);
|
||||
ap_unixd_config.suexec_enabled = 0;
|
||||
#endif
|
||||
|
||||
/* if ((apr_stat(&wrapper, SUEXEC_BIN,
|
||||
APR_FINFO_NORM, ptemp)) != APR_SUCCESS) {
|
||||
return;
|
||||
@ -967,6 +976,7 @@ static apr_lockmech_e proc_mutex_mech(apr_proc_mutex_t *pmutex)
|
||||
return APR_LOCK_DEFAULT;
|
||||
}
|
||||
|
||||
#if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER < 3
|
||||
AP_DECLARE(apr_status_t) unixd_set_proc_mutex_perms(apr_proc_mutex_t *pmutex)
|
||||
{
|
||||
////////////////
|
||||
@ -1038,5 +1048,75 @@ AP_DECLARE(apr_status_t) unixd_set_global_mutex_perms(apr_global_mutex_t *gmutex
|
||||
return unixd_set_proc_mutex_perms(gmutex);
|
||||
#endif /* APR_PROC_MUTEX_IS_GLOBAL */
|
||||
}
|
||||
#else
|
||||
AP_DECLARE(apr_status_t) ap_unixd_set_proc_mutex_perms(apr_proc_mutex_t *pmutex)
|
||||
{
|
||||
if (ap_unixd_config.user_name == NULL)
|
||||
{
|
||||
unixd_pre_config(NULL);
|
||||
}
|
||||
|
||||
if (!geteuid()) {
|
||||
apr_lockmech_e mech = proc_mutex_mech(pmutex);
|
||||
|
||||
switch(mech) {
|
||||
#if APR_HAS_SYSVSEM_SERIALIZE
|
||||
case APR_LOCK_SYSVSEM:
|
||||
{
|
||||
apr_os_proc_mutex_t ospmutex;
|
||||
#if !APR_HAVE_UNION_SEMUN
|
||||
union semun {
|
||||
long val;
|
||||
struct semid_ds *buf;
|
||||
unsigned short *array;
|
||||
};
|
||||
#endif
|
||||
union semun ick;
|
||||
struct semid_ds buf;
|
||||
|
||||
apr_os_proc_mutex_get(&ospmutex, pmutex);
|
||||
buf.sem_perm.uid = ap_unixd_config.user_id;
|
||||
buf.sem_perm.gid = ap_unixd_config.group_id;
|
||||
buf.sem_perm.mode = 0600;
|
||||
ick.buf = &buf;
|
||||
if (semctl(ospmutex.crossproc, 0, IPC_SET, ick) < 0) {
|
||||
return errno;
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#if APR_HAS_FLOCK_SERIALIZE
|
||||
case APR_LOCK_FLOCK:
|
||||
{
|
||||
const char *lockfile = apr_proc_mutex_lockfile(pmutex);
|
||||
|
||||
if (lockfile) {
|
||||
if (chown(lockfile, ap_unixd_config.user_id,
|
||||
-1 /* no gid change */) < 0) {
|
||||
return errno;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
/* do nothing */
|
||||
break;
|
||||
}
|
||||
}
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
AP_DECLARE(apr_status_t) ap_unixd_set_global_mutex_perms(apr_global_mutex_t *gmutex)
|
||||
{
|
||||
#if !APR_PROC_MUTEX_IS_GLOBAL
|
||||
apr_os_global_mutex_t osgmutex;
|
||||
apr_os_global_mutex_get(&osgmutex, gmutex);
|
||||
return ap_unixd_set_proc_mutex_perms(osgmutex.proc_mutex);
|
||||
#else /* APR_PROC_MUTEX_IS_GLOBAL */
|
||||
/* In this case, apr_proc_mutex_t and apr_global_mutex_t are the same. */
|
||||
return ap_unixd_set_proc_mutex_perms(gmutex);
|
||||
#endif /* APR_PROC_MUTEX_IS_GLOBAL */
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@ -22,7 +22,7 @@ msc_test_SOURCES = msc_test.c \
|
||||
$(top_srcdir)/apache2/acmp.c \
|
||||
$(top_srcdir)/apache2/msc_lua.c \
|
||||
$(top_srcdir)/apache2/msc_release.c \
|
||||
$(top_srcdir)/apache2/libinjection/sqlparse.c
|
||||
$(top_srcdir)/apache2/libinjection/libinjection_sqli.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 \
|
||||
|
@ -55,8 +55,8 @@
|
||||
{
|
||||
type => "op",
|
||||
name => "rx",
|
||||
param => qr/^([^=])\s*=\s*((?:abc)+(?:def|ghi){2})$/i,
|
||||
input => "x =AbCDeFgHi",
|
||||
param => "(?i:(sleep\\((\\s*?)(\\d*?)(\\s*?)\\)|benchmark\\((.*?)\\,(.*?)\\)))",
|
||||
input => "SELECT pg_sleep(10);",
|
||||
ret => 1,
|
||||
},
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user