/* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ * Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * * If any of the files related to licensing are missing or if you have any * other questions related to licensing please contact Trustwave Holdings, Inc. * directly using the email address security@modsecurity.org. */ #ifndef _MSC_MULTIPART_H_ #define _MSC_MULTIPART_H_ #define MULTIPART_BUF_SIZE 4096 #define MULTIPART_FORMDATA 1 #define MULTIPART_FILE 2 typedef struct multipart_part multipart_part; typedef struct multipart_data multipart_data; #include "apr_general.h" #include "apr_tables.h" #include "modsecurity.h" typedef struct value_part_t value_part_t; struct value_part_t { char *data; long int length; }; struct multipart_part { /* part type, can be MULTIPART_FORMDATA or MULTIPART_FILE */ int type; /* the name */ char *name; /* variables only, variable value */ char *value; apr_array_header_t *value_parts; /* files only, the content type (where available) */ char *content_type; /* files only, the name of the temporary file holding data */ char *tmp_file_name; int tmp_file_fd; unsigned int tmp_file_size; /* files only, filename as supplied by the browser */ char *filename; char *last_header_name; apr_table_t *headers; char *last_header_line; apr_array_header_t *header_lines; unsigned int offset; unsigned int length; }; struct multipart_data { /* this array keeps parts */ apr_array_header_t *parts; /* Number of parts that are files */ int nfiles; /* mime boundary used to detect when * parts end and begin */ char *boundary; int boundary_count; /* internal buffer and other variables * used while parsing */ char buf[MULTIPART_BUF_SIZE + 2]; int buf_contains_line; char *bufptr; int bufleft; /* line ending status seen immediately before current position. * 0 = neither LF nor CR; 1 = prev char CR; 2 = prev char LF alone; * 3 = prev two chars were CRLF */ int crlf_state; /* crlf_state at end of previous buffer */ int crlf_state_buf_end; unsigned int buf_offset; /* pointer that keeps track of a part while * it is being built */ multipart_part *mpp; /* part parsing state; 0 means we are reading * headers, 1 means we are collecting data */ int mpp_state; /* part parsing substate; if mpp_state is 1 (collecting * data), then for this variable: * 0 means we have not yet read any data between the * post-headers blank line and the next boundary * 1 means we have read at some data after that blank line */ int mpp_substate_part_data_read; /* because of the way this parsing algorithm * works we hold back the last two bytes of * each data chunk so that we can discard it * later if the next data chunk proves to be * a boundary; the first byte is an indicator * 0 - no content, 1 - two data bytes available */ char reserve[4]; int seen_data; int is_complete; int flag_error; int flag_data_before; int flag_data_after; int flag_header_folding; int flag_boundary_quoted; int flag_lf_line; int flag_crlf_line; int flag_unmatched_boundary; int flag_boundary_whitespace; int flag_missing_semicolon; int flag_invalid_quoting; int flag_invalid_part; int flag_invalid_header_folding; int flag_file_limit_exceeded; }; /* Functions */ int DSOLOCAL multipart_init(modsec_rec *msr, char **error_msg); int DSOLOCAL multipart_complete(modsec_rec *msr, char **error_msg); int DSOLOCAL multipart_process_chunk(modsec_rec *msr, const char *buf, unsigned int size, char **error_msg); apr_status_t DSOLOCAL multipart_cleanup(modsec_rec *msr); int DSOLOCAL multipart_get_arguments(modsec_rec *msr, char *origin, apr_table_t *arguments); char DSOLOCAL *multipart_reconstruct_urlencoded_body_sanitize(modsec_rec *msr); #endif