#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include "hi_ui_config.h"
#include "hi_si.h"
#include "hi_mi.h"
#include "hi_client.h"
#include "hi_eo_log.h"
#include "hi_util.h"
#include "hi_util_hbm.h"
#include "hi_return_codes.h"
Go to the source code of this file.
Defines | |
#define | URI_END 1 |
#define | NO_URI -1 |
#define | INVALID_HEX_VAL -1 |
Typedefs | |
typedef s_URI_PTR | URI_PTR |
typedef int(* | LOOKUP_FCN )(HI_SESSION *, u_char *, u_char *, u_char **, URI_PTR *) |
Functions | |
static int | CheckChunkEncoding (HI_SESSION *Session, u_char *start, u_char *end) |
static INLINE u_char * | FindPipelineReq (u_char *start, u_char *end) |
static int | IsHttpVersion (u_char **ptr, u_char *end) |
static int | find_rfc_delimiter (HI_SESSION *Session, u_char *start, u_char *end, u_char **ptr, URI_PTR *uri_ptr) |
static int | find_non_rfc_delimiter (HI_SESSION *Session, u_char *start, u_char *end, u_char **ptr, URI_PTR *uri_ptr) |
static int | NextNonWhiteSpace (HI_SESSION *Session, u_char *start, u_char *end, u_char **ptr, URI_PTR *uri_ptr) |
static int | SetPercentNorm (HI_SESSION *Session, u_char *start, u_char *end, u_char **ptr, URI_PTR *uri_ptr) |
static INLINE int | CheckLongDir (HI_SESSION *Session, URI_PTR *uri_ptr, u_char *ptr) |
static int | SetSlashNorm (HI_SESSION *Session, u_char *start, u_char *end, u_char **ptr, URI_PTR *uri_ptr) |
static int | SetBackSlashNorm (HI_SESSION *Session, u_char *start, u_char *end, u_char **ptr, URI_PTR *uri_ptr) |
static int | SetBinaryNorm (HI_SESSION *Session, u_char *start, u_char *end, u_char **ptr, URI_PTR *uri_ptr) |
static int | SetParamField (HI_SESSION *Session, u_char *start, u_char *end, u_char **ptr, URI_PTR *uri_ptr) |
static int | SetProxy (HI_SESSION *Session, u_char *start, u_char *end, u_char **ptr, URI_PTR *uri_ptr) |
static int | SetClientVars (HI_CLIENT *Client, URI_PTR *uri_ptr, u_int dsize) |
static int | StatelessInspection (HI_SESSION *Session, unsigned char *data, int dsize) |
int | hi_client_inspection (void *S, unsigned char *data, int dsize) |
int | hi_client_init (HTTPINSPECT_GLOBAL_CONF *GlobalConf) |
Variables | |
static LOOKUP_FCN | lookup_table [256] |
static int | hex_lookup [256] |
The job of the client module is to analyze and inspect the HTTP protocol, finding where the various fields begin and end. This must be accomplished in a stateful and stateless manner.
While the fields are being determined, we also do checks for normalization, so we don't normalize fields that don't need it.
Currently, the only fields we check for this is the URI and the parameter fields.
NOTES:
Definition in file hi_client.c.
|
Definition at line 43 of file hi_client.c. Referenced by CheckChunkEncoding(). |
|
Definition at line 42 of file hi_client.c. Referenced by find_non_rfc_delimiter(), find_rfc_delimiter(), and NextNonWhiteSpace(). |
|
Definition at line 41 of file hi_client.c. Referenced by find_non_rfc_delimiter(), find_rfc_delimiter(), and StatelessInspection(). |
|
This makes passing function arguments much more readable and easier to follow. Definition at line 79 of file hi_client.c. |
|
This structure holds pointers to the different sections of an HTTP request. We need to track where whitespace begins and ends, so we can evaluate the placement of the URI correctly. For example, GET / HTTP/1.0 ^ ^ start end The end space pointers are set to NULL if there is space until the end of the buffer. |
|
This routine checks for chunk encoding anomalies in an HTTP client request packet. We convert potential chunk lengths and test them against the user-defined max chunk length. We log events on any chunk lengths that are over this defined chunk lengths. Chunks are skipped to save time when the chunk is contained in the packet. We assume coming into this function that we are pointed at the beginning of what may be a chunk length. That's why the iCheckChunk var is set to 1.
Definition at line 116 of file hi_client.c. References s_HTTPINSPECT_CONF::chunk_length, hex_lookup, hi_eo_client_event_log(), HI_EO_CLIENT_LARGE_CHUNK, hi_eo_generate_event(), HI_INVALID_ARG, HI_SUCCESS, hi_util_in_bounds(), int(), INVALID_HEX_VAL, NULL, and s_HI_SESSION::server_conf. Referenced by StatelessInspection(). |
|
We check the directory length against the global config.
Definition at line 847 of file hi_client.c. References hi_eo_client_event_log(), HI_EO_CLIENT_OVERSIZE_DIR, hi_eo_generate_event(), HI_SUCCESS, s_URI_PTR::last_dir, s_HTTPINSPECT_CONF::long_dir, NULL, s_URI_PTR::param, and s_HI_SESSION::server_conf. Referenced by hi_norm_uri(), InspectUriChar(), SetSlashNorm(), and StatelessInspection(). |
|
Check for non standard delimiter ' It now appears that apache and iis both take this non-standard delimiter. So, we most likely will always look for it, but maybe give off a special alert or something.
Definition at line 483 of file hi_client.c. References s_HTTPINSPECT_CONF_OPT::alert, s_URI_PTR::delimiter, hi_eo_client_event_log(), HI_EO_CLIENT_IIS_DELIMITER, hi_eo_generate_event(), s_URI_PTR::ident, s_HTTPINSPECT_CONF::iis_delimiter, NO_URI, NULL, s_HTTPINSPECT_CONF_OPT::on, s_HI_SESSION::server_conf, s_URI_PTR::uri, URI_END, and s_URI_PTR::uri_end. Referenced by hi_client_init(). |
|
Check for standard RFC HTTP delimiter. If we find the delimiter, we return that URI_PTR structures should be checked, which bails us out of the loop. If there isn't a RFC delimiter, then we bail with a no URI. Otherwise, we check for out of bounds.
Definition at line 420 of file hi_client.c. References s_URI_PTR::delimiter, HI_OUT_OF_BOUNDS, hi_util_in_bounds(), s_URI_PTR::ident, NO_URI, s_URI_PTR::uri, URI_END, and s_URI_PTR::uri_end. Referenced by hi_client_init(). |
|
Catch multiple requests per packet, by returning pointer to after the end of the request header if there is another request. There are 4 types of "valid" delimiters that we look for. They are: "\r\n\r\n" "\r\n\n" "\n\r\n" "\n\n" The only patterns that we really only need to look for are: "\n\r\n" "\n\n" The reason being that these two patterns are suffixes of the other patterns. So once we find those, we are all good.
Definition at line 266 of file hi_client.c. References NULL. Referenced by StatelessInspection(). |
|
Initializes arrays and search algorithms depending on the type of inspection that we are doing.
Definition at line 1532 of file hi_client.c. References find_non_rfc_delimiter(), find_rfc_delimiter(), hex_lookup, HI_SUCCESS, HI_UI_CONFIG_STATEFUL, s_HTTPINSPECT_GLOBAL_CONF::inspection_type, lookup_table, memset, NextNonWhiteSpace(), SetBackSlashNorm(), SetBinaryNorm(), SetParamField(), SetPercentNorm(), SetProxy(), and SetSlashNorm(). Referenced by HttpInspectInit(). |
|
Definition at line 1472 of file hi_client.c. References s_HI_SESSION::global_conf, GlobalConf, HI_INVALID_ARG, HI_NONFATAL_ERR, HI_SUCCESS, HI_UI_CONFIG_STATEFUL, s_HTTPINSPECT_GLOBAL_CONF::inspection_type, and StatelessInspection(). Referenced by hi_mi_mode_inspection(). |
|
This checks that there is a version following a space with in an HTTP packet. This function gets called when a whitespace area has ended, and we want to know if a version identifier is followed directly after. So we look for the rfc standard "HTTP/" and report appropriately. We also need to make sure that the function succeeds given an end of buffer, so for instance if the buffer ends like " HTT", we still assume that this is a valid version identifier because of TCP segmentation.
We also check for the 0.9 standard of GET URI
Definition at line 343 of file hi_client.c. Referenced by NextNonWhiteSpace(). |
|
Update the URI_PTR fields spaces, find the next non-white space char, and validate the HTTP version identifier after the spaces. This is the main part of the URI algorithm. This verifies that there isn't too many spaces in the data to be a URI, it checks that after the second space that there is an HTTP identifier or otherwise it's no good. Also, if we've found an identifier after the first whitespace, and find another whitespace, there is no URI. The uri and uri_end pointers are updated in this function depending on what space we are at, and if the space was followed by the HTTP identifier. (NOTE: the HTTP delimiter is no longer "HTTP/", but can also be "\r\n", "\n", or "\r". This is the defunct method, and we deal with it in the IsHttpVersion and delimiter functions.)
Definition at line 570 of file hi_client.c. References s_HTTPINSPECT_CONF_OPT::alert, s_HTTPINSPECT_CONF::apache_whitespace, s_URI_PTR::first_sp_end, s_URI_PTR::first_sp_start, HI_EO_CLIENT_APACHE_WS, hi_eo_client_event_log(), hi_eo_generate_event(), HI_OUT_OF_BOUNDS, HI_SUCCESS, hi_util_in_bounds(), s_URI_PTR::ident, IsHttpVersion(), s_URI_PTR::last_dir, NO_URI, s_HTTPINSPECT_CONF::non_strict, s_URI_PTR::norm, NULL, s_HTTPINSPECT_CONF_OPT::on, s_URI_PTR::param, s_URI_PTR::proxy, s_URI_PTR::second_sp_end, s_URI_PTR::second_sp_start, s_HI_SESSION::server_conf, s_HTTPINSPECT_CONF::tab_uri_delimiter, s_URI_PTR::uri, and s_URI_PTR::uri_end. Referenced by hi_client_init(). |
|
Check for backslashes and if we need to normalize. This really just checks the configuration option, and sets the norm variable if applicable.
Definition at line 977 of file hi_client.c. References HI_SUCCESS, s_URI_PTR::ident, s_HTTPINSPECT_CONF::iis_backslash, s_URI_PTR::norm, s_HTTPINSPECT_CONF_OPT::on, and s_HI_SESSION::server_conf. Referenced by hi_client_init(). |
|
Look for non-ASCII chars in the URI. We look for these chars in the URI and set the normalization variable if it's not already set. I think we really only need this for IIS servers, but we may want to know if it's in the URI too.
Definition at line 1016 of file hi_client.c. References HI_SUCCESS, s_URI_PTR::ident, and s_URI_PTR::norm. Referenced by hi_client_init(). |
|
This is where we set the HI_CLIENT values that we found during URI discovery. This also covers checking these values for errors.
Definition at line 1117 of file hi_client.c. References HI_NONFATAL_ERR, HI_SUCCESS, s_URI_PTR::norm, NULL, s_HI_CLIENT::request, s_HI_CLIENT_REQ::uri, s_URI_PTR::uri, s_URI_PTR::uri_end, s_HI_CLIENT_REQ::uri_norm, and s_HI_CLIENT_REQ::uri_size. Referenced by StatelessInspection(). |
|
This function sets the parameter field as the first '?'. The big thing is that we set the param value, so we don't false positive long dir events when it's really just a long parameter field.
Definition at line 1048 of file hi_client.c. References HI_SUCCESS, s_URI_PTR::ident, and s_URI_PTR::param. Referenced by hi_client_init(). |
|
Check for percent normalization in the URI buffer. We don't do much here besides check the configuration, set the pointer, and continue processing.
Definition at line 814 of file hi_client.c. References s_HTTPINSPECT_CONF::ascii, HI_SUCCESS, s_URI_PTR::ident, s_URI_PTR::norm, s_HTTPINSPECT_CONF_OPT::on, and s_HI_SESSION::server_conf. Referenced by hi_client_init(). |
|
This function checks for an absolute URI in the URI.
Definition at line 1077 of file hi_client.c. References s_HTTPINSPECT_CONF::allow_proxy, s_HI_SESSION::global_conf, HI_SUCCESS, hi_util_in_bounds(), s_URI_PTR::ident, s_URI_PTR::last_dir, s_URI_PTR::proxy, s_HTTPINSPECT_GLOBAL_CONF::proxy_alert, and s_HI_SESSION::server_conf. Referenced by hi_client_init(). |
|
Check for any directory traversal or multi-slash normalization.
Definition at line 890 of file hi_client.c. References CheckLongDir(), s_HTTPINSPECT_CONF::directory, HI_OUT_OF_BOUNDS, HI_SUCCESS, hi_util_in_bounds(), s_URI_PTR::ident, s_URI_PTR::last_dir, s_HTTPINSPECT_CONF::multiple_slash, s_URI_PTR::norm, NULL, s_HTTPINSPECT_CONF_OPT::on, and s_HI_SESSION::server_conf. Referenced by hi_client_init(). |
|
Find the URI and determine whether the URI needs to be normalized. This is a big step in stateless inspection, because we need to reliably find the URI and when possible filter out non-URIs. We do this using a simple state machine that is based on characters found in the data buffer. Another important aspect of the stateless inspection is the ability to track and inspect pipelined requests. It is VERY IMPORTANT to reset the pipeline_req pointer, since we don't memset the whole structure. This pointer is reset in the hi_si_session_inspection() function. Check there for more details. Normalization is detected when we are looking at the packet for the URI. We look for the following issues:
If this function returns HI_NONFATAL_ERR, we return out of mode_inspection with an error and abort HttpInspect processing, and continue on with any other processing we do. The Session parameters that we use here are reset in the next time that we do session_inspection, so we don't do any initialization here.
Definition at line 1233 of file hi_client.c. References s_HTTPINSPECT_CONF::allow_proxy, CheckChunkEncoding(), CheckLongDir(), s_HTTPINSPECT_CONF::chunk_length, s_HI_SESSION::client, s_HI_SESSION::client_conf, s_URI_PTR::delimiter, FindPipelineReq(), s_URI_PTR::first_sp_end, s_HI_SESSION::global_conf, hi_eo_client_event_log(), HI_EO_CLIENT_PROXY_USE, hi_eo_generate_event(), HI_INVALID_ARG, HI_NONFATAL_ERR, HI_OUT_OF_BOUNDS, HI_SUCCESS, hi_util_in_bounds(), lookup_table, memset, s_HTTPINSPECT_CONF::no_pipeline, NULL, s_HI_CLIENT_REQ::pipeline_req, s_URI_PTR::proxy, s_HTTPINSPECT_GLOBAL_CONF::proxy_alert, s_HI_CLIENT::request, s_HI_SESSION::server_conf, SetClientVars(), s_URI_PTR::uri, URI_END, and s_URI_PTR::uri_end. Referenced by hi_client_inspection(). |
|
Definition at line 87 of file hi_client.c. Referenced by CheckChunkEncoding(), DoubleDecode(), hi_client_init(), hi_norm_init(), PercentDecode(), and UDecode(). |
|
Definition at line 86 of file hi_client.c. Referenced by hi_client_init(), and StatelessInspection(). |