2 * ModSecurity for Apache 2.x, http://www.modsecurity.org/
3 * Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
5 * This product is released under the terms of the General Public Licence,
6 * version 2 (GPLv2). Please refer to the file LICENSE (included with this
7 * distribution) which contains the complete text of the licence.
9 * There are special exceptions to the terms and conditions of the GPL
10 * as it is applied to this software. View the full text of the exception in
11 * file MODSECURITY_LICENSING_EXCEPTION in the directory of this software
14 * If any of the files related to licensing are missing or if you have any
15 * other questions related to licensing please contact Breach Security, Inc.
16 * directly using the email address support@breach.com.
19 #ifndef _MODSECURITY_H_
20 #define _MODSECURITY_H_
26 typedef struct rule_exception rule_exception;
27 typedef struct modsec_rec modsec_rec;
28 typedef struct directory_config directory_config;
29 typedef struct error_message error_message;
30 typedef struct msc_engine msc_engine;
31 typedef struct msc_data_chunk msc_data_chunk;
32 typedef struct msc_arg msc_arg;
33 typedef struct msc_string msc_string;
35 #include "msc_release.h"
36 #include "msc_logging.h"
37 #include "msc_multipart.h"
44 #include "ap_config.h"
46 #include "apr_strings.h"
49 #include "http_config.h"
51 #include "http_protocol.h"
53 #define PHASE_REQUEST_HEADERS 1
54 #define PHASE_REQUEST_BODY 2
55 #define PHASE_RESPONSE_HEADERS 3
56 #define PHASE_RESPONSE_BODY 4
57 #define PHASE_LOGGING 5
58 #define PHASE_FIRST PHASE_REQUEST_HEADERS
59 #define PHASE_LAST PHASE_LOGGING
62 #define NOT_SET_P ((void *)-1l)
64 #define CREATEMODE ( APR_UREAD | APR_UWRITE | APR_GREAD )
65 #define CREATEMODE_DIR ( APR_UREAD | APR_UWRITE | APR_UEXECUTE | APR_GREAD | APR_GEXECUTE )
68 #define CREATEMODE_UNISTD ( S_IREAD | S_IWRITE )
70 #define CREATEMODE_UNISTD ( _S_IREAD | _S_IWRITE )
72 #define CREATEMODE_UNISTD ( S_IRUSR | S_IWUSR | S_IRGRP )
75 #if !defined(O_BINARY)
80 #define PIPE_BUF (512)
83 #define REQUEST_BODY_HARD_LIMIT 1073741824L
84 #define REQUEST_BODY_DEFAULT_INMEMORY_LIMIT 131072
85 #define REQUEST_BODY_DEFAULT_LIMIT 134217728
86 #define REQUEST_BODY_NO_FILES_DEFAULT_LIMIT 1048576
87 #define RESPONSE_BODY_DEFAULT_LIMIT 524288
88 #define RESPONSE_BODY_HARD_LIMIT 1073741824L
90 #define RESPONSE_BODY_LIMIT_ACTION_REJECT 0
91 #define RESPONSE_BODY_LIMIT_ACTION_PARTIAL 1
93 #define REQUEST_BODY_FORCEBUF_OFF 0
94 #define REQUEST_BODY_FORCEBUF_ON 1
96 #define SECACTION_TARGETS "REQUEST_URI"
97 #define SECACTION_ARGS "@unconditionalMatch"
99 #define SECMARKER_TARGETS "REQUEST_URI"
100 #define SECMARKER_ARGS "@noMatch"
101 #define SECMARKER_BASE_ACTIONS "t:none,pass,id:"
103 #if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE)
105 #define __SET_MUTEX_PERMS
114 #include <sys/types.h>
118 #define NOTE_MSR "modsecurity-tx-context"
120 #define FATAL_ERROR "ModSecurity: Fatal error (memory allocation or unexpected internal error)!"
122 extern DSOLOCAL char *new_server_signature;
123 extern DSOLOCAL char *real_server_signature;
124 extern DSOLOCAL char *chroot_dir;
126 extern module AP_MODULE_DECLARE_DATA security2_module;
128 extern DSOLOCAL const command_rec module_directives[];
130 #define RESBODY_STATUS_NOT_READ 0 /* we were not configured to read the body */
131 #define RESBODY_STATUS_ERROR 1 /* error occured while we were reading the body */
132 #define RESBODY_STATUS_PARTIAL 2 /* partial body content available in the brigade */
133 #define RESBODY_STATUS_READ_BRIGADE 3 /* body was read but not flattened */
134 #define RESBODY_STATUS_READ 4 /* body was read and flattened */
136 #define IF_STATUS_NONE 0
137 #define IF_STATUS_WANTS_TO_RUN 1
138 #define IF_STATUS_COMPLETE 2
140 #define OF_STATUS_NOT_STARTED 0
141 #define OF_STATUS_IN_PROGRESS 1
142 #define OF_STATUS_COMPLETE 2
144 #define MSC_REQBODY_NONE 0
145 #define MSC_REQBODY_MEMORY 1
146 #define MSC_REQBODY_DISK 2
148 #define ACTION_NONE 0
149 #define ACTION_DENY 1
150 #define ACTION_REDIRECT 2
151 #define ACTION_PROXY 3
152 #define ACTION_DROP 4
153 #define ACTION_ALLOW 5
154 #define ACTION_ALLOW_REQUEST 6
155 #define ACTION_ALLOW_PHASE 7
157 #define MODSEC_DISABLED 0
158 #define MODSEC_DETECTION_ONLY 1
159 #define MODSEC_ENABLED 2
161 #define MODSEC_CACHE_DISABLED 0
162 #define MODSEC_CACHE_ENABLED 1
164 #define MODSEC_OFFLINE 0
165 #define MODSEC_ONLINE 1
167 #define REGEX_CAPTURE_BUFLEN 1024
169 #define KEEP_FILES_OFF 0
170 #define KEEP_FILES_ON 1
171 #define KEEP_FILES_RELEVANT_ONLY 2
173 #define RULE_EXCEPTION_IMPORT_ID 1
174 #define RULE_EXCEPTION_IMPORT_MSG 2
175 #define RULE_EXCEPTION_REMOVE_ID 3
176 #define RULE_EXCEPTION_REMOVE_MSG 4
180 struct rule_exception {
188 msc_engine *modsecurity;
190 request_rec *r_early;
192 directory_config *dcfg1;
193 directory_config *dcfg2;
194 directory_config *usercfg;
195 directory_config *txcfg;
197 unsigned int reqbody_should_exist;
198 unsigned int reqbody_chunked;
201 unsigned int phase_request_headers_complete;
202 unsigned int phase_request_body_complete;
204 apr_bucket_brigade *if_brigade;
205 unsigned int if_status;
206 unsigned int if_started_forwarding;
208 apr_size_t reqbody_length;
210 apr_bucket_brigade *of_brigade;
211 unsigned int of_status;
212 unsigned int of_done_reading;
213 unsigned int of_skipping;
214 unsigned int of_partial;
215 unsigned int of_is_error;
217 unsigned int resbody_status;
218 apr_size_t resbody_length;
220 unsigned int resbody_contains_html;
222 apr_array_header_t *error_messages;
223 apr_array_header_t *alerts;
226 const char *sessionid;
229 const char *server_software;
230 const char *local_addr;
231 unsigned int local_port;
232 const char *local_user;
236 const char *remote_addr;
237 unsigned int remote_port;
238 const char *remote_user;
242 const char *request_line;
243 const char *request_method;
244 const char *request_uri;
245 const char *query_string;
246 const char *request_protocol;
248 const char *hostname;
250 apr_table_t *request_headers;
252 apr_off_t request_content_length;
253 const char *request_content_type;
255 apr_table_t *arguments;
256 apr_table_t *arguments_to_sanitise;
257 apr_table_t *request_headers_to_sanitise;
258 apr_table_t *response_headers_to_sanitise;
259 apr_table_t *request_cookies;
261 unsigned int is_relevant;
263 apr_table_t *tx_vars;
265 /* ENH: refactor to allow arbitrary var tables */
266 apr_table_t *geo_vars;
269 unsigned int response_status;
270 const char *status_line;
271 const char *response_protocol;
272 apr_table_t *response_headers;
273 unsigned int response_headers_sent;
274 apr_off_t bytes_sent;
276 /* modsecurity request body processing stuff */
278 unsigned int msc_reqbody_storage; /* on disk or in memory */
279 unsigned int msc_reqbody_spilltodisk;
280 unsigned int msc_reqbody_read;
282 apr_pool_t *msc_reqbody_mp; /* this is where chunks are allocated from */
283 apr_array_header_t *msc_reqbody_chunks; /* data chunks when stored in memory */
284 unsigned int msc_reqbody_length; /* the amount of data received */
285 int msc_reqbody_chunk_position; /* used when retrieving the body */
286 unsigned int msc_reqbody_chunk_offset; /* offset of the chunk currently in use */
287 msc_data_chunk *msc_reqbody_chunk_current; /* current chunk */
288 char *msc_reqbody_buffer;
290 const char *msc_reqbody_filename; /* when stored on disk */
292 msc_data_chunk *msc_reqbody_disk_chunk;
294 const char *msc_reqbody_processor;
295 int msc_reqbody_error;
296 const char *msc_reqbody_error_msg;
298 apr_size_t msc_reqbody_no_files_length;
300 multipart_data *mpd; /* MULTIPART processor data structure */
302 xml_data *xml; /* XML processor data structure */
305 char *new_auditlog_boundary;
306 char *new_auditlog_filename;
307 apr_file_t *new_auditlog_fd;
308 unsigned int new_auditlog_size;
309 apr_md5_ctx_t new_auditlog_md5ctx;
311 unsigned int was_intercepted;
312 unsigned int rule_was_intercepted;
313 unsigned int intercept_phase;
314 msre_actionset *intercept_actionset;
315 const char *intercept_message;
317 /* performance measurement */
318 apr_time_t request_time;
319 apr_time_t time_checkpoint_1;
320 apr_time_t time_checkpoint_2;
321 apr_time_t time_checkpoint_3;
323 apr_array_header_t *matched_rules;
324 msc_string *matched_var;
325 int highest_severity;
328 int upload_extract_files;
329 int upload_remove_files;
332 apr_table_t *collections_original;
333 apr_table_t *collections;
334 apr_table_t *collections_dirty;
336 /* rule processing temp pool */
337 apr_pool_t *msc_rule_mptmp;
339 /* content injection */
340 const char *content_prepend;
341 apr_off_t content_prepend_len;
342 const char *content_append;
343 apr_off_t content_append_len;
347 apr_size_t tcache_items;
350 apr_array_header_t *removed_rules;
352 /* When "allow" is executed the variable below is
353 * updated to contain the scope of the allow action. Set
354 * at 0 by default, it will have ACTION_ALLOW if we are
355 * to allow phases 1-4 and ACTION_ALLOW_REQUEST if we
356 * are to allow phases 1-2 only.
358 unsigned int allow_scope;
361 struct directory_config {
364 msre_ruleset *ruleset;
368 int reqbody_buffering;
369 long int reqbody_inmemory_limit;
370 long int reqbody_limit;
371 long int reqbody_no_files_limit;
375 apr_table_t *of_mime_types;
376 int of_mime_types_cleared;
379 const char *debuglog_name;
381 apr_file_t *debuglog_fd;
384 int argument_separator;
386 int rule_inheritance;
387 apr_array_header_t *rule_exceptions;
390 /* -- Audit log -- */
392 /* Whether audit log should be enabled in the context or not */
395 /* AUDITLOG_SERIAL (single file) or AUDITLOG_CONCURRENT (multiple files) */
398 /* Mode for audit log directories and files */
399 apr_fileperms_t auditlog_dirperms;
400 apr_fileperms_t auditlog_fileperms;
402 /* The name of the audit log file (for the old type), or the
403 * name of the index file (for the new audit log type)
406 /* The name of the secondary index file */
407 char *auditlog2_name;
409 /* The file descriptors for the files above */
410 apr_file_t *auditlog_fd;
411 apr_file_t *auditlog2_fd;
413 /* For the new-style audit log only, the path where
414 * audit log entries will be stored
416 char *auditlog_storage_dir;
418 /* A list of parts to include in the new-style audit log
419 * entry. By default, it contains 'ABCFHZ'. Have a look at
420 * the AUDITLOG_PART_* constants above to decipher the
423 char *auditlog_parts;
425 /* A regular expression that determines if a response
426 * status is treated as relevant.
428 msc_regex_t *auditlog_relevant_regex;
432 const char *upload_dir;
433 int upload_keep_files;
434 int upload_validates_files;
435 int upload_filemode; /* int only so NOT_SET works */
437 /* Used only in the configuration phase. */
438 msre_rule *tmp_chain_starter;
439 msre_actionset *tmp_default_actionset;
440 apr_table_t *tmp_rule_placeholders;
443 const char *data_dir;
444 const char *webappid;
446 /* Content injection. */
447 int content_injection_enabled;
449 /* PDF XSS Protection. */
451 const char *pdfp_secret;
453 const char *pdfp_token_name;
462 int cache_trans_incremental;
463 apr_size_t cache_trans_min;
464 apr_size_t cache_trans_max;
465 apr_size_t cache_trans_maxitems;
467 /* Array to hold signatures of components, which will
468 * appear in the ModSecurity signature in the audit log.
470 apr_array_header_t *component_signatures;
472 /* Request character encoding. */
473 const char *request_encoding;
476 struct error_message {
486 apr_global_mutex_t *auditlog_lock;
488 unsigned int processing_mode;
491 struct msc_data_chunk {
494 unsigned int is_permanent;
499 unsigned int name_len;
500 unsigned int name_origin_offset;
501 unsigned int name_origin_len;
503 unsigned int value_len;
504 unsigned int value_origin_offset;
505 unsigned int value_origin_len;
511 unsigned int name_len;
513 unsigned int value_len;
517 /* Engine functions */
519 msc_engine DSOLOCAL *modsecurity_create(apr_pool_t *mp, int processing_mode);
521 int DSOLOCAL modsecurity_init(msc_engine *msce, apr_pool_t *mp);
523 void DSOLOCAL modsecurity_child_init(msc_engine *msce);
525 void DSOLOCAL modsecurity_shutdown(msc_engine *msce);
527 apr_status_t DSOLOCAL modsecurity_tx_init(modsec_rec *msr);
529 apr_status_t DSOLOCAL modsecurity_process_phase(modsec_rec *msr, unsigned int phase);
532 /* Request body functions */
534 apr_status_t DSOLOCAL modsecurity_request_body_start(modsec_rec *msr, char **error_msg);
536 apr_status_t DSOLOCAL modsecurity_request_body_store(modsec_rec *msr,
537 const char *data, apr_size_t length, char **error_msg);
539 apr_status_t DSOLOCAL modsecurity_request_body_end(modsec_rec *msr, char **error_msg);
541 apr_status_t DSOLOCAL modsecurity_request_body_retrieve_start(modsec_rec *msr, char **error_msg);
543 apr_status_t DSOLOCAL modsecurity_request_body_retrieve_end(modsec_rec *msr);
545 /* Retrieves up to nbytes bytes of the request body. Returns 1 on
546 * success, 0 when there is no more data, or -1 on error. On return
547 * nbytes will contain the number of bytes stored in the buffer.
549 apr_status_t DSOLOCAL modsecurity_request_body_retrieve(modsec_rec *msr, msc_data_chunk **chunk,
550 long int nbytes, char **error_msg);
552 void DSOLOCAL msc_add(modsec_rec *msr, int level, msre_actionset *actionset,
553 const char *action_message, const char *rule_message);
555 const char DSOLOCAL *msc_alert_message(modsec_rec *msr, msre_actionset *actionset, const char *action_message,
556 const char *rule_message);
558 void DSOLOCAL msc_alert(modsec_rec *msr, int level, msre_actionset *actionset, const char *action_message,
559 const char *rule_message);
561 apr_status_t DSOLOCAL modsecurity_request_body_clear(modsec_rec *msr, char **error_msg);