Implement unicode map

This commit is contained in:
brenosilva
2011-06-02 19:11:04 +00:00
parent 646564cd4f
commit f595919107
13 changed files with 523 additions and 149 deletions

View File

@@ -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 acmp.c msc_lua.c msc_release.c
msc_geo.c msc_gsb.c msc_unicode.c acmp.c msc_lua.c msc_release.c
mod_security2_la_CFLAGS = @APXS_CFLAGS@ @APR_CFLAGS@ @APU_CFLAGS@ \
@LIBXML2_CFLAGS@ @LUA_CFLAGS@

View File

@@ -45,7 +45,7 @@ OBJS = mod_security2.obj apache2_config.obj apache2_io.obj apache2_util.obj \
re.obj re_operators.obj re_actions.obj re_tfns.obj re_variables.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 acmp.obj msc_lua.obj \
msc_reqbody.obj msc_geo.obj msc_gsb.obj msc_unicode.obj acmp.obj msc_lua.obj \
msc_release.obj
all: $(DLL)

View File

@@ -110,6 +110,9 @@ void *create_directory_config(apr_pool_t *mp, char *path)
/* Gsb Lookups */
dcfg->gsb = NOT_SET_P;
/* Unicode Map */
dcfg->u_map = NOT_SET_P;
/* Cache */
dcfg->cache_trans = NOT_SET;
dcfg->cache_trans_incremental = NOT_SET;
@@ -483,6 +486,10 @@ void *merge_directory_configs(apr_pool_t *mp, void *_parent, void *_child)
merged->gsb = (child->gsb == NOT_SET_P
? parent->gsb : child->gsb);
/* Unicode Map */
merged->u_map = (child->u_map == NOT_SET_P
? parent->u_map : child->u_map);
/* Cache */
merged->cache_trans = (child->cache_trans == NOT_SET
? parent->cache_trans : child->cache_trans);
@@ -587,6 +594,9 @@ void init_directory_config(directory_config *dcfg)
/* Gsb Lookup */
if (dcfg->gsb == NOT_SET_P) dcfg->gsb = NULL;
/* Unicode Map */
if (dcfg->u_map == NOT_SET_P) dcfg->u_map = NULL;
/* Cache */
if (dcfg->cache_trans == NOT_SET) dcfg->cache_trans = MODSEC_CACHE_DISABLED;
if (dcfg->cache_trans_incremental == NOT_SET) dcfg->cache_trans_incremental = 0;
@@ -1989,6 +1999,41 @@ static const char *cmd_geo_lookup_db(cmd_parms *cmd, void *_dcfg,
return NULL;
}
/* Unicode CodePage */
static const char *cmd_unicode_codepage(cmd_parms *cmd,
void *_dcfg, const char *p1)
{
long val;
val = atol(p1);
if (val <= 0) {
return apr_psprintf(cmd->pool, "ModSecurity: Invalid setting for "
"SecUnicodeCodePage: %s", p1);
}
unicode_codepage = (unsigned long int)val;
return NULL;
}
/* Unicode Map */
static const char *cmd_unicode_map(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
const char *filename = resolve_relative_path(cmd->pool, cmd->directive->filename, p1);
char *error_msg;
directory_config *dcfg = (directory_config *)_dcfg;
if (dcfg == NULL) return NULL;
if (unicode_map_init(dcfg, filename, &error_msg) <= 0) {
return error_msg;
}
return NULL;
}
/* Google safe browsing */
static const char *cmd_gsb_lookup_db(cmd_parms *cmd, void *_dcfg,
@@ -2311,6 +2356,22 @@ const command_rec module_directives[] = {
"database google safe browsing"
),
AP_INIT_TAKE1 (
"SecUnicodeCodePage",
cmd_unicode_codepage,
NULL,
CMD_SCOPE_MAIN,
"Unicode CodePage"
),
AP_INIT_TAKE1 (
"SecUnicodeMapFile",
cmd_unicode_map,
NULL,
CMD_SCOPE_MAIN,
"Unicode Map file"
),
AP_INIT_TAKE1 (
"SecGeoLookupDB",
cmd_geo_lookup_db,

View File

@@ -51,6 +51,8 @@ apr_file_t DSOLOCAL *guardianlog_fd = NULL;
char DSOLOCAL *guardianlog_condition = NULL;
unsigned long int DSOLOCAL unicode_codepage = 0;
unsigned long int DSOLOCAL msc_pcre_match_limit = 0;
unsigned long int DSOLOCAL msc_pcre_match_limit_recursion = 0;
@@ -59,6 +61,8 @@ unsigned long int DSOLOCAL conn_read_state_limit = 0;
unsigned long int DSOLOCAL conn_write_state_limit = 0;
int DSOLOCAL *unicode_map_table = NULL;
static int server_limit, thread_limit;
typedef struct {

View File

@@ -38,6 +38,7 @@ typedef struct msc_parm msc_parm;
#include "msc_xml.h"
#include "msc_geo.h"
#include "msc_gsb.h"
#include "msc_unicode.h"
#include "re.h"
#include "ap_config.h"
@@ -136,6 +137,10 @@ extern DSOLOCAL unsigned long int conn_read_state_limit;
extern DSOLOCAL unsigned long int conn_write_state_limit;
extern DSOLOCAL unsigned long int unicode_codepage;
extern DSOLOCAL int *unicode_map_table;
#define RESBODY_STATUS_NOT_READ 0 /* we were not configured to read the body */
#define RESBODY_STATUS_ERROR 1 /* error occured while we were reading the body */
#define RESBODY_STATUS_PARTIAL 2 /* partial body content available in the brigade */
@@ -493,6 +498,9 @@ struct directory_config {
/* Gsb Lookup */
gsb_db *gsb;
/* Unicode map */
unicode_map *u_map;
/* Cache */
int cache_trans;
int cache_trans_incremental;

View File

@@ -1,11 +1,11 @@
MOD_SECURITY2 = mod_security2 apache2_config apache2_io apache2_util \
re re_operators re_actions re_tfns re_variables \
msc_logging msc_xml msc_multipart modsecurity msc_parsers msc_util msc_pcre \
persist_dbm msc_reqbody pdf_protect msc_geo msc_gsb acmp msc_lua
persist_dbm msc_reqbody pdf_protect msc_geo msc_gsb msc_unicode acmp msc_lua
H = re.h modsecurity.h msc_logging.h msc_multipart.h msc_parsers.h \
msc_pcre.h msc_util.h msc_xml.h persist_dbm.h apache2.h pdf_protect.h \
msc_geo.h msc_gsb.h acmp.h utf8tables.h msc_lua.h
msc_geo.h msc_gsb.h msc_unicode.h acmp.h utf8tables.h msc_lua.h
${MOD_SECURITY2:=.slo}: ${H}
${MOD_SECURITY2:=.lo}: ${H}

View File

@@ -33,6 +33,7 @@ static int gsb_db_create(directory_config *dcfg, char **error_msg)
if ((rc = apr_file_info_get(&finfo, wanted, gsb->db)) != APR_SUCCESS) {
*error_msg = apr_psprintf(mp, "Could not cannot get gsb malware file information \"%s\": %s", gsb->dbfn, apr_strerror(rc, errstr, 1024));
apr_file_close(gsb->db);
return 0;
}
@@ -40,6 +41,7 @@ static int gsb_db_create(directory_config *dcfg, char **error_msg)
if (buf == NULL) {
*error_msg = apr_psprintf(mp, "Could not alloc memory for gsb data");
apr_file_close(gsb->db);
return 0;
}
@@ -51,6 +53,7 @@ static int gsb_db_create(directory_config *dcfg, char **error_msg)
*error_msg = apr_psprintf(mp, "Could not alloc memory for gsb table");
free(buf);
buf = NULL;
apr_file_close(gsb->db);
return 0;
}

View File

@@ -38,9 +38,9 @@
#define MODSEC_VERSION_MAJOR "2"
#define MODSEC_VERSION_MINOR "6"
#define MODSEC_VERSION_MAINT "0"
#define MODSEC_VERSION_MAINT "1"
#define MODSEC_VERSION_TYPE "-rc"
#define MODSEC_VERSION_RELEASE "2"
#define MODSEC_VERSION_RELEASE "1"
#define MODSEC_VERSION_SUFFIX MODSEC_VERSION_TYPE MODSEC_VERSION_RELEASE

141
apache2/msc_unicode.c Normal file
View File

@@ -0,0 +1,141 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2011 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
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* If any of the files related to licensing are missing or if you have any
* other questions related to licensing please contact Trustwave Holdings, Inc.
* directly using the email address security@modsecurity.org.
*/
#include "msc_unicode.h"
#define CODEPAGE_SEPARATORS " \t\n\r"
static int unicode_map_create(directory_config *dcfg, char **error_msg)
{
char errstr[1024];
apr_pool_t *mp = dcfg->mp;
unicode_map *u_map = dcfg->u_map;
apr_int32_t wanted = APR_FINFO_SIZE;
apr_finfo_t finfo;
apr_status_t rc;
apr_size_t nbytes;
unsigned int codepage = 0;
char *buf = NULL, *p = NULL, *savedptr = NULL;
char *ucode = NULL, *hmap = NULL;
int found = 0, processing = 0;
int Code = 0, Map = 0;
if(unicode_map_table != NULL) {
free(unicode_map_table);
unicode_map_table = NULL;
}
if ((rc = apr_file_open(&u_map->map, u_map->mapfn, APR_READ, APR_OS_DEFAULT, mp)) != APR_SUCCESS) {
*error_msg = apr_psprintf(mp, "Could not open unicode map file \"%s\": %s", u_map->mapfn, apr_strerror(rc, errstr, 1024));
return 0;
}
if ((rc = apr_file_info_get(&finfo, wanted, u_map->map)) != APR_SUCCESS) {
*error_msg = apr_psprintf(mp, "Could not cannot get unicode map file information \"%s\": %s", u_map->mapfn, apr_strerror(rc, errstr, 1024));
apr_file_close(u_map->map);
return 0;
}
buf = (char *)malloc(finfo.size+1);
if (buf == NULL) {
*error_msg = apr_psprintf(mp, "Could not alloc memory for unicode map");
apr_file_close(u_map->map);
return 0;
}
rc = apr_file_read_full(u_map->map, buf, finfo.size, &nbytes);
if (unicode_map_table != NULL) {
memset(unicode_map_table, -1, (sizeof(int)*65536));
} else {
unicode_map_table = (int *)malloc(sizeof(int) * 65536);
if(unicode_map_table == NULL) {
*error_msg = apr_psprintf(mp, "Could not alloc memory for unicode map");
free(buf);
buf = NULL;
apr_file_close(u_map->map);
return 0;
}
memset(unicode_map_table, -1, (sizeof(int)*65536));
}
p = apr_strtok(buf,CODEPAGE_SEPARATORS,&savedptr);
while (p != NULL) {
codepage = atol(p);
if (codepage == unicode_codepage) {
found = 1;
}
if (found == 1 && (strchr(p,':') != NULL)) {
char *mapping = strdup(p);
processing = 1;
if(mapping != NULL) {
ucode = apr_strtok(mapping,":", &hmap);
sscanf(ucode,"%x",&Code);
sscanf(hmap,"%x",&Map);
if(Code >= 0 || Code <= 65535) {
unicode_map_table[Code] = Map;
}
free(mapping);
mapping = NULL;
}
}
if (processing == 1 && (strchr(p,':') == NULL)) {
free(buf);
buf = NULL;
break;
}
p = apr_strtok(NULL,CODEPAGE_SEPARATORS,&savedptr);
}
apr_file_close(u_map->map);
free(buf);
buf = NULL;
return 1;
}
/**
* Initialise Unicode Map data structure
*/
int unicode_map_init(directory_config *dcfg, const char *mapfn, char **error_msg)
{
*error_msg = NULL;
if ((dcfg->u_map == NULL) || (dcfg->u_map == NOT_SET_P)) {
dcfg->u_map = apr_pcalloc(dcfg->mp, sizeof(unicode_map));
if (dcfg->u_map == NULL) {
return -1;
}
}
dcfg->u_map->map = NULL;
dcfg->u_map->mapfn = apr_pstrdup(dcfg->mp, mapfn);
return unicode_map_create(dcfg, error_msg);
}

31
apache2/msc_unicode.h Normal file
View File

@@ -0,0 +1,31 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2011 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
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* If any of the files related to licensing are missing or if you have any
* other questions related to licensing please contact Trustwave Holdings, Inc.
* directly using the email address security@modsecurity.org.
*/
#ifndef _MSC_UNICODE_H_
#define _MSC_UNICODE_H_
typedef struct unicode_map unicode_map;
#include <apr_file_io.h>
#include "modsecurity.h"
#include "apr_hash.h"
struct unicode_map {
apr_file_t *map;
const char *mapfn;
};
int DSOLOCAL unicode_map_init(directory_config *dcfg, const char *mapfn, char **error_msg);
#endif

View File

@@ -75,13 +75,13 @@ static unsigned char x2c(unsigned char *what);
static unsigned char xsingle2c(unsigned char *what);
/* \brief Remove escape char
*
* \param mptmp Pointer to the pool
* \param input Pointer to input string
* \param input_len Input data length
*
* \retval string On Success
*/
*
* \param mptmp Pointer to the pool
* \param input Pointer to input string
* \param input_len Input data length
*
* \retval string On Success
*/
char *remove_escape(apr_pool_t *mptmp, const char *input, int input_len) {
char *parm = apr_palloc(mptmp, input_len);
char *ret = parm;
@@ -113,14 +113,14 @@ int parse_boolean(const char *input) {
}
/* \brief Decode Base64 data with special chars
*
* \param plain_text Pointer to plain text data
* \param input Pointer to input data
* \param input_len Input data length
*
* \retval 0 On failure
* \retval string length On Success
*/
*
* \param plain_text Pointer to plain text data
* \param input Pointer to input data
* \param input_len Input data length
*
* \retval 0 On failure
* \retval string length On Success
*/
int decode_base64_ext(char *plain_text, const char *input, int input_len)
{
const char *encoded = input;
@@ -178,34 +178,34 @@ int decode_base64_ext(char *plain_text, const char *input, int input_len)
}
/* \brief Convert const char to int
*
* \param c number string
*
* \retval n The converted number
*/
*
* \param c number string
*
* \retval n The converted number
*/
int convert_to_int(const char c)
{
int n;
if ((c>='0') && (c<='9'))
n = c - '0';
else if ((c>='A') && (c<='F'))
n = c - 'A' + 10;
else if ((c>='a') && (c<='f'))
n = c - 'a' + 10;
else
n = 0;
return n;
int n;
if ((c>='0') && (c<='9'))
n = c - '0';
else if ((c>='A') && (c<='F'))
n = c - 'A' + 10;
else if ((c>='a') && (c<='f'))
n = c - 'a' + 10;
else
n = 0;
return n;
}
/* \brief Set a match to tx.N
*
* \param msr Pointer to modsec resource
* \param capture If ON match will be saved
* \param match Pointer to captured string
*
* \param msr Pointer to modsec resource
* \param capture If ON match will be saved
* \param match Pointer to captured string
*\parm tx_n The tx number to save the data
*
* \retval 0 On Sucess|Fail
*/
*
* \retval 0 On Sucess|Fail
*/
int set_match_to_tx(modsec_rec *msr, int capture, const char *match, int tx_n) {
if (capture) {
@@ -226,12 +226,12 @@ int set_match_to_tx(modsec_rec *msr, int capture, const char *match, int tx_n)
}
/*
for(i = 0; i <= 9; i++) {
char buf[2];
apr_snprintf(buf, sizeof(buf), "%d", i);
apr_table_unset(msr->tx_vars, buf);
}
*/
for(i = 0; i <= 9; i++) {
char buf[2];
apr_snprintf(buf, sizeof(buf), "%d", i);
apr_table_unset(msr->tx_vars, buf);
}
*/
}
return 0;
@@ -291,16 +291,16 @@ char *url_encode(apr_pool_t *mp, char *input, unsigned int input_len, int *chang
*d++ = '+';
*changed = 1;
} else
if ( (c == 42) || ((c >= 48)&&(c <= 57)) || ((c >= 65)&&(c <= 90))
|| ((c >= 97)&&(c <= 122))
) {
*d++ = c;
} else {
*d++ = '%';
c2x(c, (unsigned char *)d);
d += 2;
*changed = 1;
}
if ( (c == 42) || ((c >= 48)&&(c <= 57)) || ((c >= 65)&&(c <= 90))
|| ((c >= 97)&&(c <= 122))
) {
*d++ = c;
} else {
*d++ = '%';
c2x(c, (unsigned char *)d);
d += 2;
*changed = 1;
}
}
*d = '\0';
@@ -332,24 +332,24 @@ char *strnurlencat(char *destination, char *source, unsigned int maxlen) {
*d++ = '+';
maxlen--;
} else
if ( (c == 42) || ((c >= 48)&&(c <= 57)) || ((c >= 65)&&(c <= 90))
|| ((c >= 97)&&(c <= 122))
) {
*d++ = c;
maxlen--;
} else {
if (maxlen >= 3) {
*d++ = '%';
c2x(c, (unsigned char *)d);
d += 2;
maxlen -= 3;
if ( (c == 42) || ((c >= 48)&&(c <= 57)) || ((c >= 65)&&(c <= 90))
|| ((c >= 97)&&(c <= 122))
) {
*d++ = c;
maxlen--;
} else {
/* If there's not enough room for the encoded
* byte we ignore it.
*/
maxlen = 0;
if (maxlen >= 3) {
*d++ = '%';
c2x(c, (unsigned char *)d);
d += 2;
maxlen -= 3;
} else {
/* If there's not enough room for the encoded
* byte we ignore it.
*/
maxlen = 0;
}
}
}
s++;
}
@@ -549,11 +549,11 @@ char *guess_tmp_dir(apr_pool_t *p) {
/* ENH Use apr_temp_dir_get instead. */
#ifdef WIN32
#ifdef WIN32
filename = apr_pcalloc(p, 256);
if (filename == NULL) return "";
if (GetTempPath(255, filename) != 0) return filename;
#endif
#endif
filename = getenv("TMPDIR");
if (filename != NULL) return filename;
@@ -564,13 +564,13 @@ char *guess_tmp_dir(apr_pool_t *p) {
filename = getenv("TMP");
if (filename != NULL) return filename;
#if defined NETWARE
#if defined NETWARE
return("sys:/tmp/");
#elif defined WIN32
#elif defined WIN32
return("");
#else
#else
return("/tmp/");
#endif
#endif
}
/**
@@ -585,8 +585,8 @@ char *current_logtime(apr_pool_t *mp) {
apr_strftime(tstr, &len, 80, "%d/%b/%Y:%H:%M:%S ", &t);
apr_snprintf(tstr + strlen(tstr), 80 - strlen(tstr), "%c%.2d%.2d",
t.tm_gmtoff < 0 ? '-' : '+',
t.tm_gmtoff / (60 * 60), t.tm_gmtoff % (60 * 60));
t.tm_gmtoff < 0 ? '-' : '+',
t.tm_gmtoff / (60 * 60), t.tm_gmtoff % (60 * 60));
return apr_pstrdup(mp, tstr);
}
@@ -667,7 +667,7 @@ static unsigned char *c2x(unsigned what, unsigned char *where) {
}
static char *_log_escape(apr_pool_t *p, const unsigned char *input,
unsigned long int input_length, int escape_quotes, int escape_colon, int escape_re);
unsigned long int input_length, int escape_quotes, int escape_colon, int escape_re);
char *log_escape_re(apr_pool_t *mp, const char *text) {
return _log_escape(mp, (const unsigned char *)text, text ? strlen(text) : 0, 1, 1, 1);
@@ -733,9 +733,9 @@ char *log_escape_hex(apr_pool_t *mp, const unsigned char *text, unsigned long in
for (i = 0, j = 0; i < text_length; i++) {
if ( (text[i] == '"')
||(text[i] == '\\')
||(text[i] <= 0x1f)
||(text[i] >= 0x7f))
||(text[i] == '\\')
||(text[i] <= 0x1f)
||(text[i] >= 0x7f))
{
ret[j] = '\\';
ret[j+1] = 'x';
@@ -756,7 +756,7 @@ char *log_escape_hex(apr_pool_t *mp, const unsigned char *text, unsigned long in
* Transform input into a form safe for logging.
*/
static char *_log_escape(apr_pool_t *mp, const unsigned char *input, unsigned long int input_len,
int escape_quotes, int escape_colon, int escape_re)
int escape_quotes, int escape_colon, int escape_re)
{
unsigned char *d = NULL;
char *ret = NULL;
@@ -912,8 +912,8 @@ int js_decode_nonstrict_inplace(unsigned char *input, long int input_len) {
/* Character is an escape. */
if ( (i + 5 < input_len) && (input[i + 1] == 'u')
&& (VALID_HEX(input[i + 2])) && (VALID_HEX(input[i + 3]))
&& (VALID_HEX(input[i + 4])) && (VALID_HEX(input[i + 5])) )
&& (VALID_HEX(input[i + 2])) && (VALID_HEX(input[i + 3]))
&& (VALID_HEX(input[i + 4])) && (VALID_HEX(input[i + 5])) )
{
/* \uHHHH */
@@ -922,8 +922,8 @@ int js_decode_nonstrict_inplace(unsigned char *input, long int input_len) {
/* Full width ASCII (ff01 - ff5e) needs 0x20 added */
if ( (*d > 0x00) && (*d < 0x5f)
&& ((input[i + 2] == 'f') || (input[i + 2] == 'F'))
&& ((input[i + 3] == 'f') || (input[i + 3] == 'F')))
&& ((input[i + 2] == 'f') || (input[i + 2] == 'F'))
&& ((input[i + 3] == 'f') || (input[i + 3] == 'F')))
{
(*d) += 0x20;
}
@@ -933,7 +933,7 @@ int js_decode_nonstrict_inplace(unsigned char *input, long int input_len) {
i += 6;
}
else if ( (i + 3 < input_len) && (input[i + 1] == 'x')
&& VALID_HEX(input[i + 2]) && VALID_HEX(input[i + 3])) {
&& VALID_HEX(input[i + 2]) && VALID_HEX(input[i + 3])) {
/* \xHH */
*d++ = x2c(&input[i + 2]);
count++;
@@ -987,9 +987,9 @@ int js_decode_nonstrict_inplace(unsigned char *input, long int input_len) {
case 'v' :
c = '\v';
break;
/* The remaining (\?,\\,\',\") are just a removal
* of the escape char which is default.
*/
/* The remaining (\?,\\,\',\") are just a removal
* of the escape char which is default.
*/
}
*d++ = c;
@@ -1021,7 +1021,8 @@ int js_decode_nonstrict_inplace(unsigned char *input, long int input_len) {
*/
int urldecode_uni_nonstrict_inplace_ex(unsigned char *input, long int input_len, int *changed) {
unsigned char *d = input;
long int i, count;
long int i, count, fact, j, xv;
unsigned int Code, hmap = -1;
*changed = 0;
@@ -1037,19 +1038,47 @@ int urldecode_uni_nonstrict_inplace_ex(unsigned char *input, long int input_len,
if (i + 5 < input_len) {
/* We have at least 4 data bytes. */
if ( (VALID_HEX(input[i + 2]))&&(VALID_HEX(input[i + 3]))
&&(VALID_HEX(input[i + 4]))&&(VALID_HEX(input[i + 5])) )
&&(VALID_HEX(input[i + 4]))&&(VALID_HEX(input[i + 5])) )
{
/* We first make use of the lower byte here, ignoring the higher byte. */
*d = x2c(&input[i + 4]);
/* Full width ASCII (ff01 - ff5e) needs 0x20 added */
if ( (*d > 0x00) && (*d < 0x5f)
&& ((input[i + 2] == 'f') || (input[i + 2] == 'F'))
&& ((input[i + 3] == 'f') || (input[i + 3] == 'F')))
{
(*d) += 0x20;
Code = 0;
fact = 1;
if (unicode_map_table != NULL && unicode_codepage > 0) {
for(j=5; j>=2; j--) {
if (isxdigit((input[i+j]))) {
if ((input[i+j])>=97) {
xv = ( (input[i+j]) - 97) + 10;
} else if ( (input[i+j]) >= 65) {
xv = ((input[i+j]) - 65) + 10;
} else {
xv = (input[i+j]) - 48;
}
Code += (xv * fact);
fact *= 16;
}
}
if(Code >= 0 && Code <= 65535) {
hmap = unicode_map_table[Code];
}
}
if(hmap != -1) {
*d = hmap;
} else {
/* We first make use of the lower byte here, ignoring the higher byte. */
*d = x2c(&input[i + 4]);
/* Full width ASCII (ff01 - ff5e) needs 0x20 added */
if ( (*d > 0x00) && (*d < 0x5f)
&& ((input[i + 2] == 'f') || (input[i + 2] == 'F'))
&& ((input[i + 3] == 'f') || (input[i + 3] == 'F')))
{
(*d) += 0x20;
}
}
d++;
count++;
i += 6;
@@ -1254,18 +1283,18 @@ int html_entities_decode_inplace(apr_pool_t *mp, unsigned char *input, int input
/* ENH What about others? */
if (strcasecmp(x, "quot") == 0) *d++ = '"';
else
if (strcasecmp(x, "amp") == 0) *d++ = '&';
else
if (strcasecmp(x, "lt") == 0) *d++ = '<';
else
if (strcasecmp(x, "gt") == 0) *d++ = '>';
else
if (strcasecmp(x, "nbsp") == 0) *d++ = NBSP;
else {
/* We do no want to convert this entity, copy the raw data over. */
copy = j - k + 1;
goto HTML_ENT_OUT;
}
if (strcasecmp(x, "amp") == 0) *d++ = '&';
else
if (strcasecmp(x, "lt") == 0) *d++ = '<';
else
if (strcasecmp(x, "gt") == 0) *d++ = '>';
else
if (strcasecmp(x, "nbsp") == 0) *d++ = NBSP;
else {
/* We do no want to convert this entity, copy the raw data over. */
copy = j - k + 1;
goto HTML_ENT_OUT;
}
count++;
@@ -1278,7 +1307,7 @@ int html_entities_decode_inplace(apr_pool_t *mp, unsigned char *input, int input
}
}
HTML_ENT_OUT:
HTML_ENT_OUT:
for(z = 0; ((z < copy) && (count < input_len)); z++) {
*d++ = input[i++];
@@ -1355,22 +1384,22 @@ int ansi_c_sequences_decode_inplace(unsigned char *input, int input_len) {
}
}
else
if (ISODIGIT(input[i + 1])) { /* Octal. */
char buf[4];
int j = 0;
if (ISODIGIT(input[i + 1])) { /* Octal. */
char buf[4];
int j = 0;
while((i + 1 + j < input_len)&&(j < 3)) {
buf[j] = input[i + 1 + j];
j++;
if (!ISODIGIT(input[i + 1 + j])) break;
}
buf[j] = '\0';
while((i + 1 + j < input_len)&&(j < 3)) {
buf[j] = input[i + 1 + j];
j++;
if (!ISODIGIT(input[i + 1 + j])) break;
}
buf[j] = '\0';
if (j > 0) {
c = strtol(buf, NULL, 8);
i += 1 + j;
if (j > 0) {
c = strtol(buf, NULL, 8);
i += 1 + j;
}
}
}
}
if (c == -1) {
@@ -1535,7 +1564,7 @@ copy:
unsigned char *oldsrc = src;
while ( (src < end)
&& ((*(src + 1) == '/') || (win && (*(src + 1) == '\\'))) )
&& ((*(src + 1) == '/') || (win && (*(src + 1) == '\\'))) )
{
src++;
}
@@ -1573,11 +1602,11 @@ length:
char *modsec_build(apr_pool_t *mp) {
return apr_psprintf(mp, "%02i%02i%02i%1i%02i",
atoi(MODSEC_VERSION_MAJOR),
atoi(MODSEC_VERSION_MINOR),
atoi(MODSEC_VERSION_MAINT),
get_modsec_build_type(NULL),
atoi(MODSEC_VERSION_RELEASE));
atoi(MODSEC_VERSION_MAJOR),
atoi(MODSEC_VERSION_MINOR),
atoi(MODSEC_VERSION_MAINT),
get_modsec_build_type(NULL),
atoi(MODSEC_VERSION_RELEASE));
}
int is_empty_string(const char *string) {
@@ -1600,8 +1629,8 @@ char *resolve_relative_path(apr_pool_t *pool, const char *parent_filename, const
if (filename[0] == '/') return (char *)filename;
return apr_pstrcat(pool, apr_pstrndup(pool, parent_filename,
strlen(parent_filename) - strlen(apr_filepath_name_get(parent_filename))),
filename, NULL);
strlen(parent_filename) - strlen(apr_filepath_name_get(parent_filename))),
filename, NULL);
}
/**
@@ -1685,8 +1714,8 @@ int css_decode_inplace(unsigned char *input, long int input_len) {
/* Do full check if first/second bytes are 0 */
if ( (input[i] == '0')
&& (input[i + 1] == '0')
) {
&& (input[i + 1] == '0')
) {
fullcheck = 1;
}
else {
@@ -1698,10 +1727,10 @@ int css_decode_inplace(unsigned char *input, long int input_len) {
/* Full width ASCII (0xff01 - 0xff5e) needs 0x20 added */
if (fullcheck) {
if ( (*d > 0x00) && (*d < 0x5f)
&& ((input[i + j - 3] == 'f') ||
(input[i + j - 3] == 'F'))
&& ((input[i + j - 4] == 'f') ||
(input[i + j - 4] == 'F')))
&& ((input[i + j - 3] == 'f') ||
(input[i + j - 3] == 'F'))
&& ((input[i + j - 4] == 'f') ||
(input[i + j - 4] == 'F')))
{
(*d) += 0x20;
}
@@ -1713,7 +1742,7 @@ int css_decode_inplace(unsigned char *input, long int input_len) {
if ((i + j < input_len) && isspace(input[i + j])) {
j++;
}
/* Move over. */
count++;
i += j;
@@ -1732,7 +1761,7 @@ int css_decode_inplace(unsigned char *input, long int input_len) {
count++;
}
}
/* No characters after backslash. */
else {
/* Do not include backslash in output (continuation to nothing) */
@@ -1796,7 +1825,7 @@ char *construct_single_var(modsec_rec *msr, char *name) {
/* Resolve variable. */
var = msre_create_var_ex(msr->mp, msr->modsecurity->msre,
varname, param, msr, &my_error_msg);
varname, param, msr, &my_error_msg);
if (var == NULL) return NULL;
/* Generate variable. */

View File

@@ -18,6 +18,7 @@
#include "apr_sha1.h"
#include "apr_base64.h"
#include "msc_unicode.h"
#include "re.h"
#include "msc_util.h"