|
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 |
//#undef inline
|
|
Packit |
284210 |
#define inline inline
|
|
Packit |
284210 |
|
|
Packit |
284210 |
#include <stdio.h>
|
|
Packit |
284210 |
#include <conio.h>
|
|
Packit |
284210 |
#include "api.h"
|
|
Packit |
284210 |
|
|
Packit |
284210 |
|
|
Packit |
284210 |
char *config_file = NULL;
|
|
Packit |
284210 |
char *url_file = NULL;
|
|
Packit |
284210 |
char *event_files[1024];
|
|
Packit |
284210 |
int event_file_cnt;
|
|
Packit |
284210 |
char *event_file = NULL;
|
|
Packit |
284210 |
int event_file_len = 0;
|
|
Packit |
284210 |
char **event_file_lines;
|
|
Packit |
284210 |
int event_line_cnt = 0;
|
|
Packit |
284210 |
int event_file_blocks[256];
|
|
Packit |
284210 |
|
|
Packit |
284210 |
#define EVENT_FILE_MAX_SIZE (16*1024*1024)
|
|
Packit |
284210 |
|
|
Packit |
284210 |
#define MAX_URLS 4096
|
|
Packit |
284210 |
|
|
Packit |
284210 |
char urls[MAX_URLS][4096];
|
|
Packit |
284210 |
int url_cnt = 0;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
void readeventfile(char *name)
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
if(event_file == NULL)
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
event_file = (char *)malloc(EVENT_FILE_MAX_SIZE);
|
|
Packit |
284210 |
event_file_lines = (char **)malloc(EVENT_FILE_MAX_SIZE);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
event_file_len = 0;
|
|
Packit |
284210 |
event_line_cnt = 0;
|
|
Packit |
284210 |
memset(event_file_blocks, -1, sizeof(int) * 256);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
FILE *fr = fopen(name, "rb");
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(fr == NULL)
|
|
Packit |
284210 |
return;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
event_file_len = fread(event_file, 1, EVENT_FILE_MAX_SIZE - 1, fr);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
fclose(fr);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
event_file[event_file_len] = 0;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
void parseeventfile()
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
if(event_file_len == 0 || event_file == NULL)
|
|
Packit |
284210 |
return;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
char *t = event_file;
|
|
Packit |
284210 |
char *e = event_file + event_file_len;
|
|
Packit |
284210 |
int nocrlf = 1;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
while(t < e)
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
event_file_lines[event_line_cnt++] = t;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
while(t < e && *t != 10 && *t != 13)
|
|
Packit |
284210 |
t++;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
char ct = *t;
|
|
Packit |
284210 |
*t = 0;
|
|
Packit |
284210 |
int i = event_line_cnt - 1;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
int l = strlen(event_file_lines[i]);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(l == 14 && event_file_lines[i][0] == '-' && event_file_lines[i][1] == '-' && event_file_lines[i][l-2] == '-' && event_file_lines[i][l-1] == '-')
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
char blk = event_file_lines[i][l-3];
|
|
Packit |
284210 |
|
|
Packit |
284210 |
event_file_blocks[blk] = i;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(blk == 'C' || blk == 'G')
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
nocrlf = 0;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
else
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
nocrlf = 1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
*t = ct;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(nocrlf)
|
|
Packit |
284210 |
while(t < e && (*t == 10 || *t == 13))
|
|
Packit |
284210 |
*t++ = 0;
|
|
Packit |
284210 |
else
|
|
Packit |
284210 |
while(t < e && (*t == 10 || *t == 13))
|
|
Packit |
284210 |
t++;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
void parseargs(int argc, char *argv[])
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
int i = 1;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
event_file_cnt = 0;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
while(i < argc)
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
if(argv[i][0] == '-')
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
if(argv[i][1] == 'c' && i < argc - 1)
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
config_file = argv[i + 1];
|
|
Packit |
284210 |
i += 2;
|
|
Packit |
284210 |
continue;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
if(argv[i][1] == 'u' && i < argc - 1)
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
url_file = argv[i + 1];
|
|
Packit |
284210 |
i += 2;
|
|
Packit |
284210 |
continue;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
i++;
|
|
Packit |
284210 |
continue;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
if(event_file_cnt == 1024)
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
fprintf(stderr, "Too many input files! (limit 1024)\n");
|
|
Packit |
284210 |
break;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
event_files[event_file_cnt++] = argv[i++];
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
void log(void *obj, int level, char *str)
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
printf("%s\n", str);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
unsigned int bodypos = 0;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
apr_status_t readbody(request_rec *r, char *buf, unsigned int length, unsigned int *readcnt, int *is_eos)
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
int j = event_file_blocks['C'];
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(j < 0)
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
*is_eos = 1;
|
|
Packit |
284210 |
return APR_SUCCESS;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
j++;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(event_file_lines[j][0] == 0)
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
*is_eos = 1;
|
|
Packit |
284210 |
return APR_SUCCESS;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
unsigned int l = strlen(event_file_lines[j]);
|
|
Packit |
284210 |
unsigned int size = length;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(bodypos + size > l)
|
|
Packit |
284210 |
size = l - bodypos;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
memcpy(buf, &event_file_lines[j][bodypos], size);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
bodypos += size;
|
|
Packit |
284210 |
*readcnt = size;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(bodypos == l)
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
*is_eos = 1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return APR_SUCCESS;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
unsigned int responsepos = 0;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
apr_status_t readresponse(request_rec *r, char *buf, unsigned int length, unsigned int *readcnt, int *is_eos)
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
int j = event_file_blocks['G'];
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(j < 0)
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
*is_eos = 1;
|
|
Packit |
284210 |
return APR_SUCCESS;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
j++;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(event_file_lines[j][0] == 0)
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
*is_eos = 1;
|
|
Packit |
284210 |
return APR_SUCCESS;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
unsigned int l = strlen(event_file_lines[j]);
|
|
Packit |
284210 |
unsigned int size = length;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(responsepos + size > l)
|
|
Packit |
284210 |
size = l - responsepos;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
memcpy(buf, &event_file_lines[j][responsepos], size);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
responsepos += size;
|
|
Packit |
284210 |
*readcnt = size;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(responsepos == l)
|
|
Packit |
284210 |
*is_eos = 1;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return APR_SUCCESS;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
void main(int argc, char *argv[])
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
directory_config *config;
|
|
Packit |
284210 |
conn_rec *c;
|
|
Packit |
284210 |
request_rec *r;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
parseargs(argc, argv);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(config_file == NULL || argc < 3)
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
printf("Usage:\n");
|
|
Packit |
284210 |
printf("standalone.exe -c <config_file> [-u <text_file_with_urls>] <event_file1> [<event_file2> <event_file3> ...]\n");
|
|
Packit |
284210 |
return;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
modsecSetLogHook(NULL, log);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
modsecSetReadBody(readbody);
|
|
Packit |
284210 |
modsecSetReadResponse(readresponse);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
modsecInit();
|
|
Packit |
284210 |
|
|
Packit |
284210 |
modsecStartConfig();
|
|
Packit |
284210 |
|
|
Packit |
284210 |
config = modsecGetDefaultConfig();
|
|
Packit |
284210 |
|
|
Packit |
284210 |
const char * err = modsecProcessConfig(config, config_file, "c:\\inetpub\\wwwroot");
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(err != NULL)
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
printf("%s\n", err);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
modsecFinalizeConfig();
|
|
Packit |
284210 |
|
|
Packit |
284210 |
modsecInitProcess();
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(url_file != NULL)
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
FILE *fr = fopen(url_file, "rb");
|
|
Packit |
284210 |
int i = 0;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
while(fgets(urls[i],4096,fr) != NULL)
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
urls[i][4095] = 0;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
int l = strlen(urls[i]) - 1;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(l < 8)
|
|
Packit |
284210 |
continue;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
while(urls[i][l] == 10 || urls[i][l] == 13)
|
|
Packit |
284210 |
l--;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
urls[i++][l + 1] = 0;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
url_cnt = i;
|
|
Packit |
284210 |
fclose(fr);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
for(int i = 0; i < event_file_cnt; i++)
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
if(url_cnt == 0)
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
urls[0][0] = 0;
|
|
Packit |
284210 |
url_cnt = 1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
for(int ui = 0; ui < url_cnt; ui++)
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
readeventfile(event_files[i]);
|
|
Packit |
284210 |
parseeventfile();
|
|
Packit |
284210 |
|
|
Packit |
284210 |
bodypos = 0;
|
|
Packit |
284210 |
responsepos = 0;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
c = modsecNewConnection();
|
|
Packit |
284210 |
|
|
Packit |
284210 |
modsecProcessConnection(c);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
r = modsecNewRequest(c, config);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
int j = event_file_blocks['B'];
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(j < 0)
|
|
Packit |
284210 |
continue;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
j++;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(event_file_lines[j][0] == 0)
|
|
Packit |
284210 |
continue;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
char *method = event_file_lines[j];
|
|
Packit |
284210 |
char *url = strchr(method, 32);
|
|
Packit |
284210 |
char *proto = strchr(url + 1, 32);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(url == NULL || proto == NULL)
|
|
Packit |
284210 |
continue;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
*url++=0;
|
|
Packit |
284210 |
*proto++=0;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(urls[ui][0] != 0)
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
url = urls[ui];
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
#define SETMETHOD(m) if(strcmp(method,#m) == 0){ r->method = method; r->method_number = M_##m; }
|
|
Packit |
284210 |
|
|
Packit |
284210 |
r->method = "INVALID";
|
|
Packit |
284210 |
r->method_number = M_INVALID;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
SETMETHOD(OPTIONS)
|
|
Packit |
284210 |
SETMETHOD(GET)
|
|
Packit |
284210 |
SETMETHOD(POST)
|
|
Packit |
284210 |
SETMETHOD(PUT)
|
|
Packit |
284210 |
SETMETHOD(DELETE)
|
|
Packit |
284210 |
SETMETHOD(TRACE)
|
|
Packit |
284210 |
SETMETHOD(CONNECT)
|
|
Packit |
284210 |
SETMETHOD(MOVE)
|
|
Packit |
284210 |
SETMETHOD(COPY)
|
|
Packit |
284210 |
SETMETHOD(PROPFIND)
|
|
Packit |
284210 |
SETMETHOD(PROPPATCH)
|
|
Packit |
284210 |
SETMETHOD(MKCOL)
|
|
Packit |
284210 |
SETMETHOD(LOCK)
|
|
Packit |
284210 |
SETMETHOD(UNLOCK)
|
|
Packit |
284210 |
|
|
Packit |
284210 |
r->protocol = proto;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
while(event_file_lines[++j][0] != 0)
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
char *value = strchr(event_file_lines[j], ':');
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(value == NULL)
|
|
Packit |
284210 |
break;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
*value++ = 0;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
while(*value <=32 && *value != 0)
|
|
Packit |
284210 |
value++;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
apr_table_setn(r->headers_in, event_file_lines[j], value);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
r->content_encoding = apr_table_get(r->headers_in, "Content-Encoding");
|
|
Packit |
284210 |
r->content_type = apr_table_get(r->headers_in, "Content-Type");
|
|
Packit |
284210 |
r->hostname = apr_table_get(r->headers_in, "Host");
|
|
Packit |
284210 |
r->path_info = url;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
char *query = strchr(url, '?');
|
|
Packit |
284210 |
char *rawurl = url;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(query != NULL)
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
rawurl = (char *)apr_palloc(r->pool, strlen(url) + 1);
|
|
Packit |
284210 |
strcpy(rawurl, url);
|
|
Packit |
284210 |
*query++ = 0;
|
|
Packit |
284210 |
r->args = query;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
const char *lng = apr_table_get(r->headers_in, "Content-Languages");
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(lng != NULL)
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
r->content_languages = apr_array_make(r->pool, 1, sizeof(const char *));
|
|
Packit |
284210 |
|
|
Packit |
284210 |
*(const char **)apr_array_push(r->content_languages) = lng;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
r->request_time = apr_time_now();
|
|
Packit |
284210 |
|
|
Packit |
284210 |
r->parsed_uri.scheme = "http";
|
|
Packit |
284210 |
r->parsed_uri.path = r->path_info;
|
|
Packit |
284210 |
r->parsed_uri.hostname = (char *)r->hostname;
|
|
Packit |
284210 |
r->parsed_uri.is_initialized = 1;
|
|
Packit |
284210 |
r->parsed_uri.port = 80;
|
|
Packit |
284210 |
r->parsed_uri.port_str = "80";
|
|
Packit |
284210 |
r->parsed_uri.query = r->args;
|
|
Packit |
284210 |
r->parsed_uri.dns_looked_up = 0;
|
|
Packit |
284210 |
r->parsed_uri.dns_resolved = 0;
|
|
Packit |
284210 |
r->parsed_uri.password = NULL;
|
|
Packit |
284210 |
r->parsed_uri.user = NULL;
|
|
Packit |
284210 |
r->parsed_uri.fragment = NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
r->unparsed_uri = rawurl;
|
|
Packit |
284210 |
r->uri = r->unparsed_uri;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
r->the_request = (char *)apr_palloc(r->pool, strlen(r->method) + 1 + strlen(r->uri) + 1 + strlen(r->protocol) + 1);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
strcpy(r->the_request, r->method);
|
|
Packit |
284210 |
strcat(r->the_request, " ");
|
|
Packit |
284210 |
strcat(r->the_request, r->uri);
|
|
Packit |
284210 |
strcat(r->the_request, " ");
|
|
Packit |
284210 |
strcat(r->the_request, r->protocol);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
apr_table_setn(r->subprocess_env, "UNIQUE_ID", "1");
|
|
Packit |
284210 |
|
|
Packit |
284210 |
modsecProcessRequest(r);
|
|
Packit |
284210 |
modsecProcessResponse(r);
|
|
Packit |
284210 |
modsecFinishRequest(r);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
modsecTerminate();
|
|
Packit |
284210 |
getch();
|
|
Packit |
284210 |
}
|