~ubuntu-branches/ubuntu/quantal/modsecurity-apache/quantal

« back to all changes in this revision

Viewing changes to apache2/api/mod_op_strstr.c

  • Committer: Bazaar Package Importer
  • Author(s): Alberto Gonzalez Iniesta
  • Date: 2011-03-23 18:36:29 UTC
  • Revision ID: james.westby@ubuntu.com-20110323183629-8rwn0362sqqqqbgl
Tags: upstream-2.5.13
ImportĀ upstreamĀ versionĀ 2.5.13

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
#include "httpd.h"
 
3
#include "http_core.h"
 
4
#include "http_config.h"
 
5
#include "http_log.h"
 
6
#include "http_protocol.h"
 
7
#include "ap_config.h"
 
8
#include "apr_optional.h"
 
9
 
 
10
#include "modsecurity.h"
 
11
 
 
12
#define ALPHABET_SIZE       256
 
13
#define MAX_PATTERN_SIZE    64
 
14
 
 
15
static void initBoyerMooreHorspool(const char *pattern, int patlength,
 
16
    int *bm_badcharacter_array);
 
17
 
 
18
static int BoyerMooreHorspool(const char *pattern, int patlength,
 
19
    const char *text, int textlen, int *bm_badcharacter_array);
 
20
 
 
21
/**
 
22
 * Operator parameter initialisation entry point.
 
23
 */
 
24
static int op_strstr_init(msre_rule *rule, char **error_msg) {
 
25
    /* Operator initialisation function will be called once per
 
26
     * statement where operator is used. It is meant to be used
 
27
     * to check the parameters to see whether they are present
 
28
     * and if they are in the correct format.
 
29
     */
 
30
 
 
31
    /* In this example we just look for a simple non-empty parameter. */
 
32
    if ((rule->op_param == NULL)||(strlen(rule->op_param) == 0)) {
 
33
        *error_msg = apr_psprintf(rule->ruleset->mp, "Missing parameter for operator 'strstr'.");
 
34
        return 0; /* ERROR */
 
35
    }
 
36
 
 
37
    /* If you need to transform the data in the parameter into something
 
38
     * else you should do that here. Simply create a new structure to hold
 
39
     * the transformed data and place the pointer to it into rule->op_param_data.
 
40
     * You will have access to this pointer later on.
 
41
     */
 
42
    rule->op_param_data = apr_pcalloc(rule->ruleset->mp, ALPHABET_SIZE * sizeof(int));
 
43
    initBoyerMooreHorspool(rule->op_param, strlen(rule->op_param), (int *)rule->op_param_data);
 
44
 
 
45
    /* OK */
 
46
    return 1;
 
47
}
 
48
 
 
49
/**
 
50
 * Operator execution entry point.
 
51
 */
 
52
static int op_strstr_exec(modsec_rec *msr, msre_rule *rule, msre_var *var, char **error_msg) {
 
53
    /* Here we need to inspect the contents of the supplied variable. */
 
54
 
 
55
    /* In a general case it is possible for the value
 
56
     * to be NULL. What you need to do in this case
 
57
     * depends on your operator. In this example we return
 
58
     * a "no match" response.
 
59
     */
 
60
    if (var->value == NULL) return 0; /* No match. */
 
61
 
 
62
    /* Another thing to note is that variables are not C strings,
 
63
     * meaning the NULL byte is not used to determine the end
 
64
     * of the string. Variable length var->value_len should be
 
65
     * used for this purpose.
 
66
     */
 
67
 
 
68
    if (BoyerMooreHorspool(rule->op_param, strlen(rule->op_param),
 
69
        var->value, var->value_len, (int *)rule->op_param_data) >= 0)
 
70
    {
 
71
        return 1; /* Match. */
 
72
    }
 
73
    
 
74
    return 0; /* No match. */
 
75
}
 
76
 
 
77
static int hook_pre_config(apr_pool_t *mp, apr_pool_t *mp_log, apr_pool_t *mp_temp) {
 
78
    void (*fn)(const char *name, void *fn_init, void *fn_exec);
 
79
 
 
80
    /* Look for the registration function
 
81
     * exported by ModSecurity.
 
82
     */
 
83
    fn = APR_RETRIEVE_OPTIONAL_FN(modsec_register_operator);
 
84
    if (fn) {
 
85
        /* Use it to register our new
 
86
         * transformation function under the
 
87
         * name "reverse".
 
88
         */
 
89
        fn("strstr", (void *)op_strstr_init, (void *)op_strstr_exec);
 
90
    }
 
91
 
 
92
    return OK;
 
93
}
 
94
 
 
95
static void register_hooks(apr_pool_t *p) {
 
96
    ap_hook_pre_config(hook_pre_config, NULL, NULL, APR_HOOK_LAST);
 
97
}
 
98
 
 
99
/* Dispatch list for API hooks */
 
100
module AP_MODULE_DECLARE_DATA op_strstr_module = {
 
101
    STANDARD20_MODULE_STUFF, 
 
102
    NULL,                  /* create per-dir    config structures */
 
103
    NULL,                  /* merge  per-dir    config structures */
 
104
    NULL,                  /* create per-server config structures */
 
105
    NULL,                  /* merge  per-server config structures */
 
106
    NULL,                  /* table of config file commands       */
 
107
    register_hooks         /* register hooks                      */
 
108
};
 
109
 
 
110
/*
 
111
 
 
112
This example uses an implementation Boyer-Moore-Horspool
 
113
matching algorithm as implemented in Streamline (http://ffpf.sourceforge.net).
 
114
 
 
115
Copyright (c) 2004-2006, Vrije Universiteit Amsterdam
 
116
All rights reserved.
 
117
 
 
118
Redistribution and use in source and binary forms, with or without modification, 
 
119
are permitted provided that the following conditions are met:
 
120
 
 
121
Redistributions of source code must retain the above copyright notice, 
 
122
this list of conditions and the following disclaimer.
 
123
 
 
124
Redistributions in binary form must reproduce the above copyright notice, 
 
125
this list of conditions and the following disclaimer in the documentation 
 
126
and/or other materials provided with the distribution.
 
127
 
 
128
Neither the name of the Vrije Universiteit nor the names of its contributors 
 
129
may be used to endorse or promote products derived from this software without 
 
130
specific prior written permission.
 
131
 
 
132
*/
 
133
 
 
134
static void precompute_badcharacter(const char *pattern, int patlength,
 
135
    int bm_badcharacter_array[])
 
136
{
 
137
    int i;
 
138
 
 
139
    for (i = 0; i < ALPHABET_SIZE; ++i) {
 
140
        bm_badcharacter_array[i] = patlength;
 
141
    }
 
142
 
 
143
    for (i = 0; i < patlength - 1; ++i){
 
144
        bm_badcharacter_array[(uint8_t)pattern[i]] = patlength - i - 1;
 
145
        }
 
146
}
 
147
 
 
148
static void initBoyerMooreHorspool(const char *pattern, int patlength,
 
149
    int *bm_badcharacter_array)
 
150
{
 
151
    precompute_badcharacter(pattern,
 
152
        (patlength < MAX_PATTERN_SIZE ? patlength : MAX_PATTERN_SIZE), bm_badcharacter_array);
 
153
}
 
154
 
 
155
static int BoyerMooreHorspool(const char *pattern, int patlength,
 
156
    const char *text, int textlen, int *bm_badcharacter_array)
 
157
{
 
158
    int j;
 
159
    char c;
 
160
 
 
161
    j = 0;
 
162
    while (j <= textlen - patlength) {
 
163
        c = text[j + patlength - 1];
 
164
        if (pattern[patlength - 1] == c && memcmp(pattern, text + j, patlength - 1) == 0) {
 
165
            return j;
 
166
        }
 
167
        j += bm_badcharacter_array[(uint8_t)c];
 
168
    }
 
169
 
 
170
    return -1;
 
171
}