|
Packit Service |
384592 |
/*
|
|
Packit Service |
384592 |
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
|
Packit Service |
384592 |
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
|
Packit Service |
384592 |
*
|
|
Packit Service |
384592 |
* You may not use this file except in compliance with
|
|
Packit Service |
384592 |
* the License. You may obtain a copy of the License at
|
|
Packit Service |
384592 |
*
|
|
Packit Service |
384592 |
* http://www.apache.org/licenses/LICENSE-2.0
|
|
Packit Service |
384592 |
*
|
|
Packit Service |
384592 |
* If any of the files related to licensing are missing or if you have any
|
|
Packit Service |
384592 |
* other questions related to licensing please contact Trustwave Holdings, Inc.
|
|
Packit Service |
384592 |
* directly using the email address security@modsecurity.org.
|
|
Packit Service |
384592 |
*/
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
#include <apr.h>
|
|
Packit Service |
384592 |
#include <apr_getopt.h>
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
#include "modsecurity.h"
|
|
Packit Service |
384592 |
#include "re.h"
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
#define ISHEX(X) (((X >= '0')&&(X <= '9')) || ((X >= 'a')&&(X <= 'f')) || ((X >= 'A')&&(X <= 'F')))
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
#define BUFLEN 32768
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
#define RESULT_SUCCESS 0
|
|
Packit Service |
384592 |
#define RESULT_ERROR -1
|
|
Packit Service |
384592 |
#define RESULT_MISMATCHED -2
|
|
Packit Service |
384592 |
#define RESULT_WRONGSIZE -3
|
|
Packit Service |
384592 |
#define RESULT_WRONGRET -4
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
#define DEFAULT_ACTION "phase:2,log,auditlog,pass"
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
#define CMDLINE_OPTS "t:n:p:P:r:I:D:Nh"
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* Types */
|
|
Packit Service |
384592 |
typedef struct tfn_data_t tfn_data_t;
|
|
Packit Service |
384592 |
typedef struct op_data_t op_data_t;
|
|
Packit Service |
384592 |
typedef struct action_data_t action_data_t;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
struct tfn_data_t {
|
|
Packit Service |
384592 |
const char *name;
|
|
Packit Service |
384592 |
const char *param;
|
|
Packit Service |
384592 |
unsigned char *input;
|
|
Packit Service |
384592 |
apr_size_t input_len;
|
|
Packit Service |
384592 |
msre_tfn_metadata *metadata;
|
|
Packit Service |
384592 |
};
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
struct op_data_t {
|
|
Packit Service |
384592 |
const char *name;
|
|
Packit Service |
384592 |
const char *param;
|
|
Packit Service |
384592 |
unsigned char *input;
|
|
Packit Service |
384592 |
apr_size_t input_len;
|
|
Packit Service |
384592 |
msre_ruleset *ruleset;
|
|
Packit Service |
384592 |
msre_rule *rule;
|
|
Packit Service |
384592 |
msre_var *var;
|
|
Packit Service |
384592 |
msre_op_metadata *metadata;
|
|
Packit Service |
384592 |
};
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
struct action_data_t {
|
|
Packit Service |
384592 |
const char *name;
|
|
Packit Service |
384592 |
unsigned char *input;
|
|
Packit Service |
384592 |
apr_size_t input_len;
|
|
Packit Service |
384592 |
msre_ruleset *ruleset;
|
|
Packit Service |
384592 |
msre_rule *rule;
|
|
Packit Service |
384592 |
msre_var *var;
|
|
Packit Service |
384592 |
msre_actionset *actionset;
|
|
Packit Service |
384592 |
msre_action *action;
|
|
Packit Service |
384592 |
};
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* Globals */
|
|
Packit Service |
384592 |
static int debuglog_level = 0;
|
|
Packit Service |
384592 |
static char *test_name = NULL;
|
|
Packit Service |
384592 |
static apr_pool_t *g_mp = NULL;
|
|
Packit Service |
384592 |
static modsec_rec *g_msr = NULL;
|
|
Packit Service |
384592 |
static unsigned char buf[BUFLEN];
|
|
Packit Service |
384592 |
msc_engine *modsecurity = NULL;
|
|
Packit Service |
384592 |
unsigned long int DSOLOCAL msc_pcre_match_limit = 0;
|
|
Packit Service |
384592 |
unsigned long int DSOLOCAL msc_pcre_match_limit_recursion = 0;
|
|
Packit Service |
384592 |
char DSOLOCAL *real_server_signature = NULL;
|
|
Packit Service |
384592 |
int DSOLOCAL remote_rules_fail_action = REMOTE_RULES_ABORT_ON_FAIL;
|
|
Packit Service |
384592 |
char DSOLOCAL *remote_rules_fail_message = NULL;
|
|
Packit Service |
384592 |
module AP_MODULE_DECLARE_DATA security2_module = {
|
|
Packit Service |
384592 |
NULL,
|
|
Packit Service |
384592 |
NULL,
|
|
Packit Service |
384592 |
NULL,
|
|
Packit Service |
384592 |
NULL,
|
|
Packit Service |
384592 |
NULL,
|
|
Packit Service |
384592 |
NULL,
|
|
Packit Service |
384592 |
NULL
|
|
Packit Service |
384592 |
};
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* Stubs */
|
|
Packit Service |
384592 |
char *format_error_log_message(apr_pool_t *mp, error_message_t *em) {
|
|
Packit Service |
384592 |
return "FAKE ERROR LOG MESSAGE";
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
apr_status_t send_error_bucket(modsec_rec *msr, ap_filter_t *f, int status) {
|
|
Packit Service |
384592 |
return APR_SUCCESS;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
int apache2_exec(modsec_rec *msr, const char *command, const char **argv, char **output) {
|
|
Packit Service |
384592 |
return 0;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
char *get_apr_error(apr_pool_t *p, apr_status_t rc) {
|
|
Packit Service |
384592 |
char *text = apr_pcalloc(p, 201);
|
|
Packit Service |
384592 |
if (text == NULL) return NULL;
|
|
Packit Service |
384592 |
apr_strerror(rc, text, 200);
|
|
Packit Service |
384592 |
return text;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
void msr_log(modsec_rec *msr, int level, const char *text, ...) {
|
|
Packit Service |
384592 |
va_list ap;
|
|
Packit Service |
384592 |
char str1[1024] = "";
|
|
Packit Service |
384592 |
char str2[1256] = "";
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if ((msr == NULL) || (level > msr->txcfg->debuglog_level)) {
|
|
Packit Service |
384592 |
return;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
if (msr->txcfg->debuglog_fd == NOT_SET_P) {
|
|
Packit Service |
384592 |
if (apr_file_open(&msr->txcfg->debuglog_fd, msr->txcfg->debuglog_name, APR_READ|APR_WRITE|APR_CREATE|APR_APPEND|APR_BINARY, APR_OS_DEFAULT, g_mp) != APR_SUCCESS) {
|
|
Packit Service |
384592 |
fprintf(stderr, "ERROR: failed to create unit test debug log \"%s\".\n", msr->txcfg->debuglog_name);
|
|
Packit Service |
384592 |
msr->txcfg->debuglog_fd = NULL;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
va_start(ap, text);
|
|
Packit Service |
384592 |
if (msr->txcfg->debuglog_fd != NULL) {
|
|
Packit Service |
384592 |
apr_size_t nbytes_written = 0;
|
|
Packit Service |
384592 |
apr_vsnprintf(str1, sizeof(str1), text, ap);
|
|
Packit Service |
384592 |
apr_snprintf(str2, sizeof(str2), "%lu: [%d] [%s] %s\n", (unsigned long)getpid(), level, test_name, str1);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
apr_file_write_full(msr->txcfg->debuglog_fd, str2, strlen(str2), &nbytes_written);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
va_end(ap);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
void msr_log_error(modsec_rec *msr, const char *text, ...) {
|
|
Packit Service |
384592 |
va_list ap;
|
|
Packit Service |
384592 |
int level = 3;
|
|
Packit Service |
384592 |
char str1[1024] = "";
|
|
Packit Service |
384592 |
char str2[1256] = "";
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if ((msr == NULL) || (level > msr->txcfg->debuglog_level)) {
|
|
Packit Service |
384592 |
return;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
if (msr->txcfg->debuglog_fd == NOT_SET_P) {
|
|
Packit Service |
384592 |
if (apr_file_open(&msr->txcfg->debuglog_fd, msr->txcfg->debuglog_name, APR_READ|APR_WRITE|APR_CREATE|APR_APPEND|APR_BINARY, APR_OS_DEFAULT, g_mp) != APR_SUCCESS) {
|
|
Packit Service |
384592 |
fprintf(stderr, "ERROR: failed to create unit test debug log \"%s\".\n", msr->txcfg->debuglog_name);
|
|
Packit Service |
384592 |
msr->txcfg->debuglog_fd = NULL;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
va_start(ap, text);
|
|
Packit Service |
384592 |
if (msr->txcfg->debuglog_fd != NULL) {
|
|
Packit Service |
384592 |
apr_size_t nbytes_written = 0;
|
|
Packit Service |
384592 |
apr_vsnprintf(str1, sizeof(str1), text, ap);
|
|
Packit Service |
384592 |
apr_snprintf(str2, sizeof(str2), "%lu: [%d] [%s] %s\n", (unsigned long)getpid(), level, test_name, str1);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
apr_file_write_full(msr->txcfg->debuglog_fd, str2, strlen(str2), &nbytes_written);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
va_end(ap);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
void msr_log_warn(modsec_rec *msr, const char *text, ...) {
|
|
Packit Service |
384592 |
va_list ap;
|
|
Packit Service |
384592 |
int level = 4;
|
|
Packit Service |
384592 |
char str1[1024] = "";
|
|
Packit Service |
384592 |
char str2[1256] = "";
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if ((msr == NULL) || (level > msr->txcfg->debuglog_level)) {
|
|
Packit Service |
384592 |
return;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
if (msr->txcfg->debuglog_fd == NOT_SET_P) {
|
|
Packit Service |
384592 |
if (apr_file_open(&msr->txcfg->debuglog_fd, msr->txcfg->debuglog_name, APR_READ|APR_WRITE|APR_CREATE|APR_APPEND|APR_BINARY, APR_OS_DEFAULT, g_mp) != APR_SUCCESS) {
|
|
Packit Service |
384592 |
fprintf(stderr, "ERROR: failed to create unit test debug log \"%s\".\n", msr->txcfg->debuglog_name);
|
|
Packit Service |
384592 |
msr->txcfg->debuglog_fd = NULL;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
va_start(ap, text);
|
|
Packit Service |
384592 |
if (msr->txcfg->debuglog_fd != NULL) {
|
|
Packit Service |
384592 |
apr_size_t nbytes_written = 0;
|
|
Packit Service |
384592 |
apr_vsnprintf(str1, sizeof(str1), text, ap);
|
|
Packit Service |
384592 |
apr_snprintf(str2, sizeof(str2), "%lu: [%d] [%s] %s\n", (unsigned long)getpid(), level, test_name, str1);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
apr_file_write_full(msr->txcfg->debuglog_fd, str2, strlen(str2), &nbytes_written);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
va_end(ap);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
#define ap_get_remote_host(a, b, c, d) test_ap_get_remote_host(a, b, c, d)
|
|
Packit Service |
384592 |
const char *test_ap_get_remote_host(conn_rec *conn, void *dir_config, int type, int *str_is_ip) {
|
|
Packit Service |
384592 |
return "FAKE-REMOTE-HOST";
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
char *get_env_var(request_rec *r, char *name) {
|
|
Packit Service |
384592 |
return "FAKE-ENV-VAR";
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
#define unixd_set_global_mutex_perms(a) my_unixd_set_global_mutex_perms(a)
|
|
Packit Service |
384592 |
apr_status_t my_unixd_set_global_mutex_perms(apr_global_mutex_t *gmutex) {
|
|
Packit Service |
384592 |
return APR_SUCCESS;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
#define unixd_set_proc_mutex_perms(a) my_unixd_set_proc_mutex_perms(a)
|
|
Packit Service |
384592 |
apr_status_t my_unixd_set_proc_mutex_perms(apr_proc_mutex_t *pmutex) {
|
|
Packit Service |
384592 |
return APR_SUCCESS;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* Escaping functions */
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
static unsigned char hex2dec(unsigned char *what) {
|
|
Packit Service |
384592 |
register unsigned char digit;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A') + 10 : (what[0] - '0'));
|
|
Packit Service |
384592 |
digit *= 16;
|
|
Packit Service |
384592 |
digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A') + 10 : (what[1] - '0'));
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return digit;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
static unsigned char *unescape_inplace(unsigned char *str, apr_size_t *len)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
apr_size_t i, j;
|
|
Packit Service |
384592 |
for (i = j = 0; i < *len; j++) {
|
|
Packit Service |
384592 |
if ((str[i] == '\\') && (i + 3 < *len) && (str[i + 1] == 'x') && ISHEX(str[i + 2]) && ISHEX(str[i + 3]) ) {
|
|
Packit Service |
384592 |
str[j] = hex2dec(str + i + 2);
|
|
Packit Service |
384592 |
i += 4;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
else {
|
|
Packit Service |
384592 |
str[j] = str[i++];
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
*len = j;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
while (j < i) {
|
|
Packit Service |
384592 |
str[j++] = '\0';
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return str;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
static char *escape(unsigned char *str, apr_size_t *len)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
char *new = apr_pcalloc(g_mp, (*len * 4) + 1);
|
|
Packit Service |
384592 |
apr_size_t i, j;
|
|
Packit Service |
384592 |
for (i = j = 0; i < *len; i++) {
|
|
Packit Service |
384592 |
if ((str[i] >= 0x20) && (str[i] <= 0x7e)) {
|
|
Packit Service |
384592 |
new[j++] = str[i];
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
else {
|
|
Packit Service |
384592 |
sprintf(new + j, "\\x%02x", str[i]);
|
|
Packit Service |
384592 |
j += 4;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
*len = j;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return new;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* Testing functions */
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
static int init_tfn(tfn_data_t *data, const char *name, unsigned char *input, apr_size_t input_len, char **errmsg) {
|
|
Packit Service |
384592 |
*errmsg = NULL;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
data->name = name;
|
|
Packit Service |
384592 |
data->input = apr_pmemdup(g_mp, input, input_len);
|
|
Packit Service |
384592 |
data->input_len = input_len;
|
|
Packit Service |
384592 |
data->metadata = msre_engine_tfn_resolve(modsecurity->msre, name);
|
|
Packit Service |
384592 |
if (data->metadata == NULL) {
|
|
Packit Service |
384592 |
*errmsg = apr_psprintf(g_mp, "Failed to fetch tfn \"%s\".", name);
|
|
Packit Service |
384592 |
return -1;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return 0;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
static int test_tfn(tfn_data_t *data, unsigned char **rval, apr_size_t *rval_len, char **errmsg)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
int rc = -1;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
*errmsg = NULL;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* Execute the tfn */
|
|
Packit Service |
384592 |
rc = data->metadata->execute(g_mp, data->input, (long)(data->input_len), (char **)rval, (long *)rval_len);
|
|
Packit Service |
384592 |
if (rc < 0) {
|
|
Packit Service |
384592 |
*errmsg = apr_psprintf(g_mp, "Failed to execute tfn \"%s\".", data->name);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return rc;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
static int init_op(op_data_t *data, const char *name, const char *param, unsigned char *input, apr_size_t input_len, char **errmsg) {
|
|
Packit Service |
384592 |
const char *args = apr_psprintf(g_mp, "@%s %s", name, param);
|
|
Packit Service |
384592 |
char *conf_fn;
|
|
Packit Service |
384592 |
int rc = -1;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
*errmsg = NULL;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
data->name = name;
|
|
Packit Service |
384592 |
data->param = param;
|
|
Packit Service |
384592 |
data->input = input;
|
|
Packit Service |
384592 |
data->input_len = input_len;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if ( apr_filepath_merge(&conf_fn, NULL, "unit-test.conf", APR_FILEPATH_TRUENAME, g_mp) != APR_SUCCESS) {
|
|
Packit Service |
384592 |
*errmsg = apr_psprintf(g_mp, "Failed to build a conf filename.");
|
|
Packit Service |
384592 |
return -1;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* Register UNIT_TEST variable */
|
|
Packit Service |
384592 |
msre_engine_variable_register(modsecurity->msre,
|
|
Packit Service |
384592 |
"UNIT_TEST",
|
|
Packit Service |
384592 |
VAR_SIMPLE,
|
|
Packit Service |
384592 |
0, 0,
|
|
Packit Service |
384592 |
NULL,
|
|
Packit Service |
384592 |
NULL,
|
|
Packit Service |
384592 |
VAR_DONT_CACHE,
|
|
Packit Service |
384592 |
PHASE_REQUEST_HEADERS
|
|
Packit Service |
384592 |
);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* Lookup the operator */
|
|
Packit Service |
384592 |
data->metadata = msre_engine_op_resolve(modsecurity->msre, name);
|
|
Packit Service |
384592 |
if (data->metadata == NULL) {
|
|
Packit Service |
384592 |
*errmsg = apr_psprintf(g_mp, "Failed to fetch op \"%s\".", name);
|
|
Packit Service |
384592 |
return -1;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* Create a ruleset/rule */
|
|
Packit Service |
384592 |
data->ruleset = msre_ruleset_create(modsecurity->msre, g_mp);
|
|
Packit Service |
384592 |
if (data->ruleset == NULL) {
|
|
Packit Service |
384592 |
*errmsg = apr_psprintf(g_mp, "Failed to create ruleset for op \"%s\".", name);
|
|
Packit Service |
384592 |
return -1;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
data->rule = msre_rule_create(data->ruleset, RULE_TYPE_NORMAL, conf_fn, 1, "UNIT_TEST", args, DEFAULT_ACTION, errmsg);
|
|
Packit Service |
384592 |
if (data->rule == NULL) {
|
|
Packit Service |
384592 |
*errmsg = apr_psprintf(g_mp, "Failed to create rule for op \"%s\": %s", name, *errmsg);
|
|
Packit Service |
384592 |
return -1;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* Create a fake variable */
|
|
Packit Service |
384592 |
data->var = (msre_var *)apr_pcalloc(g_mp, sizeof(msre_var));
|
|
Packit Service |
384592 |
data->var->name = "UNIT_TEST";
|
|
Packit Service |
384592 |
data->var->value = apr_pstrmemdup(g_mp, (char *)input, input_len);
|
|
Packit Service |
384592 |
data->var->value_len = input_len;
|
|
Packit Service |
384592 |
data->var->metadata = msre_resolve_var(modsecurity->msre, data->var->name);
|
|
Packit Service |
384592 |
if (data->var->metadata == NULL) {
|
|
Packit Service |
384592 |
*errmsg = apr_psprintf(g_mp, "Failed to resolve variable for op \"%s\": %s", name, data->var->name);
|
|
Packit Service |
384592 |
return -1;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* Initialize the operator parameter */
|
|
Packit Service |
384592 |
if (data->metadata->param_init != NULL) {
|
|
Packit Service |
384592 |
rc = data->metadata->param_init(data->rule, errmsg);
|
|
Packit Service |
384592 |
if (rc <= 0) {
|
|
Packit Service |
384592 |
*errmsg = apr_psprintf(g_mp, "Failed to init op \"%s\": %s", name, *errmsg);
|
|
Packit Service |
384592 |
return rc;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return 0;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
static int test_op(op_data_t *data, char **errmsg)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
int rc = -1;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
*errmsg = NULL;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* Execute the operator */
|
|
Packit Service |
384592 |
if (data->metadata->execute != NULL) {
|
|
Packit Service |
384592 |
rc = data->metadata->execute(g_msr, data->rule, data->var, errmsg);
|
|
Packit Service |
384592 |
if (rc < 0) {
|
|
Packit Service |
384592 |
*errmsg = apr_psprintf(g_mp, "Failed to execute op \"%s\": %s", data->name, *errmsg);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return rc;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
static int init_action(action_data_t *data, const char *name, const char *param, char **errmsg)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
const char *action_string = NULL;
|
|
Packit Service |
384592 |
char *conf_fn;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
*errmsg = NULL;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if ((param == NULL) || (strcmp("", param) == 0)) {
|
|
Packit Service |
384592 |
action_string = apr_psprintf(g_mp, "%s", name);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
else {
|
|
Packit Service |
384592 |
action_string = apr_psprintf(g_mp, "%s:%s", name, param);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
if (action_string == NULL) {
|
|
Packit Service |
384592 |
*errmsg = apr_psprintf(g_mp, "Failed to build action string for action: \"%s\".", name);
|
|
Packit Service |
384592 |
return -1;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if ( apr_filepath_merge(&conf_fn, NULL, "unit-test.conf", APR_FILEPATH_TRUENAME, g_mp) != APR_SUCCESS) {
|
|
Packit Service |
384592 |
*errmsg = apr_psprintf(g_mp, "Failed to build a conf filename.");
|
|
Packit Service |
384592 |
return -1;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* Register UNIT_TEST variable */
|
|
Packit Service |
384592 |
msre_engine_variable_register(modsecurity->msre,
|
|
Packit Service |
384592 |
"UNIT_TEST",
|
|
Packit Service |
384592 |
VAR_SIMPLE,
|
|
Packit Service |
384592 |
0, 0,
|
|
Packit Service |
384592 |
NULL,
|
|
Packit Service |
384592 |
NULL,
|
|
Packit Service |
384592 |
VAR_DONT_CACHE,
|
|
Packit Service |
384592 |
PHASE_REQUEST_HEADERS
|
|
Packit Service |
384592 |
);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* Create a ruleset/rule */
|
|
Packit Service |
384592 |
data->ruleset = msre_ruleset_create(modsecurity->msre, g_mp);
|
|
Packit Service |
384592 |
if (data->ruleset == NULL) {
|
|
Packit Service |
384592 |
*errmsg = apr_psprintf(g_mp, "Failed to create ruleset for action \"%s\".", name);
|
|
Packit Service |
384592 |
return -1;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
data->rule = msre_rule_create(data->ruleset, RULE_TYPE_NORMAL, conf_fn, 1, "UNIT_TEST", "@unconditionalMatch", action_string, errmsg);
|
|
Packit Service |
384592 |
if (data->rule == NULL) {
|
|
Packit Service |
384592 |
*errmsg = apr_psprintf(g_mp, "Failed to create rule for action \"%s\": %s", name, *errmsg);
|
|
Packit Service |
384592 |
return -1;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* Get the actionset/action */
|
|
Packit Service |
384592 |
data->actionset = data->rule->actionset;
|
|
Packit Service |
384592 |
if (data->actionset == NULL) {
|
|
Packit Service |
384592 |
*errmsg = apr_psprintf(g_mp, "Failed to fetch actionset for action \"%s\"", name);
|
|
Packit Service |
384592 |
return -1;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
data->action = (msre_action *)apr_table_get(data->actionset->actions, name);
|
|
Packit Service |
384592 |
if (data->action == NULL) {
|
|
Packit Service |
384592 |
*errmsg = apr_psprintf(g_mp, "Failed to fetch action for action \"%s\"", name);
|
|
Packit Service |
384592 |
return -1;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return 0;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
static int test_action(action_data_t *data, char **errmsg)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
int rc = -1;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
*errmsg = NULL;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* Execute the action */
|
|
Packit Service |
384592 |
if (data->action->metadata->execute != NULL) {
|
|
Packit Service |
384592 |
rc = data->action->metadata->execute(g_msr, g_mp, data->rule, data->action);
|
|
Packit Service |
384592 |
if (rc < 0) {
|
|
Packit Service |
384592 |
*errmsg = apr_psprintf(g_mp, "Failed to execute action \"%s\": %d", data->name, rc);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return rc;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* Initialization */
|
|
Packit Service |
384592 |
static void init_msr(void)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
directory_config *dcfg = NULL;
|
|
Packit Service |
384592 |
request_rec *r = NULL;
|
|
Packit Service |
384592 |
r = (request_rec *)apr_pcalloc(g_mp, sizeof(request_rec));
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
dcfg = (directory_config *)apr_pcalloc(g_mp, sizeof(directory_config));
|
|
Packit Service |
384592 |
dcfg->is_enabled = 0;
|
|
Packit Service |
384592 |
dcfg->reqbody_access = 0;
|
|
Packit Service |
384592 |
dcfg->reqbody_buffering = 0;
|
|
Packit Service |
384592 |
dcfg->reqbody_inmemory_limit = REQUEST_BODY_DEFAULT_INMEMORY_LIMIT;
|
|
Packit Service |
384592 |
dcfg->reqbody_limit = REQUEST_BODY_DEFAULT_LIMIT;
|
|
Packit Service |
384592 |
dcfg->reqbody_no_files_limit = REQUEST_BODY_NO_FILES_DEFAULT_LIMIT;
|
|
Packit Service |
384592 |
dcfg->resbody_access = 0;
|
|
Packit Service |
384592 |
dcfg->of_limit = RESPONSE_BODY_DEFAULT_LIMIT;
|
|
Packit Service |
384592 |
dcfg->of_limit_action = RESPONSE_BODY_LIMIT_ACTION_REJECT;
|
|
Packit Service |
384592 |
dcfg->debuglog_fd = NOT_SET_P;
|
|
Packit Service |
384592 |
dcfg->debuglog_name = "msc-test-debug.log";
|
|
Packit Service |
384592 |
dcfg->debuglog_level = debuglog_level;
|
|
Packit Service |
384592 |
dcfg->cookie_format = 0;
|
|
Packit Service |
384592 |
dcfg->argument_separator = '&';
|
|
Packit Service |
384592 |
dcfg->rule_inheritance = 0;
|
|
Packit Service |
384592 |
dcfg->auditlog_flag = 0;
|
|
Packit Service |
384592 |
dcfg->auditlog_type = AUDITLOG_SERIAL;
|
|
Packit Service |
384592 |
dcfg->auditlog_fd = NULL;
|
|
Packit Service |
384592 |
dcfg->auditlog2_fd = NULL;
|
|
Packit Service |
384592 |
dcfg->auditlog_name = NULL;
|
|
Packit Service |
384592 |
dcfg->auditlog2_name = NULL;
|
|
Packit Service |
384592 |
dcfg->auditlog_storage_dir = NULL;
|
|
Packit Service |
384592 |
dcfg->auditlog_parts = "ABCFHZ";
|
|
Packit Service |
384592 |
dcfg->auditlog_relevant_regex = NULL;
|
|
Packit Service |
384592 |
dcfg->tmp_dir = guess_tmp_dir(g_mp);
|
|
Packit Service |
384592 |
dcfg->upload_dir = NULL;
|
|
Packit Service |
384592 |
dcfg->upload_keep_files = KEEP_FILES_OFF;
|
|
Packit Service |
384592 |
dcfg->upload_validates_files = 0;
|
|
Packit Service |
384592 |
dcfg->data_dir = ".";
|
|
Packit Service |
384592 |
dcfg->webappid = "default";
|
|
Packit Service |
384592 |
dcfg->content_injection_enabled = 0;
|
|
Packit Service |
384592 |
dcfg->geo = NULL;
|
|
Packit Service |
384592 |
dcfg->cache_trans = MODSEC_CACHE_ENABLED;
|
|
Packit Service |
384592 |
dcfg->cache_trans_min = 15;
|
|
Packit Service |
384592 |
dcfg->cache_trans_max = 0;
|
|
Packit Service |
384592 |
dcfg->request_encoding = NULL;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
g_msr = (modsec_rec *)apr_pcalloc(g_mp, sizeof(modsec_rec));
|
|
Packit Service |
384592 |
g_msr->modsecurity = modsecurity;
|
|
Packit Service |
384592 |
g_msr->mp = g_mp;
|
|
Packit Service |
384592 |
g_msr->r = r;
|
|
Packit Service |
384592 |
g_msr->r_early = r;
|
|
Packit Service |
384592 |
g_msr->request_time = apr_time_now();
|
|
Packit Service |
384592 |
g_msr->dcfg1 = NULL;
|
|
Packit Service |
384592 |
g_msr->usercfg = NULL;
|
|
Packit Service |
384592 |
g_msr->txcfg = dcfg;
|
|
Packit Service |
384592 |
g_msr->txid = "FAKE-TXID";
|
|
Packit Service |
384592 |
g_msr->error_messages = NULL;
|
|
Packit Service |
384592 |
g_msr->alerts = NULL;
|
|
Packit Service |
384592 |
g_msr->server_software = "FAKE-SERVER-SOFTWARE";
|
|
Packit Service |
384592 |
g_msr->local_addr = "127.0.0.1";
|
|
Packit Service |
384592 |
g_msr->local_port = 80;
|
|
Packit Service |
384592 |
g_msr->remote_addr = "127.0.0.1";
|
|
Packit Service |
384592 |
g_msr->remote_port = 1080;
|
|
Packit Service |
384592 |
g_msr->request_line = "GET /unit-tests HTTP/1.1";
|
|
Packit Service |
384592 |
g_msr->request_uri = "http://localhost/unit-tests";
|
|
Packit Service |
384592 |
g_msr->request_method = "GET";
|
|
Packit Service |
384592 |
g_msr->query_string = "";
|
|
Packit Service |
384592 |
g_msr->request_protocol = "HTTP/1.1";
|
|
Packit Service |
384592 |
g_msr->request_headers = NULL;
|
|
Packit Service |
384592 |
g_msr->hostname = "localhost";
|
|
Packit Service |
384592 |
g_msr->msc_rule_mptmp = g_mp;
|
|
Packit Service |
384592 |
g_msr->tx_vars = apr_table_make(g_mp, 1);
|
|
Packit Service |
384592 |
g_msr->collections_original = apr_table_make(g_mp, 1);
|
|
Packit Service |
384592 |
g_msr->collections = apr_table_make(g_mp, 1);
|
|
Packit Service |
384592 |
g_msr->collections_dirty = apr_table_make(g_mp, 1);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/**
|
|
Packit Service |
384592 |
* Usage text.
|
|
Packit Service |
384592 |
*/
|
|
Packit Service |
384592 |
static void usage(void)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
fprintf(stderr, "ModSecurity Unit Tester v%s\n", MODSEC_VERSION);
|
|
Packit Service |
384592 |
fprintf(stderr, " Usage: msc_test [options]\n");
|
|
Packit Service |
384592 |
fprintf(stderr, "\n");
|
|
Packit Service |
384592 |
fprintf(stderr, " Options:\n");
|
|
Packit Service |
384592 |
fprintf(stderr, " -t Type (required)\n");
|
|
Packit Service |
384592 |
fprintf(stderr, " -n Name (required)\n");
|
|
Packit Service |
384592 |
fprintf(stderr, " -p Parameter (required)\n");
|
|
Packit Service |
384592 |
fprintf(stderr, " -P Prerun (optional for actions)\n");
|
|
Packit Service |
384592 |
fprintf(stderr, " -r Function return code (required for some types)\n");
|
|
Packit Service |
384592 |
fprintf(stderr, " -I Iterations (default 1)\n");
|
|
Packit Service |
384592 |
fprintf(stderr, " -D Debug log level (default 0)\n");
|
|
Packit Service |
384592 |
fprintf(stderr, " -N No input on stdin.\n\n");
|
|
Packit Service |
384592 |
fprintf(stderr, " -h This help\n\n");
|
|
Packit Service |
384592 |
fprintf(stderr, "\n");
|
|
Packit Service |
384592 |
fprintf(stderr, "Input is from stdin unless -N is used.\n");
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* Main */
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
int main(int argc, const char * const argv[])
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
apr_getopt_t *opt;
|
|
Packit Service |
384592 |
apr_file_t *fd;
|
|
Packit Service |
384592 |
apr_size_t nbytes = 0;
|
|
Packit Service |
384592 |
const char *type = NULL;
|
|
Packit Service |
384592 |
const char *name = NULL;
|
|
Packit Service |
384592 |
unsigned char *param = NULL;
|
|
Packit Service |
384592 |
unsigned char *prerun = NULL;
|
|
Packit Service |
384592 |
const char *returnval = NULL;
|
|
Packit Service |
384592 |
int iterations = 1;
|
|
Packit Service |
384592 |
char *errmsg = NULL;
|
|
Packit Service |
384592 |
unsigned char *out = NULL;
|
|
Packit Service |
384592 |
apr_size_t param_len = 0;
|
|
Packit Service |
384592 |
apr_size_t prerun_len = 0;
|
|
Packit Service |
384592 |
apr_size_t out_len = 0;
|
|
Packit Service |
384592 |
int noinput = 0;
|
|
Packit Service |
384592 |
int rc = 0;
|
|
Packit Service |
384592 |
int result = 0;
|
|
Packit Service |
384592 |
int ec = 0;
|
|
Packit Service |
384592 |
int i;
|
|
Packit Service |
384592 |
apr_time_t T0 = 0;
|
|
Packit Service |
384592 |
apr_time_t T1 = 0;
|
|
Packit Service |
384592 |
tfn_data_t tfn_data;
|
|
Packit Service |
384592 |
op_data_t op_data;
|
|
Packit Service |
384592 |
action_data_t action_data;
|
|
Packit Service |
384592 |
int ret = 0;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
memset(&tfn_data, 0, sizeof(tfn_data_t));
|
|
Packit Service |
384592 |
memset(&op_data, 0, sizeof(op_data_t));
|
|
Packit Service |
384592 |
memset(&action_data, 0, sizeof(action_data_t));
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
apr_app_initialize(&argc, &argv, NULL);
|
|
Packit Service |
384592 |
atexit(apr_terminate);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
apr_pool_create(&g_mp, NULL);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
rc = apr_getopt_init(&opt, g_mp, argc, argv);
|
|
Packit Service |
384592 |
if (rc != APR_SUCCESS) {
|
|
Packit Service |
384592 |
fprintf(stderr, "Failed to initialize.\n\n");
|
|
Packit Service |
384592 |
usage();
|
|
Packit Service |
384592 |
exit(1);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
do {
|
|
Packit Service |
384592 |
char ch;
|
|
Packit Service |
384592 |
const char *val;
|
|
Packit Service |
384592 |
rc = apr_getopt(opt, CMDLINE_OPTS, &ch, &val;;
|
|
Packit Service |
384592 |
switch (rc) {
|
|
Packit Service |
384592 |
case APR_SUCCESS:
|
|
Packit Service |
384592 |
switch (ch) {
|
|
Packit Service |
384592 |
case 't':
|
|
Packit Service |
384592 |
type = val;
|
|
Packit Service |
384592 |
break;
|
|
Packit Service |
384592 |
case 'n':
|
|
Packit Service |
384592 |
name = val;
|
|
Packit Service |
384592 |
break;
|
|
Packit Service |
384592 |
case 'p':
|
|
Packit Service |
384592 |
param_len = strlen(val);
|
|
Packit Service |
384592 |
param = apr_pmemdup(g_mp, val, param_len + 1);
|
|
Packit Service |
384592 |
unescape_inplace(param, ¶m_len);
|
|
Packit Service |
384592 |
break;
|
|
Packit Service |
384592 |
case 'P':
|
|
Packit Service |
384592 |
prerun_len = strlen(val);
|
|
Packit Service |
384592 |
prerun = apr_pmemdup(g_mp, val, prerun_len + 1);
|
|
Packit Service |
384592 |
unescape_inplace(prerun, &prerun_len);
|
|
Packit Service |
384592 |
break;
|
|
Packit Service |
384592 |
case 'r':
|
|
Packit Service |
384592 |
returnval = val;
|
|
Packit Service |
384592 |
break;
|
|
Packit Service |
384592 |
case 'I':
|
|
Packit Service |
384592 |
iterations = atoi(val);
|
|
Packit Service |
384592 |
break;
|
|
Packit Service |
384592 |
case 'D':
|
|
Packit Service |
384592 |
debuglog_level = atoi(val);
|
|
Packit Service |
384592 |
break;
|
|
Packit Service |
384592 |
case 'N':
|
|
Packit Service |
384592 |
noinput = 1;
|
|
Packit Service |
384592 |
break;
|
|
Packit Service |
384592 |
case 'h':
|
|
Packit Service |
384592 |
usage();
|
|
Packit Service |
384592 |
exit(0);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
break;
|
|
Packit Service |
384592 |
case APR_BADCH:
|
|
Packit Service |
384592 |
case APR_BADARG:
|
|
Packit Service |
384592 |
usage();
|
|
Packit Service |
384592 |
exit(1);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
} while (rc != APR_EOF);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
rc = apr_getopt_init(&opt, g_mp, argc, argv);
|
|
Packit Service |
384592 |
if (!type || !name || !param) {
|
|
Packit Service |
384592 |
usage();
|
|
Packit Service |
384592 |
exit(1);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
modsecurity = modsecurity_create(g_mp, MODSEC_OFFLINE);
|
|
Packit Service |
384592 |
test_name = apr_psprintf(g_mp, "%s/%s", type, name);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (noinput == 0) {
|
|
Packit Service |
384592 |
if (apr_file_open_stdin(&fd, g_mp) != APR_SUCCESS) {
|
|
Packit Service |
384592 |
fprintf(stderr, "Failed to open stdin\n");
|
|
Packit Service |
384592 |
exit(1);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* Read in the input */
|
|
Packit Service |
384592 |
nbytes = BUFLEN;
|
|
Packit Service |
384592 |
memset(buf, 0, nbytes);
|
|
Packit Service |
384592 |
rc = apr_file_read(fd, buf, &nbytes);
|
|
Packit Service |
384592 |
if ((rc != APR_EOF) && (rc != APR_SUCCESS)) {
|
|
Packit Service |
384592 |
fprintf(stderr, "Failed to read data\n");
|
|
Packit Service |
384592 |
exit(1);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (nbytes < 0) {
|
|
Packit Service |
384592 |
fprintf(stderr, "Error reading data\n");
|
|
Packit Service |
384592 |
exit(1);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
apr_file_close(fd);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (strcmp("tfn", type) == 0) {
|
|
Packit Service |
384592 |
ret = returnval ? atoi(returnval) : -8888;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
rc = init_tfn(&tfn_data, name, buf, nbytes, &errmsg);
|
|
Packit Service |
384592 |
if (rc < 0) {
|
|
Packit Service |
384592 |
fprintf(stderr, "ERROR: %s\n", errmsg);
|
|
Packit Service |
384592 |
result = RESULT_ERROR;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
else if (strcmp("op", type) == 0) {
|
|
Packit Service |
384592 |
if (!returnval) {
|
|
Packit Service |
384592 |
fprintf(stderr, "Return value required for type \"%s\"\n", type);
|
|
Packit Service |
384592 |
exit(1);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
ret = atoi(returnval);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
init_msr();
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
rc = init_op(&op_data, name, (const char *)param, buf, nbytes, &errmsg);
|
|
Packit Service |
384592 |
if (rc < 0) {
|
|
Packit Service |
384592 |
fprintf(stderr, "ERROR: %s\n", errmsg);
|
|
Packit Service |
384592 |
result = RESULT_ERROR;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
else if (strcmp("action", type) == 0) {
|
|
Packit Service |
384592 |
if (!returnval) {
|
|
Packit Service |
384592 |
fprintf(stderr, "Return value required for type \"%s\"\n", type);
|
|
Packit Service |
384592 |
exit(1);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
ret = atoi(returnval);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
init_msr();
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (prerun) {
|
|
Packit Service |
384592 |
action_data_t paction_data;
|
|
Packit Service |
384592 |
char *pname = apr_pstrdup(g_mp, (const char *)prerun);
|
|
Packit Service |
384592 |
char *pparam = NULL;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if ((pparam = strchr((const char *)pname, ':'))) {
|
|
Packit Service |
384592 |
pparam[0] = '\0';
|
|
Packit Service |
384592 |
pparam++;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
rc = init_action(&paction_data, pname, (const char *)pparam, &errmsg);
|
|
Packit Service |
384592 |
if (rc < 0) {
|
|
Packit Service |
384592 |
fprintf(stderr, "ERROR: prerun - %s\n", errmsg);
|
|
Packit Service |
384592 |
exit(1);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
rc = test_action(&paction_data, &errmsg);
|
|
Packit Service |
384592 |
if (rc < 0) {
|
|
Packit Service |
384592 |
fprintf(stderr, "ERROR: prerun - %s\n", errmsg);
|
|
Packit Service |
384592 |
exit(1);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
rc = init_action(&action_data, name, (const char *)param, &errmsg);
|
|
Packit Service |
384592 |
if (rc < 0) {
|
|
Packit Service |
384592 |
fprintf(stderr, "ERROR: %s\n", errmsg);
|
|
Packit Service |
384592 |
result = RESULT_ERROR;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (iterations > 1) {
|
|
Packit Service |
384592 |
apr_time_clock_hires (g_mp);
|
|
Packit Service |
384592 |
T0 = apr_time_now();
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
for (i = 1; i <= iterations; i++) {
|
|
Packit Service |
384592 |
#ifdef VERBOSE
|
|
Packit Service |
384592 |
if (i % 100 == 0) {
|
|
Packit Service |
384592 |
if (i == 100) {
|
|
Packit Service |
384592 |
fprintf(stderr, "Iterations/100: .");
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
else {
|
|
Packit Service |
384592 |
fprintf(stderr, ".");
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
#endif
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (strcmp("tfn", type) == 0) {
|
|
Packit Service |
384592 |
/* Transformations */
|
|
Packit Service |
384592 |
rc = test_tfn(&tfn_data, &out, &out_len, &errmsg);
|
|
Packit Service |
384592 |
if (rc < 0) {
|
|
Packit Service |
384592 |
fprintf(stderr, "ERROR: %s\n", errmsg);
|
|
Packit Service |
384592 |
result = RESULT_ERROR;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
else if ((ret != -8888) && (rc != ret)) {
|
|
Packit Service |
384592 |
fprintf(stderr, "Returned %d (expected %d)\n", rc, ret);
|
|
Packit Service |
384592 |
result = RESULT_WRONGRET;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
else if (param_len != out_len) {
|
|
Packit Service |
384592 |
fprintf(stderr, "Length %" APR_SIZE_T_FMT " (expected %" APR_SIZE_T_FMT ")\n", out_len, param_len);
|
|
Packit Service |
384592 |
result = RESULT_WRONGSIZE;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
else {
|
|
Packit Service |
384592 |
result = memcmp(param, out, param_len) ? RESULT_MISMATCHED : RESULT_SUCCESS;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (result != RESULT_SUCCESS) {
|
|
Packit Service |
384592 |
apr_size_t s0len = nbytes;
|
|
Packit Service |
384592 |
const char *s0 = escape(buf, &s0len);
|
|
Packit Service |
384592 |
apr_size_t s1len = out_len;
|
|
Packit Service |
384592 |
const char *s1 = escape(out, &s1len);
|
|
Packit Service |
384592 |
apr_size_t s2len = param_len;
|
|
Packit Service |
384592 |
const char *s2 = escape(param, &s2len);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
fprintf(stderr, " Input: '%s' len=%" APR_SIZE_T_FMT "\n"
|
|
Packit Service |
384592 |
"Output: '%s' len=%" APR_SIZE_T_FMT "\n"
|
|
Packit Service |
384592 |
"Expect: '%s' len=%" APR_SIZE_T_FMT "\n",
|
|
Packit Service |
384592 |
s0, nbytes, s1, out_len, s2, param_len);
|
|
Packit Service |
384592 |
ec = 1;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
else if (strcmp("op", type) == 0) {
|
|
Packit Service |
384592 |
/* Operators */
|
|
Packit Service |
384592 |
rc = test_op(&op_data, &errmsg);
|
|
Packit Service |
384592 |
if (rc < 0) {
|
|
Packit Service |
384592 |
fprintf(stderr, "ERROR: %s\n", errmsg);
|
|
Packit Service |
384592 |
result = RESULT_ERROR;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
else if (rc != ret) {
|
|
Packit Service |
384592 |
fprintf(stderr, "Returned %d (expected %d)\n", rc, ret);
|
|
Packit Service |
384592 |
result = RESULT_WRONGRET;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
else {
|
|
Packit Service |
384592 |
result = RESULT_SUCCESS;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (result != RESULT_SUCCESS) {
|
|
Packit Service |
384592 |
apr_size_t s0len = nbytes;
|
|
Packit Service |
384592 |
const char *s0 = escape(buf, &s0len);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
fprintf(stderr, " Test: '@%s %s'\n"
|
|
Packit Service |
384592 |
"Input: '%s' len=%" APR_SIZE_T_FMT "\n",
|
|
Packit Service |
384592 |
name, param, s0, nbytes);
|
|
Packit Service |
384592 |
ec = 1;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
else if (strcmp("action", type) == 0) {
|
|
Packit Service |
384592 |
/* Actions */
|
|
Packit Service |
384592 |
int n;
|
|
Packit Service |
384592 |
const apr_array_header_t *arr;
|
|
Packit Service |
384592 |
apr_table_entry_t *te;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
rc = test_action(&action_data, &errmsg);
|
|
Packit Service |
384592 |
if (rc < 0) {
|
|
Packit Service |
384592 |
fprintf(stderr, "ERROR: %s\n", errmsg);
|
|
Packit Service |
384592 |
result = RESULT_ERROR;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
else if (rc != ret) {
|
|
Packit Service |
384592 |
fprintf(stderr, "Returned %d (expected %d)\n", rc, ret);
|
|
Packit Service |
384592 |
result = RESULT_WRONGRET;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
else {
|
|
Packit Service |
384592 |
result = RESULT_SUCCESS;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (result != RESULT_SUCCESS) {
|
|
Packit Service |
384592 |
fprintf(stderr, " Test: '%s:%s'\n"
|
|
Packit Service |
384592 |
"Prerun: '%s'\n",
|
|
Packit Service |
384592 |
name, param, (prerun ? (const char *)prerun : ""));
|
|
Packit Service |
384592 |
ec = 1;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* Store any collections that were initialized and changed */
|
|
Packit Service |
384592 |
arr = apr_table_elts(g_msr->collections);
|
|
Packit Service |
384592 |
te = (apr_table_entry_t *)arr->elts;
|
|
Packit Service |
384592 |
for (n = 0; n < arr->nelts; n++) {
|
|
Packit Service |
384592 |
apr_table_t *col = (apr_table_t *)te[n].val;
|
|
Packit Service |
384592 |
// apr_table_t *orig_col = NULL;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (g_msr->txcfg->debuglog_level >= 9) {
|
|
Packit Service |
384592 |
msr_log(g_msr, 9, "Found loaded collection: %s", te[n].key);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
/* Only store those collections that changed. */
|
|
Packit Service |
384592 |
if (apr_table_get(g_msr->collections_dirty, te[n].key)) {
|
|
Packit Service |
384592 |
int x = collection_store(g_msr, col);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (g_msr->txcfg->debuglog_level >= 9) {
|
|
Packit Service |
384592 |
msr_log(g_msr, 9, "Stored collection: %s (%d)", te[n].key, x);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
#if 0
|
|
Packit Service |
384592 |
/* Re-populate the original values with the new ones. */
|
|
Packit Service |
384592 |
if ((orig_col = (apr_table_t *)apr_table_get(g_msr->collections_original, te[n].key)) != NULL) {
|
|
Packit Service |
384592 |
const apr_array_header_t *orig_arr = apr_table_elts(orig_col);
|
|
Packit Service |
384592 |
apr_table_entry_t *orig_te = (apr_table_entry_t *)orig_arr->elts;
|
|
Packit Service |
384592 |
int m;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
for (m = 0; m < orig_arr->nelts; m++) {
|
|
Packit Service |
384592 |
msc_string *mstr = (msc_string *)apr_table_get(col, orig_te[m].key);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (g_msr->txcfg->debuglog_level >= 9) {
|
|
Packit Service |
384592 |
msr_log(g_msr, 9, "Updating original collection: %s.%s=%s", te[n].key, mstr->name, mstr->value);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
//apr_table_setn(orig_col, orig_te[m].key, (void *)mstr );
|
|
Packit Service |
384592 |
collection_original_setvar(g_msr, te[n].key, mstr);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
#endif
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
apr_table_clear(g_msr->collections_dirty);
|
|
Packit Service |
384592 |
apr_table_clear(g_msr->collections_original);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
else {
|
|
Packit Service |
384592 |
fprintf(stderr, "Unknown type: \"%s\"\n", type);
|
|
Packit Service |
384592 |
exit(1);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (ec != 0) {
|
|
Packit Service |
384592 |
fprintf(stdout, "%s\n", errmsg ? errmsg : "");
|
|
Packit Service |
384592 |
return ec;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (iterations > 1) {
|
|
Packit Service |
384592 |
double dT;
|
|
Packit Service |
384592 |
T1 = apr_time_now();
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
dT = apr_time_as_msec(T1 - T0);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
#ifdef VERBOSE
|
|
Packit Service |
384592 |
if (i >= 100) {
|
|
Packit Service |
384592 |
fprintf(stderr, "\n");
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
#endif
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
fprintf(stdout, "%d @ %.4f msec per iteration.\n", iterations, dT / iterations);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
fprintf(stdout, "%s\n", errmsg ? errmsg : "");
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return ec;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
|