mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-09-29 19:24:29 +03:00
Implement unicode map
This commit is contained in:
@@ -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@
|
||||
|
@@ -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)
|
||||
|
@@ -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,
|
||||
|
@@ -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 {
|
||||
|
@@ -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;
|
||||
|
@@ -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}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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
141
apache2/msc_unicode.c
Normal 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
31
apache2/msc_unicode.h
Normal 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
|
@@ -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. */
|
||||
|
@@ -18,6 +18,7 @@
|
||||
#include "apr_sha1.h"
|
||||
#include "apr_base64.h"
|
||||
|
||||
#include "msc_unicode.h"
|
||||
#include "re.h"
|
||||
#include "msc_util.h"
|
||||
|
||||
|
Reference in New Issue
Block a user