Blame standalone/main.cpp

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
}