|
Packit |
284210 |
/*
|
|
Packit |
284210 |
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
|
Packit |
284210 |
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
|
Packit |
284210 |
*
|
|
Packit |
284210 |
* You may not use this file except in compliance with
|
|
Packit |
284210 |
* the License. You may obtain a copy of the License at
|
|
Packit |
284210 |
*
|
|
Packit |
284210 |
* http://www.apache.org/licenses/LICENSE-2.0
|
|
Packit |
284210 |
*
|
|
Packit |
284210 |
* If any of the files related to licensing are missing or if you have any
|
|
Packit |
284210 |
* other questions related to licensing please contact Trustwave Holdings, Inc.
|
|
Packit |
284210 |
* directly using the email address security@modsecurity.org.
|
|
Packit |
284210 |
*/
|
|
Packit |
284210 |
|
|
Packit |
284210 |
#include "msc_crypt.h"
|
|
Packit |
284210 |
#include "msc_util.h"
|
|
Packit |
284210 |
#include "apr_sha1.h"
|
|
Packit |
284210 |
#include "apr_uri.h"
|
|
Packit |
284210 |
#include "apr_base64.h"
|
|
Packit |
284210 |
#include "acmp.h"
|
|
Packit |
284210 |
#include "libxml/HTMLtree.h"
|
|
Packit |
284210 |
#include "libxml/uri.h"
|
|
Packit |
284210 |
#include <string.h>
|
|
Packit |
284210 |
|
|
Packit |
284210 |
/**
|
|
Packit |
284210 |
* \brief Normalize path in URI
|
|
Packit |
284210 |
*
|
|
Packit |
284210 |
* \param msr ModSecurity transaction resource
|
|
Packit |
284210 |
* \param input The URI to be normalized
|
|
Packit |
284210 |
*
|
|
Packit |
284210 |
* \retval input normalized input
|
|
Packit |
284210 |
* \retval NULL on fail
|
|
Packit |
284210 |
*/
|
|
Packit |
284210 |
char *normalize_path(modsec_rec *msr, char *input) {
|
|
Packit |
284210 |
xmlURI *uri = NULL;
|
|
Packit |
284210 |
char *parsed_content = NULL;
|
|
Packit |
284210 |
char *content = NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr == NULL) return NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(input == NULL) return NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
uri = xmlParseURI(input);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(uri != NULL && uri->path) {
|
|
Packit |
284210 |
if(uri->scheme) {
|
|
Packit |
284210 |
content = apr_psprintf(msr->mp, "%s://", uri->scheme);
|
|
Packit |
284210 |
parsed_content = apr_pstrcat(msr->mp, content, NULL);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(uri->server) {
|
|
Packit |
284210 |
content = apr_psprintf(msr->mp, "%s", uri->server);
|
|
Packit |
284210 |
if(parsed_content)
|
|
Packit |
284210 |
parsed_content = apr_pstrcat(msr->mp, parsed_content, content, NULL);
|
|
Packit |
284210 |
else
|
|
Packit |
284210 |
parsed_content = apr_pstrcat(msr->mp, content, NULL);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(uri->port) {
|
|
Packit |
284210 |
content = apr_psprintf(msr->mp, ":%d", uri->port);
|
|
Packit |
284210 |
if(parsed_content)
|
|
Packit |
284210 |
parsed_content = apr_pstrcat(msr->mp, parsed_content, content, NULL);
|
|
Packit |
284210 |
else
|
|
Packit |
284210 |
parsed_content = apr_pstrcat(msr->mp, content, NULL);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(uri->path) {
|
|
Packit |
284210 |
char *Uri = NULL;
|
|
Packit |
284210 |
int bytes = 0;
|
|
Packit |
284210 |
/*int i;*/
|
|
Packit |
284210 |
char *abs_link = NULL;
|
|
Packit |
284210 |
char *filename = NULL;
|
|
Packit |
284210 |
char *abs_path = NULL;
|
|
Packit |
284210 |
char *abs_uri = NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (uri->path[0] != '/') {
|
|
Packit |
284210 |
/* uri->path is relative. make it absolute */
|
|
Packit |
284210 |
filename = file_basename(msr->mp, msr->r->parsed_uri.path);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(filename == NULL || (strlen(msr->r->parsed_uri.path) - strlen(filename) < 0))
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
abs_path = apr_pstrndup(msr->mp, msr->r->parsed_uri.path, strlen(msr->r->parsed_uri.path) - strlen(filename));
|
|
Packit |
284210 |
abs_uri = apr_pstrcat(msr->mp, abs_path, uri->path, NULL);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
abs_link = apr_pstrdup(msr->mp, abs_uri);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
else {
|
|
Packit |
284210 |
abs_link = apr_pstrdup(msr->mp, uri->path);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
xmlNormalizeURIPath(abs_link);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
Uri = apr_pstrdup(msr->mp, abs_link);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
/*
|
|
Packit |
284210 |
for(i = 0; i < (int)strlen(Uri); i++) {
|
|
Packit |
284210 |
if(Uri[i] != '.' && Uri[i] != '/') {
|
|
Packit |
284210 |
if (i - 1 < 0)
|
|
Packit |
284210 |
i = 0;
|
|
Packit |
284210 |
else
|
|
Packit |
284210 |
i--;
|
|
Packit |
284210 |
if(Uri[i] == '/')
|
|
Packit |
284210 |
--bytes;
|
|
Packit |
284210 |
break;
|
|
Packit |
284210 |
} else {
|
|
Packit |
284210 |
bytes++;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(bytes >= (int)strlen(uri->path))
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
*/
|
|
Packit |
284210 |
|
|
Packit |
284210 |
content = apr_psprintf(msr->mp, "%s", Uri);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(parsed_content)
|
|
Packit |
284210 |
parsed_content = apr_pstrcat(msr->mp, parsed_content, content, NULL);
|
|
Packit |
284210 |
else
|
|
Packit |
284210 |
parsed_content = apr_pstrcat(msr->mp, content, NULL);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(uri->query_raw) {
|
|
Packit |
284210 |
content = apr_psprintf(msr->mp, "?%s", uri->query_raw);
|
|
Packit |
284210 |
if(parsed_content)
|
|
Packit |
284210 |
parsed_content = apr_pstrcat(msr->mp, parsed_content, content, NULL);
|
|
Packit |
284210 |
else
|
|
Packit |
284210 |
parsed_content = apr_pstrcat(msr->mp, content, NULL);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(uri->fragment) {
|
|
Packit |
284210 |
content = apr_psprintf(msr->mp, "#%s", uri->fragment);
|
|
Packit |
284210 |
if(parsed_content)
|
|
Packit |
284210 |
parsed_content = apr_pstrcat(msr->mp, parsed_content, content, NULL);
|
|
Packit |
284210 |
else
|
|
Packit |
284210 |
parsed_content = apr_pstrcat(msr->mp, content, NULL);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
xmlFreeURI(uri);
|
|
Packit |
284210 |
return apr_pstrdup(msr->mp, parsed_content);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(uri != NULL) xmlFreeURI(uri);
|
|
Packit |
284210 |
return apr_pstrdup(msr->mp, input);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
/**
|
|
Packit |
284210 |
* \brief Create a random password
|
|
Packit |
284210 |
*
|
|
Packit |
284210 |
* \param mp ModSecurity transaction memory pool
|
|
Packit |
284210 |
*
|
|
Packit |
284210 |
* \retval key random key
|
|
Packit |
284210 |
*/
|
|
Packit |
284210 |
char *getkey(apr_pool_t *mp) {
|
|
Packit |
284210 |
unsigned char digest[APR_SHA1_DIGESTSIZE];
|
|
Packit |
284210 |
char *sig, *key, *value;
|
|
Packit |
284210 |
apr_sha1_ctx_t ctx;
|
|
Packit |
284210 |
char salt[64];
|
|
Packit |
284210 |
|
|
Packit |
284210 |
apr_generate_random_bytes(salt, sizeof(salt));
|
|
Packit |
284210 |
key = apr_psprintf(mp,"%.*s",(int)sizeof(salt),salt);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
apr_sha1_init (&ctx;;
|
|
Packit |
284210 |
apr_sha1_update (&ctx, (const char*)key, strlen(key));
|
|
Packit |
284210 |
apr_sha1_update (&ctx, "\0", 1);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
apr_generate_random_bytes(salt, sizeof(salt));
|
|
Packit |
284210 |
value = apr_psprintf(mp,"%.*s",(int)sizeof(salt),salt);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
apr_sha1_update (&ctx, value, strlen (value));
|
|
Packit |
284210 |
apr_sha1_final (digest, &ctx;;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
sig = apr_pcalloc (mp, apr_base64_encode_len (sizeof (digest)));
|
|
Packit |
284210 |
apr_base64_encode (sig, (const char*)digest, sizeof (digest));
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return sig;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
|
|
Packit |
284210 |
/**
|
|
Packit |
284210 |
* \brief Generate the MAC for a given message
|
|
Packit |
284210 |
*
|
|
Packit |
284210 |
* \param msr ModSecurity transaction resource
|
|
Packit |
284210 |
* \param key The key used within HMAC
|
|
Packit |
284210 |
* \param key_len Key length
|
|
Packit |
284210 |
* \param msg The message to generate the MAC
|
|
Packit |
284210 |
* \param msglen The message length
|
|
Packit |
284210 |
*
|
|
Packit |
284210 |
* \retval hex_digest The MAC
|
|
Packit |
284210 |
*/
|
|
Packit |
284210 |
char *hmac(modsec_rec *msr, const char *key, int key_len,
|
|
Packit |
284210 |
unsigned char *msg, int msglen) {
|
|
Packit |
284210 |
apr_sha1_ctx_t ctx;
|
|
Packit |
284210 |
unsigned char digest[APR_SHA1_DIGESTSIZE];
|
|
Packit |
284210 |
unsigned char hmac_ipad[HMAC_PAD_SIZE], hmac_opad[HMAC_PAD_SIZE];
|
|
Packit |
284210 |
unsigned char nkey[APR_SHA1_DIGESTSIZE];
|
|
Packit |
284210 |
unsigned char *hmac_key = (unsigned char *) key;
|
|
Packit |
284210 |
char hex_digest[APR_SHA1_DIGESTSIZE * 2 + 1], *hmac_digest;
|
|
Packit |
284210 |
const char hex[] = "0123456789abcdef";
|
|
Packit |
284210 |
int i;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (key_len > HMAC_PAD_SIZE-1) {
|
|
Packit |
284210 |
hmac_key = nkey;
|
|
Packit |
284210 |
key_len = APR_SHA1_DIGESTSIZE;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
memset ((void *) hmac_ipad, 0, sizeof (hmac_ipad));
|
|
Packit |
284210 |
memset ((void *) hmac_opad, 0, sizeof (hmac_opad));
|
|
Packit |
284210 |
memmove (hmac_ipad, hmac_key, key_len);
|
|
Packit |
284210 |
memmove (hmac_opad, hmac_key, key_len);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
for (i = 0; i < HMAC_PAD_SIZE-1; i++) {
|
|
Packit |
284210 |
hmac_ipad[i] ^= 0x36;
|
|
Packit |
284210 |
hmac_opad[i] ^= 0x5c;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
apr_sha1_init (&ctx;;
|
|
Packit |
284210 |
apr_sha1_update_binary (&ctx, hmac_ipad, HMAC_PAD_SIZE-1);
|
|
Packit |
284210 |
apr_sha1_update_binary (&ctx, (const unsigned char *) msg, msglen);
|
|
Packit |
284210 |
apr_sha1_final (digest, &ctx;;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
apr_sha1_init (&ctx;;
|
|
Packit |
284210 |
apr_sha1_update_binary (&ctx, hmac_opad, HMAC_PAD_SIZE-1);
|
|
Packit |
284210 |
apr_sha1_update_binary (&ctx, digest, sizeof (digest));
|
|
Packit |
284210 |
apr_sha1_final (digest, &ctx;;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
hmac_digest = hex_digest;
|
|
Packit |
284210 |
for (i = 0; i < sizeof (digest); i++) {
|
|
Packit |
284210 |
*hmac_digest++ = hex[digest[i] >> 4];
|
|
Packit |
284210 |
*hmac_digest++ = hex[digest[i] & 0xF];
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
*hmac_digest = '\0';
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return apr_pstrdup (msr->mp, hex_digest);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
|
|
Packit |
284210 |
/**
|
|
Packit |
284210 |
* \brief Init html response body parser
|
|
Packit |
284210 |
*
|
|
Packit |
284210 |
* \param msr ModSecurity transaction resource
|
|
Packit |
284210 |
*
|
|
Packit |
284210 |
* \retval 1 on success
|
|
Packit |
284210 |
* \retval -1 on fail
|
|
Packit |
284210 |
*/
|
|
Packit |
284210 |
int init_response_body_html_parser(modsec_rec *msr) {
|
|
Packit |
284210 |
char *charset = NULL;
|
|
Packit |
284210 |
char *final_charset = NULL;
|
|
Packit |
284210 |
char sep;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr == NULL) return -1;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr->r == NULL) return -1;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr->r->content_type == NULL) return -1;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr->crypto_html_tree != NULL){
|
|
Packit |
284210 |
xmlFreeDoc(msr->crypto_html_tree);
|
|
Packit |
284210 |
msr->crypto_html_tree = NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if((strncmp("text/html",msr->r->content_type, 9) != 0)){
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4,
|
|
Packit |
284210 |
"init_response_body_html_parser: skipping html_tree generation for Content[%s].", msr->r->content_type);
|
|
Packit |
284210 |
if(msr->crypto_html_tree != NULL){
|
|
Packit |
284210 |
xmlFreeDoc(msr->crypto_html_tree);
|
|
Packit |
284210 |
msr->crypto_html_tree = NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
return -1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (msr->resbody_length == 0) {
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4, "init_response_body_html_parser: skipping html_tree generation for zero length respomse body.");
|
|
Packit |
284210 |
msr->crypto_html_tree = NULL;
|
|
Packit |
284210 |
return 0;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if((msr->r->content_encoding == NULL)||(apr_strnatcasecmp(msr->r->content_encoding,"(null)")==0)){
|
|
Packit |
284210 |
charset=m_strcasestr(msr->r->content_type,"charset=");
|
|
Packit |
284210 |
if(charset == NULL){
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4, "init_response_body_html_parser: assuming ISO-8859-1.");
|
|
Packit |
284210 |
msr->crypto_html_tree = htmlReadMemory(msr->resbody_data, msr->resbody_length, NULL,
|
|
Packit |
284210 |
"ISO-8859-1", HTML_PARSE_RECOVER | HTML_PARSE_NOBLANKS | HTML_PARSE_NOERROR | HTML_PARSE_NOWARNING);
|
|
Packit |
284210 |
htmlSetMetaEncoding ((htmlDocPtr) msr->crypto_html_tree, (const xmlChar *) "ISO-8859-1");
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
else{
|
|
Packit |
284210 |
charset+=8;
|
|
Packit |
284210 |
final_charset=strchr(charset,' ');
|
|
Packit |
284210 |
if(final_charset == NULL) final_charset = strchr(charset,';');
|
|
Packit |
284210 |
if(final_charset != NULL) {
|
|
Packit |
284210 |
sep = *final_charset;
|
|
Packit |
284210 |
*final_charset = '\0';
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4,
|
|
Packit |
284210 |
"init_response_body_html_parser: Charset[%s]",charset);
|
|
Packit |
284210 |
msr->crypto_html_tree = htmlReadMemory(msr->resbody_data, msr->resbody_length, NULL,
|
|
Packit |
284210 |
charset, HTML_PARSE_RECOVER| HTML_PARSE_NOBLANKS | HTML_PARSE_NOERROR | HTML_PARSE_NOWARNING);
|
|
Packit |
284210 |
htmlSetMetaEncoding ((htmlDocPtr) msr->crypto_html_tree, (const xmlChar *)charset);
|
|
Packit |
284210 |
if(final_charset != NULL) *final_charset=sep;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
else{
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4,"init_response_body_html_parser: Enconding[%s].",msr->r->content_encoding);
|
|
Packit |
284210 |
msr->crypto_html_tree = htmlReadMemory(msr->resbody_data, msr->resbody_length, NULL,
|
|
Packit |
284210 |
msr->r->content_encoding, HTML_PARSE_RECOVER | HTML_PARSE_NOBLANKS | HTML_PARSE_NOERROR | HTML_PARSE_NOWARNING);
|
|
Packit |
284210 |
htmlSetMetaEncoding ((htmlDocPtr) msr->crypto_html_tree, (const xmlChar *)msr->r->content_encoding);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
if(msr->crypto_html_tree == NULL){
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4,
|
|
Packit |
284210 |
"init_response_body_html_parser: Failed to parse response body.");
|
|
Packit |
284210 |
return -1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
else {
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4,
|
|
Packit |
284210 |
"init_response_body_html_parser: Successfully html parser generated.");
|
|
Packit |
284210 |
return 1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return 1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
/**
|
|
Packit |
284210 |
* \brief Execute all hash methods
|
|
Packit |
284210 |
*
|
|
Packit |
284210 |
* \param msr ModSecurity transaction resource
|
|
Packit |
284210 |
* \param link The html attr value to be checked
|
|
Packit |
284210 |
* \param type The hash method type
|
|
Packit |
284210 |
*
|
|
Packit |
284210 |
* \retval 1 Match
|
|
Packit |
284210 |
* \retval 0 No Match
|
|
Packit |
284210 |
* \retval -1 on fail
|
|
Packit |
284210 |
*/
|
|
Packit |
284210 |
int do_hash_method(modsec_rec *msr, char *link, int type) {
|
|
Packit |
284210 |
hash_method **em = NULL;
|
|
Packit |
284210 |
int i = 0;
|
|
Packit |
284210 |
char *error_msg = NULL;
|
|
Packit |
284210 |
char *my_error_msg = NULL;
|
|
Packit |
284210 |
int ovector[33];
|
|
Packit |
284210 |
int rc;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr == NULL) return -1;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
em = (hash_method **)msr->txcfg->hash_method->elts;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr->txcfg->hash_method->nelts == 0)
|
|
Packit |
284210 |
return 1;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
for (i = 0; i < msr->txcfg->hash_method->nelts; i++) {
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(em[i] != NULL && em[i]->param_data != NULL){
|
|
Packit |
284210 |
|
|
Packit |
284210 |
switch(type) {
|
|
Packit |
284210 |
case HASH_URL_HREF_HASH_PM:
|
|
Packit |
284210 |
if(em[i]->type == HASH_URL_HREF_HASH_PM) {
|
|
Packit |
284210 |
const char *match = NULL;
|
|
Packit |
284210 |
apr_status_t rc = 0;
|
|
Packit |
284210 |
ACMPT pt;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
pt.parser = (ACMP *)em[i]->param_data;
|
|
Packit |
284210 |
pt.ptr = NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
rc = acmp_process_quick(&pt, &match, link, strlen(link));
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (rc) {
|
|
Packit |
284210 |
return 1;
|
|
Packit |
284210 |
} else {
|
|
Packit |
284210 |
return 0;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
break;
|
|
Packit |
284210 |
case HASH_URL_HREF_HASH_RX:
|
|
Packit |
284210 |
if(em[i]->type == HASH_URL_HREF_HASH_RX) {
|
|
Packit |
284210 |
rc = msc_regexec_capture(em[i]->param_data, link, strlen(link), ovector, 30, &my_error_msg);
|
|
Packit |
284210 |
if ((rc == PCRE_ERROR_MATCHLIMIT) || (rc == PCRE_ERROR_RECURSIONLIMIT)) {
|
|
Packit |
284210 |
msc_string *s = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (s == NULL) return -1;
|
|
Packit |
284210 |
s->name = apr_pstrdup(msr->mp, "MSC_PCRE_LIMITS_EXCEEDED");
|
|
Packit |
284210 |
if (s->name == NULL) return -1;
|
|
Packit |
284210 |
s->name_len = strlen(s->name);
|
|
Packit |
284210 |
s->value = apr_pstrdup(msr->mp, "1");
|
|
Packit |
284210 |
if (s->value == NULL) return -1;
|
|
Packit |
284210 |
s->value_len = 1;
|
|
Packit |
284210 |
apr_table_setn(msr->tx_vars, s->name, (void *)s);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
error_msg = apr_psprintf(msr->mp,
|
|
Packit |
284210 |
"Execution error - "
|
|
Packit |
284210 |
"PCRE limits exceeded for Hash regex [%s] (%d): %s",
|
|
Packit |
284210 |
em[i]->param,rc, my_error_msg);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4, "%s.", error_msg);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return 0; /* No match. */
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
else if (rc < -1) {
|
|
Packit |
284210 |
error_msg = apr_psprintf(msr->mp, "Regex execution failed (%d): %s",
|
|
Packit |
284210 |
rc, my_error_msg);
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4, "%s.", error_msg);
|
|
Packit |
284210 |
return -1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
if (rc != PCRE_ERROR_NOMATCH) { /* Match. */
|
|
Packit |
284210 |
return 1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
break;
|
|
Packit |
284210 |
case HASH_URL_FACTION_HASH_PM:
|
|
Packit |
284210 |
if(em[i]->type == HASH_URL_FACTION_HASH_PM) {
|
|
Packit |
284210 |
const char *match = NULL;
|
|
Packit |
284210 |
apr_status_t rc = 0;
|
|
Packit |
284210 |
ACMPT pt;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
pt.parser = (ACMP *)em[i]->param_data;
|
|
Packit |
284210 |
pt.ptr = NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
rc = acmp_process_quick(&pt, &match, link, strlen(link));
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (rc) {
|
|
Packit |
284210 |
return 1;
|
|
Packit |
284210 |
} else {
|
|
Packit |
284210 |
return 0;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
break;
|
|
Packit |
284210 |
case HASH_URL_FACTION_HASH_RX:
|
|
Packit |
284210 |
if(em[i]->type == HASH_URL_FACTION_HASH_RX) {
|
|
Packit |
284210 |
rc = msc_regexec_capture(em[i]->param_data, link, strlen(link), ovector, 30, &my_error_msg);
|
|
Packit |
284210 |
if ((rc == PCRE_ERROR_MATCHLIMIT) || (rc == PCRE_ERROR_RECURSIONLIMIT)) {
|
|
Packit |
284210 |
msc_string *s = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (s == NULL) return -1;
|
|
Packit |
284210 |
s->name = apr_pstrdup(msr->mp, "MSC_PCRE_LIMITS_EXCEEDED");
|
|
Packit |
284210 |
if (s->name == NULL) return -1;
|
|
Packit |
284210 |
s->name_len = strlen(s->name);
|
|
Packit |
284210 |
s->value = apr_pstrdup(msr->mp, "1");
|
|
Packit |
284210 |
if (s->value == NULL) return -1;
|
|
Packit |
284210 |
s->value_len = 1;
|
|
Packit |
284210 |
apr_table_setn(msr->tx_vars, s->name, (void *)s);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
error_msg = apr_psprintf(msr->mp,
|
|
Packit |
284210 |
"Execution error - "
|
|
Packit |
284210 |
"PCRE limits exceeded for Hash regex [%s] (%d): %s",
|
|
Packit |
284210 |
em[i]->param,rc, my_error_msg);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4, "%s.", error_msg);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return 0; /* No match. */
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
else if (rc < -1) {
|
|
Packit |
284210 |
error_msg = apr_psprintf(msr->mp, "Regex execution failed (%d): %s",
|
|
Packit |
284210 |
rc, my_error_msg);
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4, "%s.", error_msg);
|
|
Packit |
284210 |
return -1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
if (rc != PCRE_ERROR_NOMATCH) { /* Match. */
|
|
Packit |
284210 |
return 1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
break;
|
|
Packit |
284210 |
case HASH_URL_LOCATION_HASH_PM:
|
|
Packit |
284210 |
if(em[i]->type == HASH_URL_LOCATION_HASH_PM) {
|
|
Packit |
284210 |
const char *match = NULL;
|
|
Packit |
284210 |
apr_status_t rc = 0;
|
|
Packit |
284210 |
ACMPT pt;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
pt.parser = (ACMP *)em[i]->param_data;
|
|
Packit |
284210 |
pt.ptr = NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
rc = acmp_process_quick(&pt, &match, link, strlen(link));
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (rc) {
|
|
Packit |
284210 |
return 1;
|
|
Packit |
284210 |
} else {
|
|
Packit |
284210 |
return 0;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
break;
|
|
Packit |
284210 |
case HASH_URL_LOCATION_HASH_RX:
|
|
Packit |
284210 |
if(em[i]->type == HASH_URL_LOCATION_HASH_RX) {
|
|
Packit |
284210 |
rc = msc_regexec_capture(em[i]->param_data, link, strlen(link), ovector, 30, &my_error_msg);
|
|
Packit |
284210 |
if ((rc == PCRE_ERROR_MATCHLIMIT) || (rc == PCRE_ERROR_RECURSIONLIMIT)) {
|
|
Packit |
284210 |
msc_string *s = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (s == NULL) return -1;
|
|
Packit |
284210 |
s->name = apr_pstrdup(msr->mp, "MSC_PCRE_LIMITS_EXCEEDED");
|
|
Packit |
284210 |
if (s->name == NULL) return -1;
|
|
Packit |
284210 |
s->name_len = strlen(s->name);
|
|
Packit |
284210 |
s->value = apr_pstrdup(msr->mp, "1");
|
|
Packit |
284210 |
if (s->value == NULL) return -1;
|
|
Packit |
284210 |
s->value_len = 1;
|
|
Packit |
284210 |
apr_table_setn(msr->tx_vars, s->name, (void *)s);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
error_msg = apr_psprintf(msr->mp,
|
|
Packit |
284210 |
"Execution error - "
|
|
Packit |
284210 |
"PCRE limits exceeded for Hash regex [%s] (%d): %s",
|
|
Packit |
284210 |
em[i]->param,rc, my_error_msg);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4, "%s.", error_msg);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return 0; /* No match. */
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
else if (rc < -1) {
|
|
Packit |
284210 |
error_msg = apr_psprintf(msr->mp, "Regex execution failed (%d): %s",
|
|
Packit |
284210 |
rc, my_error_msg);
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4, "%s.", error_msg);
|
|
Packit |
284210 |
return -1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
if (rc != PCRE_ERROR_NOMATCH) { /* Match. */
|
|
Packit |
284210 |
return 1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
break;
|
|
Packit |
284210 |
case HASH_URL_IFRAMESRC_HASH_PM:
|
|
Packit |
284210 |
if(em[i]->type == HASH_URL_IFRAMESRC_HASH_PM) {
|
|
Packit |
284210 |
const char *match = NULL;
|
|
Packit |
284210 |
apr_status_t rc = 0;
|
|
Packit |
284210 |
ACMPT pt;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
pt.parser = (ACMP *)em[i]->param_data;
|
|
Packit |
284210 |
pt.ptr = NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
rc = acmp_process_quick(&pt, &match, link, strlen(link));
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (rc) {
|
|
Packit |
284210 |
return 1;
|
|
Packit |
284210 |
} else {
|
|
Packit |
284210 |
return 0;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
break;
|
|
Packit |
284210 |
case HASH_URL_IFRAMESRC_HASH_RX:
|
|
Packit |
284210 |
if(em[i]->type == HASH_URL_IFRAMESRC_HASH_RX) {
|
|
Packit |
284210 |
rc = msc_regexec_capture(em[i]->param_data, link, strlen(link), ovector, 30, &my_error_msg);
|
|
Packit |
284210 |
if ((rc == PCRE_ERROR_MATCHLIMIT) || (rc == PCRE_ERROR_RECURSIONLIMIT)) {
|
|
Packit |
284210 |
msc_string *s = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (s == NULL) return -1;
|
|
Packit |
284210 |
s->name = apr_pstrdup(msr->mp, "MSC_PCRE_LIMITS_EXCEEDED");
|
|
Packit |
284210 |
if (s->name == NULL) return -1;
|
|
Packit |
284210 |
s->name_len = strlen(s->name);
|
|
Packit |
284210 |
s->value = apr_pstrdup(msr->mp, "1");
|
|
Packit |
284210 |
if (s->value == NULL) return -1;
|
|
Packit |
284210 |
s->value_len = 1;
|
|
Packit |
284210 |
apr_table_setn(msr->tx_vars, s->name, (void *)s);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
error_msg = apr_psprintf(msr->mp,
|
|
Packit |
284210 |
"Execution error - "
|
|
Packit |
284210 |
"PCRE limits exceeded for Hash regex [%s] (%d): %s",
|
|
Packit |
284210 |
em[i]->param,rc, my_error_msg);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4, "%s.", error_msg);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return 0; /* No match. */
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
else if (rc < -1) {
|
|
Packit |
284210 |
error_msg = apr_psprintf(msr->mp, "Regex execution failed (%d): %s",
|
|
Packit |
284210 |
rc, my_error_msg);
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4, "%s.", error_msg);
|
|
Packit |
284210 |
return -1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
if (rc != PCRE_ERROR_NOMATCH) { /* Match. */
|
|
Packit |
284210 |
return 1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
break;
|
|
Packit |
284210 |
case HASH_URL_FRAMESRC_HASH_PM:
|
|
Packit |
284210 |
if(em[i]->type == HASH_URL_FRAMESRC_HASH_PM) {
|
|
Packit |
284210 |
const char *match = NULL;
|
|
Packit |
284210 |
apr_status_t rc = 0;
|
|
Packit |
284210 |
ACMPT pt;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
pt.parser = (ACMP *)em[i]->param_data;
|
|
Packit |
284210 |
pt.ptr = NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
rc = acmp_process_quick(&pt, &match, link, strlen(link));
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (rc) {
|
|
Packit |
284210 |
return 1;
|
|
Packit |
284210 |
} else {
|
|
Packit |
284210 |
return 0;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
break;
|
|
Packit |
284210 |
case HASH_URL_FRAMESRC_HASH_RX:
|
|
Packit |
284210 |
if(em[i]->type == HASH_URL_FRAMESRC_HASH_RX) {
|
|
Packit |
284210 |
rc = msc_regexec_capture(em[i]->param_data, link, strlen(link), ovector, 30, &my_error_msg);
|
|
Packit |
284210 |
if ((rc == PCRE_ERROR_MATCHLIMIT) || (rc == PCRE_ERROR_RECURSIONLIMIT)) {
|
|
Packit |
284210 |
msc_string *s = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (s == NULL) return -1;
|
|
Packit |
284210 |
s->name = apr_pstrdup(msr->mp, "MSC_PCRE_LIMITS_EXCEEDED");
|
|
Packit |
284210 |
if (s->name == NULL) return -1;
|
|
Packit |
284210 |
s->name_len = strlen(s->name);
|
|
Packit |
284210 |
s->value = apr_pstrdup(msr->mp, "1");
|
|
Packit |
284210 |
if (s->value == NULL) return -1;
|
|
Packit |
284210 |
s->value_len = 1;
|
|
Packit |
284210 |
apr_table_setn(msr->tx_vars, s->name, (void *)s);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
error_msg = apr_psprintf(msr->mp,
|
|
Packit |
284210 |
"Execution error - "
|
|
Packit |
284210 |
"PCRE limits exceeded for Hash regex [%s] (%d): %s",
|
|
Packit |
284210 |
em[i]->param,rc, my_error_msg);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4, "%s.", error_msg);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return 0; /* No match. */
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
else if (rc < -1) {
|
|
Packit |
284210 |
error_msg = apr_psprintf(msr->mp, "Regex execution failed (%d): %s",
|
|
Packit |
284210 |
rc, my_error_msg);
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4, "%s.", error_msg);
|
|
Packit |
284210 |
return -1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
if (rc != PCRE_ERROR_NOMATCH) { /* Match. */
|
|
Packit |
284210 |
return 1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
break;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
return 0;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
/**
|
|
Packit |
284210 |
* \brief Hash the html elements
|
|
Packit |
284210 |
*
|
|
Packit |
284210 |
* \param msr ModSecurity transaction resource
|
|
Packit |
284210 |
*
|
|
Packit |
284210 |
* \retval 1 On success
|
|
Packit |
284210 |
* \retval 0 No element was changed
|
|
Packit |
284210 |
* \retval -1 On fail
|
|
Packit |
284210 |
*/
|
|
Packit |
284210 |
int hash_response_body_links(modsec_rec *msr) {
|
|
Packit |
284210 |
int lsize = 0, fsize = 0, lcount = 0, fcount = 0, i;
|
|
Packit |
284210 |
int isize = 0, icount = 0, frsize = 0, frcount = 0;
|
|
Packit |
284210 |
int bytes = 0;
|
|
Packit |
284210 |
xmlXPathContextPtr xpathCtx = NULL;
|
|
Packit |
284210 |
xmlXPathObjectPtr xpathObj = NULL;
|
|
Packit |
284210 |
xmlChar *content_option = NULL;
|
|
Packit |
284210 |
char *mac_link = NULL;
|
|
Packit |
284210 |
int rc, elts = 0;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr == NULL)
|
|
Packit |
284210 |
return -1;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (msr->crypto_html_tree == NULL) {
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4, "hash_response_body_links: Cannot parse NULL html tree");
|
|
Packit |
284210 |
return -1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr->txcfg->crypto_hash_href_rx == 0 && msr->txcfg->crypto_hash_href_pm == 0
|
|
Packit |
284210 |
&& msr->txcfg->crypto_hash_faction_rx == 0 && msr->txcfg->crypto_hash_faction_pm == 0
|
|
Packit |
284210 |
&& msr->txcfg->crypto_hash_iframesrc_rx == 0 && msr->txcfg->crypto_hash_iframesrc_pm == 0
|
|
Packit |
284210 |
&& msr->txcfg->crypto_hash_framesrc_rx == 0 && msr->txcfg->crypto_hash_framesrc_pm == 0)
|
|
Packit |
284210 |
return -1;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
xpathCtx = xmlXPathNewContext(msr->crypto_html_tree);
|
|
Packit |
284210 |
if(xpathCtx == NULL) {
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4, "hash_response_body_links: Unable to create Xpath context.");
|
|
Packit |
284210 |
goto ctx_error;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
lcount=fcount=0;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr->txcfg->crypto_hash_href_rx == 1 || msr->txcfg->crypto_hash_href_pm == 1) {
|
|
Packit |
284210 |
|
|
Packit |
284210 |
xpathObj = xmlXPathEvalExpression((xmlChar*)"//*[@href]", xpathCtx);
|
|
Packit |
284210 |
if(xpathObj == NULL) {
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4,
|
|
Packit |
284210 |
"hash_response_body_links: Unable to evaluate xpath expression.");
|
|
Packit |
284210 |
goto obj_error;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
lsize = (xpathObj->nodesetval) ? xpathObj->nodesetval->nodeNr : 0;
|
|
Packit |
284210 |
for(i = lsize - 1; i >=0; i--) {
|
|
Packit |
284210 |
register xmlNodePtr cur;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
cur = xpathObj->nodesetval->nodeTab[i];
|
|
Packit |
284210 |
if(cur != NULL){
|
|
Packit |
284210 |
xmlChar *href = xmlGetProp(cur, (const xmlChar *) "href");
|
|
Packit |
284210 |
char *content_href = normalize_path(msr, (char *)href);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(content_href != NULL && strstr(content_href,msr->txcfg->crypto_param_name) == NULL) {
|
|
Packit |
284210 |
if(msr->txcfg->crypto_hash_href_rx == 1) {
|
|
Packit |
284210 |
rc = do_hash_method(msr, (char *)content_href, HASH_URL_HREF_HASH_RX);
|
|
Packit |
284210 |
if(rc > 0) {
|
|
Packit |
284210 |
mac_link = NULL;
|
|
Packit |
284210 |
mac_link = do_hash_link(msr, (char *)content_href, FULL_LINK);
|
|
Packit |
284210 |
if(mac_link != NULL) {
|
|
Packit |
284210 |
xmlSetProp(cur, (const xmlChar *) "href", (const xmlChar *) mac_link);
|
|
Packit |
284210 |
lcount++;
|
|
Packit |
284210 |
bytes += strlen(mac_link);
|
|
Packit |
284210 |
msr->of_stream_changed = 1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
mac_link = NULL;
|
|
Packit |
284210 |
if(href != NULL)
|
|
Packit |
284210 |
xmlFree(href);
|
|
Packit |
284210 |
continue;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
if(msr->txcfg->crypto_hash_href_pm == 1) {
|
|
Packit |
284210 |
rc = do_hash_method(msr, (char *)content_href, HASH_URL_HREF_HASH_PM);
|
|
Packit |
284210 |
if(rc > 0) {
|
|
Packit |
284210 |
mac_link = NULL;
|
|
Packit |
284210 |
mac_link = do_hash_link(msr, (char *)content_href, FULL_LINK);
|
|
Packit |
284210 |
if(mac_link != NULL) {
|
|
Packit |
284210 |
xmlSetProp(cur, (const xmlChar *) "href", (const xmlChar *) mac_link);
|
|
Packit |
284210 |
lcount++;
|
|
Packit |
284210 |
bytes += strlen(mac_link);
|
|
Packit |
284210 |
msr->of_stream_changed = 1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
mac_link = NULL;
|
|
Packit |
284210 |
if(href != NULL)
|
|
Packit |
284210 |
xmlFree(href);
|
|
Packit |
284210 |
continue;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(href != NULL) {
|
|
Packit |
284210 |
xmlFree(href);
|
|
Packit |
284210 |
href = NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(xpathObj != NULL)
|
|
Packit |
284210 |
xmlXPathFreeObject(xpathObj);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr->txcfg->crypto_hash_faction_rx == 1 || msr->txcfg->crypto_hash_faction_pm == 1) {
|
|
Packit |
284210 |
xpathObj = xmlXPathEvalExpression((xmlChar*)"//form", xpathCtx);
|
|
Packit |
284210 |
if(xpathObj == NULL) {
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4,
|
|
Packit |
284210 |
"hash_response_body_links: Unable to evaluate xpath expression.");
|
|
Packit |
284210 |
goto obj_error;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
fsize = (xpathObj->nodesetval) ? xpathObj->nodesetval->nodeNr : 0;
|
|
Packit |
284210 |
for(i = fsize - 1; i >=0; i--) {
|
|
Packit |
284210 |
register xmlNodePtr cur;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
cur = xpathObj->nodesetval->nodeTab[i];
|
|
Packit |
284210 |
if((cur != NULL)){
|
|
Packit |
284210 |
xmlChar *action = NULL;
|
|
Packit |
284210 |
char *content_action = NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(content_option)
|
|
Packit |
284210 |
xmlFree(content_option);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
action = xmlGetProp(cur, (const xmlChar *) "action");
|
|
Packit |
284210 |
content_action = normalize_path(msr, (char *)action);
|
|
Packit |
284210 |
content_option = xmlGetProp(cur, (const xmlChar *) "option");
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(content_action != NULL && content_option == NULL && strstr(content_action,msr->txcfg->crypto_param_name) == NULL) {
|
|
Packit |
284210 |
if(msr->txcfg->crypto_hash_faction_rx == 1) {
|
|
Packit |
284210 |
rc = do_hash_method(msr, (char *)content_action, HASH_URL_FACTION_HASH_RX);
|
|
Packit |
284210 |
if(rc > 0) {
|
|
Packit |
284210 |
mac_link = NULL;
|
|
Packit |
284210 |
mac_link = do_hash_link(msr, (char *)content_action, FULL_LINK);
|
|
Packit |
284210 |
if(mac_link != NULL) {
|
|
Packit |
284210 |
xmlSetProp(cur, (const xmlChar *) "action", (const xmlChar *) mac_link);
|
|
Packit |
284210 |
fcount++;
|
|
Packit |
284210 |
bytes += strlen(mac_link);
|
|
Packit |
284210 |
msr->of_stream_changed = 1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
mac_link = NULL;
|
|
Packit |
284210 |
if(action != NULL)
|
|
Packit |
284210 |
xmlFree(action);
|
|
Packit |
284210 |
continue;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
if(msr->txcfg->crypto_hash_faction_pm == 1) {
|
|
Packit |
284210 |
rc = do_hash_method(msr, (char *)content_action, HASH_URL_FACTION_HASH_PM);
|
|
Packit |
284210 |
if(rc > 0) {
|
|
Packit |
284210 |
mac_link = NULL;
|
|
Packit |
284210 |
mac_link = do_hash_link(msr, (char *)content_action, FULL_LINK);
|
|
Packit |
284210 |
if(mac_link != NULL) {
|
|
Packit |
284210 |
xmlSetProp(cur, (const xmlChar *) "action", (const xmlChar *) mac_link);
|
|
Packit |
284210 |
fcount++;
|
|
Packit |
284210 |
bytes += strlen(mac_link);
|
|
Packit |
284210 |
msr->of_stream_changed = 1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
mac_link = NULL;
|
|
Packit |
284210 |
if(action != NULL)
|
|
Packit |
284210 |
xmlFree(action);
|
|
Packit |
284210 |
continue;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(action != NULL) {
|
|
Packit |
284210 |
xmlFree(action);
|
|
Packit |
284210 |
action = NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(content_option) {
|
|
Packit |
284210 |
xmlFree(content_option);
|
|
Packit |
284210 |
content_option = NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(xpathObj != NULL)
|
|
Packit |
284210 |
xmlXPathFreeObject(xpathObj);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr->txcfg->crypto_hash_iframesrc_rx == 1 || msr->txcfg->crypto_hash_iframesrc_pm == 1) {
|
|
Packit |
284210 |
xpathObj = xmlXPathEvalExpression((xmlChar*)"//iframe", xpathCtx);
|
|
Packit |
284210 |
if(xpathObj == NULL) {
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4,
|
|
Packit |
284210 |
"hash_response_body_links: Unable to evaluate xpath expression.");
|
|
Packit |
284210 |
goto obj_error;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
isize = (xpathObj->nodesetval) ? xpathObj->nodesetval->nodeNr : 0;
|
|
Packit |
284210 |
for(i = isize - 1; i >=0; i--) {
|
|
Packit |
284210 |
register xmlNodePtr cur;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
cur = xpathObj->nodesetval->nodeTab[i];
|
|
Packit |
284210 |
if((cur != NULL)){
|
|
Packit |
284210 |
|
|
Packit |
284210 |
xmlChar *src = xmlGetProp(cur, (const xmlChar *) "src");
|
|
Packit |
284210 |
char *content_src = normalize_path(msr, (char *)src);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(content_src != NULL && strstr(content_src,msr->txcfg->crypto_param_name) == NULL) {
|
|
Packit |
284210 |
if(msr->txcfg->crypto_hash_iframesrc_rx == 1) {
|
|
Packit |
284210 |
rc = do_hash_method(msr, (char *)content_src, HASH_URL_IFRAMESRC_HASH_RX);
|
|
Packit |
284210 |
if(rc > 0) {
|
|
Packit |
284210 |
mac_link = NULL;
|
|
Packit |
284210 |
mac_link = do_hash_link(msr, (char *)content_src, FULL_LINK);
|
|
Packit |
284210 |
if(mac_link != NULL) {
|
|
Packit |
284210 |
xmlSetProp(cur, (const xmlChar *) "src", (const xmlChar *) mac_link);
|
|
Packit |
284210 |
icount++;
|
|
Packit |
284210 |
bytes += strlen(mac_link);
|
|
Packit |
284210 |
msr->of_stream_changed = 1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
mac_link = NULL;
|
|
Packit |
284210 |
if(src != NULL)
|
|
Packit |
284210 |
xmlFree(src);
|
|
Packit |
284210 |
continue;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
if(msr->txcfg->crypto_hash_iframesrc_pm == 1) {
|
|
Packit |
284210 |
rc = do_hash_method(msr, (char *)content_src, HASH_URL_IFRAMESRC_HASH_PM);
|
|
Packit |
284210 |
if(rc > 0) {
|
|
Packit |
284210 |
mac_link = NULL;
|
|
Packit |
284210 |
mac_link = do_hash_link(msr, (char *)content_src, FULL_LINK);
|
|
Packit |
284210 |
if(mac_link != NULL) {
|
|
Packit |
284210 |
xmlSetProp(cur, (const xmlChar *) "src", (const xmlChar *) mac_link);
|
|
Packit |
284210 |
icount++;
|
|
Packit |
284210 |
bytes += strlen(mac_link);
|
|
Packit |
284210 |
msr->of_stream_changed = 1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
mac_link = NULL;
|
|
Packit |
284210 |
if(src != NULL)
|
|
Packit |
284210 |
xmlFree(src);
|
|
Packit |
284210 |
continue;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(src != NULL) {
|
|
Packit |
284210 |
xmlFree(src);
|
|
Packit |
284210 |
src = NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(xpathObj != NULL)
|
|
Packit |
284210 |
xmlXPathFreeObject(xpathObj);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr->txcfg->crypto_hash_framesrc_rx == 1 || msr->txcfg->crypto_hash_framesrc_pm == 1) {
|
|
Packit |
284210 |
xpathObj = xmlXPathEvalExpression((xmlChar*)"//frame", xpathCtx);
|
|
Packit |
284210 |
if(xpathObj == NULL) {
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4,
|
|
Packit |
284210 |
"hash_response_body_links: Unable to evaluate xpath expression.");
|
|
Packit |
284210 |
goto obj_error;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
frsize = (xpathObj->nodesetval) ? xpathObj->nodesetval->nodeNr : 0;
|
|
Packit |
284210 |
for(i = frsize - 1; i >=0; i--) {
|
|
Packit |
284210 |
register xmlNodePtr cur;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
cur = xpathObj->nodesetval->nodeTab[i];
|
|
Packit |
284210 |
if((cur != NULL)){
|
|
Packit |
284210 |
|
|
Packit |
284210 |
xmlChar *src = xmlGetProp(cur, (const xmlChar *) "src");
|
|
Packit |
284210 |
char *content_src = normalize_path(msr, (char *)src);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(content_src != NULL && strstr(content_src,msr->txcfg->crypto_param_name) == NULL) {
|
|
Packit |
284210 |
if(msr->txcfg->crypto_hash_framesrc_rx == 1) {
|
|
Packit |
284210 |
rc = do_hash_method(msr, (char *)content_src, HASH_URL_FRAMESRC_HASH_RX);
|
|
Packit |
284210 |
if(rc > 0) {
|
|
Packit |
284210 |
mac_link = NULL;
|
|
Packit |
284210 |
mac_link = do_hash_link(msr, (char *)content_src, FULL_LINK);
|
|
Packit |
284210 |
if(mac_link != NULL) {
|
|
Packit |
284210 |
xmlSetProp(cur, (const xmlChar *) "src", (const xmlChar *) mac_link);
|
|
Packit |
284210 |
frcount++;
|
|
Packit |
284210 |
bytes += strlen(mac_link);
|
|
Packit |
284210 |
msr->of_stream_changed = 1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
mac_link = NULL;
|
|
Packit |
284210 |
if(src != NULL)
|
|
Packit |
284210 |
xmlFree(src);
|
|
Packit |
284210 |
continue;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
if(msr->txcfg->crypto_hash_framesrc_pm == 1) {
|
|
Packit |
284210 |
rc = do_hash_method(msr, (char *)content_src, HASH_URL_FRAMESRC_HASH_PM);
|
|
Packit |
284210 |
if(rc > 0) {
|
|
Packit |
284210 |
mac_link = NULL;
|
|
Packit |
284210 |
mac_link = do_hash_link(msr, (char *)content_src, FULL_LINK);
|
|
Packit |
284210 |
if(mac_link != NULL) {
|
|
Packit |
284210 |
xmlSetProp(cur, (const xmlChar *) "src", (const xmlChar *) mac_link);
|
|
Packit |
284210 |
frcount++;
|
|
Packit |
284210 |
bytes += strlen(mac_link);
|
|
Packit |
284210 |
msr->of_stream_changed = 1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
mac_link = NULL;
|
|
Packit |
284210 |
if(src != NULL)
|
|
Packit |
284210 |
xmlFree(src);
|
|
Packit |
284210 |
continue;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(src != NULL) {
|
|
Packit |
284210 |
xmlFree(src);
|
|
Packit |
284210 |
src = NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(xpathObj != NULL)
|
|
Packit |
284210 |
xmlXPathFreeObject(xpathObj);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(xpathCtx != NULL)
|
|
Packit |
284210 |
xmlXPathFreeContext(xpathCtx);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4) {
|
|
Packit |
284210 |
msr_log(msr, 4, "hash_response_body_links: Processed [%d] iframe src, [%d] hashed.",isize, icount);
|
|
Packit |
284210 |
msr_log(msr, 4, "hash_response_body_links: Processed [%d] frame src, [%d] hashed.",frsize, frcount);
|
|
Packit |
284210 |
msr_log(msr, 4, "hash_response_body_links: Processed [%d] form actions, [%d] hashed.",fsize, fcount);
|
|
Packit |
284210 |
msr_log(msr, 4, "hash_response_body_links: Processed [%d] links, [%d] hashed.",lsize, lcount);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr->of_stream_changed == 0) {
|
|
Packit |
284210 |
if(msr->crypto_html_tree != NULL) {
|
|
Packit |
284210 |
xmlFreeDoc(msr->crypto_html_tree);
|
|
Packit |
284210 |
msr->crypto_html_tree = NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
return 0;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
elts = (icount+frcount+fcount+lcount);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if((elts >= INT32_MAX) || (elts < 0))
|
|
Packit |
284210 |
return 0;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return bytes;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
obj_error:
|
|
Packit |
284210 |
if(xpathCtx != NULL)
|
|
Packit |
284210 |
xmlXPathFreeContext(xpathCtx);
|
|
Packit |
284210 |
ctx_error:
|
|
Packit |
284210 |
return -1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
/**
|
|
Packit |
284210 |
* \brief Inject the new response body
|
|
Packit |
284210 |
*
|
|
Packit |
284210 |
* \param msr ModSecurity transaction resource
|
|
Packit |
284210 |
* \param elts Number of hashed elements
|
|
Packit |
284210 |
*
|
|
Packit |
284210 |
* \retval 1 On success
|
|
Packit |
284210 |
* \retval -1 On fail
|
|
Packit |
284210 |
*/
|
|
Packit |
284210 |
int inject_hashed_response_body(modsec_rec *msr, int elts) {
|
|
Packit |
284210 |
xmlOutputBufferPtr output_buf = NULL;
|
|
Packit |
284210 |
xmlCharEncodingHandlerPtr handler = NULL;
|
|
Packit |
284210 |
char *p = NULL;
|
|
Packit |
284210 |
const char *ctype = NULL;
|
|
Packit |
284210 |
const char *encoding = NULL;
|
|
Packit |
284210 |
char *new_ct = NULL, *content_value = NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr == NULL) return -1;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr->r == NULL) return -1;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (msr->crypto_html_tree == NULL) {
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4, "inject_hashed_response_body: Cannot parse NULL html tree");
|
|
Packit |
284210 |
return -1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr->r->content_type != NULL)
|
|
Packit |
284210 |
ctype = msr->r->content_type;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
encoding = (const char *) htmlGetMetaEncoding(msr->crypto_html_tree);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (ctype && encoding == NULL) {
|
|
Packit |
284210 |
if (ctype && (p = m_strcasestr(ctype, "charset=") , p != NULL)) {
|
|
Packit |
284210 |
p += 8 ;
|
|
Packit |
284210 |
if (encoding = apr_pstrndup(msr->mp, p, strcspn(p, " ;") ), encoding) {
|
|
Packit |
284210 |
xmlCharEncoding enc;
|
|
Packit |
284210 |
enc = xmlParseCharEncoding(encoding);
|
|
Packit |
284210 |
handler = xmlFindCharEncodingHandler(encoding);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
} else {
|
|
Packit |
284210 |
if(encoding != NULL) {
|
|
Packit |
284210 |
xmlCharEncoding enc;
|
|
Packit |
284210 |
enc = xmlParseCharEncoding(encoding);
|
|
Packit |
284210 |
handler = xmlFindCharEncodingHandler(encoding);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4, "inject_hashed_response_body: Detected encoding type [%s].", encoding);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (handler == NULL)
|
|
Packit |
284210 |
handler = xmlFindCharEncodingHandler("UTF-8");
|
|
Packit |
284210 |
if (handler == NULL)
|
|
Packit |
284210 |
handler = xmlFindCharEncodingHandler("ISO-8859-1");
|
|
Packit |
284210 |
if (handler == NULL)
|
|
Packit |
284210 |
handler = xmlFindCharEncodingHandler("HTML");
|
|
Packit |
284210 |
if (handler == NULL)
|
|
Packit |
284210 |
handler = xmlFindCharEncodingHandler("ascii");
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(handler == NULL) {
|
|
Packit |
284210 |
xmlFreeDoc(msr->crypto_html_tree);
|
|
Packit |
284210 |
return -1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
apr_table_unset(msr->r->headers_out,"Content-Type");
|
|
Packit |
284210 |
new_ct = (char*)apr_psprintf(msr->mp, "text/html;%s",handler->name);
|
|
Packit |
284210 |
apr_table_set(msr->r->err_headers_out,"Content-Type",new_ct);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4, "inject_hashed_response_body: Using content-type [%s].", handler->name);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
output_buf = xmlAllocOutputBuffer(handler);
|
|
Packit |
284210 |
if (output_buf == NULL) {
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4, "inject_hashed_response_body: Unable to allocate memory buffer.");
|
|
Packit |
284210 |
xmlFreeDoc(msr->crypto_html_tree);
|
|
Packit |
284210 |
return -1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
htmlDocContentDumpFormatOutput(output_buf, msr->crypto_html_tree, NULL, 0);
|
|
Packit |
284210 |
// Not necessary in 2.9.4+
|
|
Packit |
284210 |
//xmlOutputBufferFlush(output_buf);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
#ifdef LIBXML2_NEW_BUFFER
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (output_buf->conv == NULL || (output_buf->conv && xmlOutputBufferGetSize(output_buf) == 0)) {
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(output_buf->buffer == NULL || xmlOutputBufferGetSize(output_buf) == 0) {
|
|
Packit |
284210 |
xmlOutputBufferClose(output_buf);
|
|
Packit |
284210 |
xmlFreeDoc(msr->crypto_html_tree);
|
|
Packit |
284210 |
msr->of_stream_changed = 0;
|
|
Packit |
284210 |
msr_log(msr, 4, "inject_hashed_response_body: NEW_BUFFER Output buffer is null.");
|
|
Packit |
284210 |
return -1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr->stream_output_data != NULL) {
|
|
Packit |
284210 |
free(msr->stream_output_data);
|
|
Packit |
284210 |
msr->stream_output_data = NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
msr->stream_output_length = xmlOutputBufferGetSize(output_buf);
|
|
Packit |
284210 |
msr->stream_output_data = (char *)malloc(msr->stream_output_length+1);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (msr->stream_output_data == NULL) {
|
|
Packit |
284210 |
xmlOutputBufferClose(output_buf);
|
|
Packit |
284210 |
xmlFreeDoc(msr->crypto_html_tree);
|
|
Packit |
284210 |
msr_log(msr, 4, "inject_hashed_response_body: NEW BUFFER Stream Output is null.");
|
|
Packit |
284210 |
return -1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
memset(msr->stream_output_data, 0x0, msr->stream_output_length+1);
|
|
Packit |
284210 |
memcpy(msr->stream_output_data, xmlOutputBufferGetContent(output_buf), msr->stream_output_length);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4, "inject_hashed_response_body: Copying XML tree from CONTENT to stream buffer [%zu] bytes.", xmlOutputBufferGetSize(output_buf));
|
|
Packit |
284210 |
|
|
Packit |
284210 |
} else {
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(output_buf->conv == NULL || xmlOutputBufferGetSize(output_buf) == 0) {
|
|
Packit |
284210 |
xmlOutputBufferClose(output_buf);
|
|
Packit |
284210 |
xmlFreeDoc(msr->crypto_html_tree);
|
|
Packit |
284210 |
msr->of_stream_changed = 0;
|
|
Packit |
284210 |
msr_log(msr, 4, "inject_hashed_response_body: Conv is null.");
|
|
Packit |
284210 |
return -1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr->stream_output_data != NULL) {
|
|
Packit |
284210 |
free(msr->stream_output_data);
|
|
Packit |
284210 |
msr->stream_output_data = NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
msr->stream_output_length = xmlOutputBufferGetSize(output_buf);
|
|
Packit |
284210 |
msr->stream_output_data = (char *)malloc(msr->stream_output_length+1);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (msr->stream_output_data == NULL) {
|
|
Packit |
284210 |
msr_log(msr, 4, "inject_hashed_response_body: Stream Output data is NULL.");
|
|
Packit |
284210 |
xmlOutputBufferClose(output_buf);
|
|
Packit |
284210 |
xmlFreeDoc(msr->crypto_html_tree);
|
|
Packit |
284210 |
return -1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
memset(msr->stream_output_data, 0x0, msr->stream_output_length+1);
|
|
Packit |
284210 |
memcpy(msr->stream_output_data, xmlOutputBufferGetContent(output_buf), msr->stream_output_length);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4, "inject_hashed_response_body: Copying XML tree from CONV to stream buffer [%zu] bytes.", xmlOutputBufferGetSize(output_buf));
|
|
Packit |
284210 |
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
#else
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (output_buf->conv == NULL || (output_buf->conv && output_buf->conv->use == 0)) {
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(output_buf->buffer == NULL || output_buf->buffer->use == 0) {
|
|
Packit |
284210 |
xmlOutputBufferClose(output_buf);
|
|
Packit |
284210 |
xmlFreeDoc(msr->crypto_html_tree);
|
|
Packit |
284210 |
msr_log(msr, 4, "inject_hashed_response_body: Output buffer is null.");
|
|
Packit |
284210 |
msr->of_stream_changed = 0;
|
|
Packit |
284210 |
return -1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr->stream_output_data != NULL) {
|
|
Packit |
284210 |
free(msr->stream_output_data);
|
|
Packit |
284210 |
msr->stream_output_data = NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
msr->stream_output_length = output_buf->buffer->use;
|
|
Packit |
284210 |
msr->stream_output_data = (char *)malloc(msr->stream_output_length+1);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (msr->stream_output_data == NULL) {
|
|
Packit |
284210 |
xmlOutputBufferClose(output_buf);
|
|
Packit |
284210 |
xmlFreeDoc(msr->crypto_html_tree);
|
|
Packit |
284210 |
msr_log(msr, 4, "inject_hashed_response_body: Stream Output is null.");
|
|
Packit |
284210 |
return -1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
memset(msr->stream_output_data, 0x0, msr->stream_output_length+1);
|
|
Packit |
284210 |
memcpy(msr->stream_output_data, (char *)xmlBufferContent(output_buf->buffer), msr->stream_output_length);
|
|
Packit |
284210 |
//memcpy(msr->stream_output_data, output_buf->buffer->content, msr->stream_output_length);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4, "inject_hashed_response_body: Copying XML tree from CONTENT to stream buffer [%d] bytes.", msr->stream_output_length);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
} else {
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(output_buf->conv == NULL || output_buf->conv->use == 0) {
|
|
Packit |
284210 |
xmlOutputBufferClose(output_buf);
|
|
Packit |
284210 |
xmlFreeDoc(msr->crypto_html_tree);
|
|
Packit |
284210 |
msr->of_stream_changed = 0;
|
|
Packit |
284210 |
msr_log(msr, 4, "inject_hashed_response_body: Stream Output is null.");
|
|
Packit |
284210 |
return -1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr->stream_output_data != NULL) {
|
|
Packit |
284210 |
free(msr->stream_output_data);
|
|
Packit |
284210 |
msr->stream_output_data = NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
msr->stream_output_length = output_buf->conv->use;
|
|
Packit |
284210 |
msr->stream_output_data = (char *)malloc(msr->stream_output_length+1);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (msr->stream_output_data == NULL) {
|
|
Packit |
284210 |
xmlOutputBufferClose(output_buf);
|
|
Packit |
284210 |
xmlFreeDoc(msr->crypto_html_tree);
|
|
Packit |
284210 |
msr_log(msr, 4, "inject_hashed_response_body: Stream Output Data is null.");
|
|
Packit |
284210 |
return -1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
memset(msr->stream_output_data, 0x0, msr->stream_output_length+1);
|
|
Packit |
284210 |
memcpy(msr->stream_output_data, (char *)xmlBufferContent(output_buf->conv), msr->stream_output_length);
|
|
Packit |
284210 |
//memcpy(msr->stream_output_data, output_buf->conv->content, msr->stream_output_length);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4, "inject_hashed_response_body: Copying XML tree from CONV to stream buffer [%d] bytes.", msr->stream_output_length);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
#endif
|
|
Packit |
284210 |
|
|
Packit |
284210 |
xmlOutputBufferClose(output_buf);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
content_value = (char*)apr_psprintf(msr->mp, "%"APR_SIZE_T_FMT, msr->stream_output_length);
|
|
Packit |
284210 |
apr_table_unset(msr->r->headers_out,"Content-Length");
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4, "inject_hashed_response_body: Setting new content value %s", content_value);
|
|
Packit |
284210 |
apr_table_set(msr->r->headers_out, "Content-Length", content_value);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
xmlFreeDoc(msr->crypto_html_tree);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4, "inject_hashed_response_body: Stream buffer [%"APR_SIZE_T_FMT"]. Done",msr->stream_output_length);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return 1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
/**
|
|
Packit |
284210 |
* \brief Parse and MAC html elements
|
|
Packit |
284210 |
*
|
|
Packit |
284210 |
* \param msr ModSecurity transaction resource
|
|
Packit |
284210 |
* \param link The html attr value to be checked
|
|
Packit |
284210 |
* \param type The hash method type
|
|
Packit |
284210 |
*
|
|
Packit |
284210 |
* \retval mac_link MACed link
|
|
Packit |
284210 |
* \retval NULL on fail
|
|
Packit |
284210 |
*/
|
|
Packit |
284210 |
char *do_hash_link(modsec_rec *msr, char *link, int type) {
|
|
Packit |
284210 |
char *mac_link = NULL;
|
|
Packit |
284210 |
char *path_chunk = NULL;
|
|
Packit |
284210 |
char *hash_value = NULL;
|
|
Packit |
284210 |
char *qm = NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr == NULL) return NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(strlen(link) > 7 && strncmp("http:",(char*)link,5)==0){
|
|
Packit |
284210 |
path_chunk = strchr(link+7,'/');
|
|
Packit |
284210 |
if(path_chunk != NULL) {
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4) {
|
|
Packit |
284210 |
msr_log(msr, 4, "Signing data [%s]", path_chunk+1);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr->txcfg->crypto_key_add == HASH_KEYONLY)
|
|
Packit |
284210 |
hash_value = hmac(msr, msr->txcfg->crypto_key, msr->txcfg->crypto_key_len, (unsigned char *) path_chunk+1, strlen((char*)path_chunk)-1);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr->txcfg->crypto_key_add == HASH_SESSIONID) {
|
|
Packit |
284210 |
if(msr->sessionid == NULL || strlen(msr->sessionid) == 0) {
|
|
Packit |
284210 |
#if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER > 2
|
|
Packit |
284210 |
const char *new_pwd = apr_psprintf(msr->mp,"%s%s", msr->txcfg->crypto_key, msr->r->connection->client_ip);
|
|
Packit |
284210 |
#else
|
|
Packit |
284210 |
const char *new_pwd = apr_psprintf(msr->mp,"%s%s", msr->txcfg->crypto_key, msr->r->connection->remote_ip);
|
|
Packit |
284210 |
#endif
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4, "Session id is empty. Using REMOTE_IP");
|
|
Packit |
284210 |
msr->txcfg->crypto_key_len = strlen(new_pwd);
|
|
Packit |
284210 |
hash_value = hmac(msr, new_pwd, msr->txcfg->crypto_key_len, (unsigned char *) path_chunk+1, strlen((char*)path_chunk)-1);
|
|
Packit |
284210 |
} else {
|
|
Packit |
284210 |
const char *new_pwd = apr_psprintf(msr->mp,"%s%s", msr->txcfg->crypto_key, msr->sessionid);
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4, "Using session id [%s]", msr->sessionid);
|
|
Packit |
284210 |
msr->txcfg->crypto_key_len = strlen(new_pwd);
|
|
Packit |
284210 |
hash_value = hmac(msr, new_pwd, msr->txcfg->crypto_key_len, (unsigned char *) path_chunk+1, strlen((char*)path_chunk)-1);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr->txcfg->crypto_key_add == HASH_REMOTEIP) {
|
|
Packit |
284210 |
#if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER > 2
|
|
Packit |
284210 |
const char *new_pwd = apr_psprintf(msr->mp,"%s%s", msr->txcfg->crypto_key, msr->r->connection->client_ip);
|
|
Packit |
284210 |
#else
|
|
Packit |
284210 |
const char *new_pwd = apr_psprintf(msr->mp,"%s%s", msr->txcfg->crypto_key, msr->r->connection->remote_ip);
|
|
Packit |
284210 |
#endif
|
|
Packit |
284210 |
msr->txcfg->crypto_key_len = strlen(new_pwd);
|
|
Packit |
284210 |
hash_value = hmac(msr, new_pwd, msr->txcfg->crypto_key_len, (unsigned char *) path_chunk+1, strlen((char*)path_chunk)-1);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
} else {
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
} else
|
|
Packit |
284210 |
if(strlen(link) > 8 && strncmp("https",(char*)link,5)==0){
|
|
Packit |
284210 |
path_chunk = strchr(link+8,'/');
|
|
Packit |
284210 |
if(path_chunk != NULL) {
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4) {
|
|
Packit |
284210 |
msr_log(msr, 4, "Signing data [%s]", path_chunk+1);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr->txcfg->crypto_key_add == HASH_KEYONLY)
|
|
Packit |
284210 |
hash_value = hmac(msr, msr->txcfg->crypto_key, msr->txcfg->crypto_key_len, (unsigned char *) path_chunk+1, strlen((char*)path_chunk)-1);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr->txcfg->crypto_key_add == HASH_SESSIONID) {
|
|
Packit |
284210 |
if(msr->sessionid == NULL || strlen(msr->sessionid) == 0) {
|
|
Packit |
284210 |
#if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER > 2
|
|
Packit |
284210 |
const char *new_pwd = apr_psprintf(msr->mp,"%s%s", msr->txcfg->crypto_key, msr->r->connection->client_ip);
|
|
Packit |
284210 |
#else
|
|
Packit |
284210 |
const char *new_pwd = apr_psprintf(msr->mp,"%s%s", msr->txcfg->crypto_key, msr->r->connection->remote_ip);
|
|
Packit |
284210 |
#endif
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4, "Session id is empty. Using REMOTE_IP");
|
|
Packit |
284210 |
msr->txcfg->crypto_key_len = strlen(new_pwd);
|
|
Packit |
284210 |
hash_value = hmac(msr, new_pwd, msr->txcfg->crypto_key_len, (unsigned char *) path_chunk+1, strlen((char*)path_chunk)-1);
|
|
Packit |
284210 |
} else {
|
|
Packit |
284210 |
const char *new_pwd = apr_psprintf(msr->mp,"%s%s", msr->txcfg->crypto_key, msr->sessionid);
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4, "Using session id [%s]", msr->sessionid);
|
|
Packit |
284210 |
msr->txcfg->crypto_key_len = strlen(new_pwd);
|
|
Packit |
284210 |
hash_value = hmac(msr, new_pwd, msr->txcfg->crypto_key_len, (unsigned char *) path_chunk+1, strlen((char*)path_chunk)-1);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr->txcfg->crypto_key_add == HASH_REMOTEIP) {
|
|
Packit |
284210 |
#if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER > 2
|
|
Packit |
284210 |
const char *new_pwd = apr_psprintf(msr->mp,"%s%s", msr->txcfg->crypto_key, msr->r->connection->client_ip);
|
|
Packit |
284210 |
#else
|
|
Packit |
284210 |
const char *new_pwd = apr_psprintf(msr->mp,"%s%s", msr->txcfg->crypto_key, msr->r->connection->remote_ip);
|
|
Packit |
284210 |
#endif
|
|
Packit |
284210 |
msr->txcfg->crypto_key_len = strlen(new_pwd);
|
|
Packit |
284210 |
hash_value = hmac(msr, new_pwd, msr->txcfg->crypto_key_len, (unsigned char *) path_chunk+1, strlen((char*)path_chunk)-1);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
} else {
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
else if(*link=='/'){
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4) {
|
|
Packit |
284210 |
msr_log(msr, 4, "Signing data [%s]", link+1);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr->txcfg->crypto_key_add == HASH_KEYONLY)
|
|
Packit |
284210 |
hash_value = hmac(msr, msr->txcfg->crypto_key, msr->txcfg->crypto_key_len, (unsigned char *) link+1, strlen((char*)link)-1);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr->txcfg->crypto_key_add == HASH_SESSIONID) {
|
|
Packit |
284210 |
if(msr->sessionid == NULL || strlen(msr->sessionid) == 0) {
|
|
Packit |
284210 |
#if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER > 2
|
|
Packit |
284210 |
const char *new_pwd = apr_psprintf(msr->mp,"%s%s", msr->txcfg->crypto_key, msr->r->connection->client_ip);
|
|
Packit |
284210 |
#else
|
|
Packit |
284210 |
const char *new_pwd = apr_psprintf(msr->mp,"%s%s", msr->txcfg->crypto_key, msr->r->connection->remote_ip);
|
|
Packit |
284210 |
#endif
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4, "Session id is empty. Using REMOTE_IP");
|
|
Packit |
284210 |
msr->txcfg->crypto_key_len = strlen(new_pwd);
|
|
Packit |
284210 |
hash_value = hmac(msr, new_pwd, msr->txcfg->crypto_key_len, (unsigned char *) link+1, strlen((char*)link)-1);
|
|
Packit |
284210 |
} else {
|
|
Packit |
284210 |
const char *new_pwd = apr_psprintf(msr->mp,"%s%s", msr->txcfg->crypto_key, msr->sessionid);
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4, "Using session id [%s]", msr->sessionid);
|
|
Packit |
284210 |
msr->txcfg->crypto_key_len = strlen(new_pwd);
|
|
Packit |
284210 |
hash_value = hmac(msr, new_pwd, msr->txcfg->crypto_key_len, (unsigned char *) link+1, strlen((char*)link)-1);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr->txcfg->crypto_key_add == HASH_REMOTEIP) {
|
|
Packit |
284210 |
#if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER > 2
|
|
Packit |
284210 |
const char *new_pwd = apr_psprintf(msr->mp,"%s%s", msr->txcfg->crypto_key, msr->r->connection->client_ip);
|
|
Packit |
284210 |
#else
|
|
Packit |
284210 |
const char *new_pwd = apr_psprintf(msr->mp,"%s%s", msr->txcfg->crypto_key, msr->r->connection->remote_ip);
|
|
Packit |
284210 |
#endif
|
|
Packit |
284210 |
msr->txcfg->crypto_key_len = strlen(new_pwd);
|
|
Packit |
284210 |
hash_value = hmac(msr, new_pwd, msr->txcfg->crypto_key_len, (unsigned char *) link+1, strlen((char*)link)-1);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
else {
|
|
Packit |
284210 |
char *relative_link = NULL;
|
|
Packit |
284210 |
char *filename = NULL;
|
|
Packit |
284210 |
char *relative_path = NULL;
|
|
Packit |
284210 |
char *relative_uri = NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
filename = file_basename(msr->mp, msr->r->parsed_uri.path);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(filename == NULL || (strlen(msr->r->parsed_uri.path) - strlen(filename) < 0))
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
relative_path = apr_pstrndup(msr->mp, msr->r->parsed_uri.path, strlen(msr->r->parsed_uri.path) - strlen(filename));
|
|
Packit |
284210 |
relative_uri = apr_pstrcat(msr->mp, relative_path, link, NULL);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
relative_link = relative_uri+1;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4) {
|
|
Packit |
284210 |
msr_log(msr, 4, "Signing data [%s] size %zu", relative_link, strlen(relative_link));
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr->txcfg->crypto_key_add == HASH_KEYONLY)
|
|
Packit |
284210 |
hash_value = hmac(msr, msr->txcfg->crypto_key, msr->txcfg->crypto_key_len, (unsigned char *) relative_link, strlen((char*)relative_link));
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr->txcfg->crypto_key_add == HASH_SESSIONID) {
|
|
Packit |
284210 |
if(msr->sessionid == NULL || strlen(msr->sessionid) == 0) {
|
|
Packit |
284210 |
#if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER > 2
|
|
Packit |
284210 |
const char *new_pwd = apr_psprintf(msr->mp,"%s%s", msr->txcfg->crypto_key, msr->r->connection->client_ip);
|
|
Packit |
284210 |
#else
|
|
Packit |
284210 |
const char *new_pwd = apr_psprintf(msr->mp,"%s%s", msr->txcfg->crypto_key, msr->r->connection->remote_ip);
|
|
Packit |
284210 |
#endif
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4, "Session id is empty. Using REMOTE_IP");
|
|
Packit |
284210 |
msr->txcfg->crypto_key_len = strlen(new_pwd);
|
|
Packit |
284210 |
hash_value = hmac(msr, new_pwd, msr->txcfg->crypto_key_len, (unsigned char *) relative_link, strlen((char*)relative_link));
|
|
Packit |
284210 |
} else {
|
|
Packit |
284210 |
const char *new_pwd = apr_psprintf(msr->mp,"%s%s", msr->txcfg->crypto_key, msr->sessionid);
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 4)
|
|
Packit |
284210 |
msr_log(msr, 4, "Using session id [%s]", msr->sessionid);
|
|
Packit |
284210 |
msr->txcfg->crypto_key_len = strlen(new_pwd);
|
|
Packit |
284210 |
hash_value = hmac(msr, new_pwd, msr->txcfg->crypto_key_len, (unsigned char *) relative_link, strlen((char*)relative_link));
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr->txcfg->crypto_key_add == HASH_REMOTEIP) {
|
|
Packit |
284210 |
#if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER > 2
|
|
Packit |
284210 |
const char *new_pwd = apr_psprintf(msr->mp,"%s%s", msr->txcfg->crypto_key, msr->r->connection->client_ip);
|
|
Packit |
284210 |
#else
|
|
Packit |
284210 |
const char *new_pwd = apr_psprintf(msr->mp,"%s%s", msr->txcfg->crypto_key, msr->r->connection->remote_ip);
|
|
Packit |
284210 |
#endif
|
|
Packit |
284210 |
msr->txcfg->crypto_key_len = strlen(new_pwd);
|
|
Packit |
284210 |
hash_value = hmac(msr, new_pwd, msr->txcfg->crypto_key_len, (unsigned char *) relative_link, strlen((char*)relative_link));
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
link = relative_uri;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(hash_value == NULL) return NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(type == HASH_ONLY)
|
|
Packit |
284210 |
return hash_value;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
qm = strchr((char*)link,'?');
|
|
Packit |
284210 |
if(qm == NULL){
|
|
Packit |
284210 |
mac_link= (char*)apr_psprintf(msr->mp, "%s?%s=%s", link, msr->txcfg->crypto_param_name, (char *)hash_value);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
else{
|
|
Packit |
284210 |
mac_link= (char*)apr_psprintf(msr->mp, "%s&%s=%s", link, msr->txcfg->crypto_param_name, (char*)hash_value);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return mac_link;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
/**
|
|
Packit |
284210 |
* \brief Modify Location in case of status 302 and 301
|
|
Packit |
284210 |
*
|
|
Packit |
284210 |
* \param msr ModSecurity transaction resource
|
|
Packit |
284210 |
*
|
|
Packit |
284210 |
* \retval 1 On Success
|
|
Packit |
284210 |
* \retval 0 on fail
|
|
Packit |
284210 |
*/
|
|
Packit |
284210 |
int modify_response_header(modsec_rec *msr) {
|
|
Packit |
284210 |
char *mac_link = NULL;
|
|
Packit |
284210 |
const char *location = NULL;
|
|
Packit |
284210 |
int rc = 0;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr == NULL) return 0;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 9)
|
|
Packit |
284210 |
msr_log(msr, 4, "HTTP status (%d)", msr->response_status);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr->response_status != HTTP_MOVED_TEMPORARILY &&
|
|
Packit |
284210 |
msr->response_status != HTTP_MOVED_PERMANENTLY) {
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 9)
|
|
Packit |
284210 |
msr_log(msr, 4, "Skipping status other than 302 an 301");
|
|
Packit |
284210 |
return 0;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
location = apr_table_get(msr->r->headers_out, "Location");
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(location == NULL || strlen(location) == 0)
|
|
Packit |
284210 |
return 0;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 9)
|
|
Packit |
284210 |
msr_log(msr, 4, "Processing reponse header location [%s]", location);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(msr->txcfg->crypto_hash_location_rx == 1) {
|
|
Packit |
284210 |
rc = do_hash_method(msr, (char *)location, HASH_URL_LOCATION_HASH_RX);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(rc > 0) {
|
|
Packit |
284210 |
mac_link = NULL;
|
|
Packit |
284210 |
mac_link = do_hash_link(msr, (char *)location, FULL_LINK);
|
|
Packit |
284210 |
} else {
|
|
Packit |
284210 |
return 0;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
} else if(msr->txcfg->crypto_hash_location_pm == 1) {
|
|
Packit |
284210 |
rc = do_hash_method(msr, (char *)location, HASH_URL_LOCATION_HASH_PM);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(rc > 0) {
|
|
Packit |
284210 |
mac_link = NULL;
|
|
Packit |
284210 |
mac_link = do_hash_link(msr, (char *)location, FULL_LINK);
|
|
Packit |
284210 |
} else {
|
|
Packit |
284210 |
return 0;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(mac_link == NULL)
|
|
Packit |
284210 |
return 0;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (msr->txcfg->debuglog_level >= 9)
|
|
Packit |
284210 |
msr_log(msr, 4, "Setting new reponse header location [%s]", mac_link);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(rc > 0) {
|
|
Packit |
284210 |
apr_table_unset(msr->r->headers_out,"Location");
|
|
Packit |
284210 |
apr_table_set(msr->r->headers_out, "Location",(char*)apr_psprintf(msr->mp,"%s", mac_link));
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return 1;
|
|
Packit |
284210 |
}
|