Main Page | Modules | Class List | Directories | File List | Class Members | File Members | Related Pages

hi_eo_log.c

Go to the documentation of this file.
00001 /**
00002 **  @file       hi_eo_log.c
00003 **
00004 **  @author     Daniel Roelker <droelker@sourcefire.com>
00005 **
00006 **  @brief      This file contains the event output functionality that 
00007 **              HttpInspect uses to log events and data associated with
00008 **              the events.
00009 **
00010 **  Log events, retrieve events, and select events that HttpInspect
00011 **  generates.
00012 **  
00013 **  Logging Events:
00014 **    Since the object behind this is no memset()s, we have to rely on the
00015 **    stack interface to make sure we don't log the same event twice.  So
00016 **    if there are events in the stack we cycle through to make sure that
00017 **    there are none available before we add a new event and increment the
00018 **    stack count.  Then to reset the event queue, we just need to set the
00019 **    stack count back to zero.
00020 **
00021 **  NOTES:
00022 **    - Initial development.  DJR
00023 */
00024 #include <stdlib.h>
00025 
00026 #include "hi_si.h"
00027 #include "hi_eo.h"
00028 #include "hi_util_xmalloc.h"
00029 #include "hi_return_codes.h"
00030 
00031 /*
00032 **  The client events and the priorities are listed here.
00033 **  Any time that a new client event is added, we have to
00034 **  add the event id and the priority here.  If you want to
00035 **  change either of those characteristics, you have to change
00036 **  them here. 
00037 */
00038 static HI_EVENT_INFO client_event_info[HI_EO_CLIENT_EVENT_NUM] = {
00039     { HI_EO_CLIENT_ASCII, HI_EO_LOW_PRIORITY, HI_EO_CLIENT_ASCII_STR },
00040     { HI_EO_CLIENT_DOUBLE_DECODE, HI_EO_HIGH_PRIORITY,
00041         HI_EO_CLIENT_DOUBLE_DECODE_STR },
00042     { HI_EO_CLIENT_U_ENCODE, HI_EO_MED_PRIORITY, HI_EO_CLIENT_U_ENCODE_STR },
00043     { HI_EO_CLIENT_BARE_BYTE, HI_EO_HIGH_PRIORITY, HI_EO_CLIENT_BARE_BYTE_STR},
00044     { HI_EO_CLIENT_BASE36, HI_EO_HIGH_PRIORITY, HI_EO_CLIENT_BASE36_STR },
00045     { HI_EO_CLIENT_UTF_8, HI_EO_LOW_PRIORITY, HI_EO_CLIENT_UTF_8_STR },
00046     { HI_EO_CLIENT_IIS_UNICODE, HI_EO_LOW_PRIORITY, 
00047         HI_EO_CLIENT_IIS_UNICODE_STR },
00048     { HI_EO_CLIENT_MULTI_SLASH, HI_EO_MED_PRIORITY,
00049         HI_EO_CLIENT_MULTI_SLASH_STR },
00050     { HI_EO_CLIENT_IIS_BACKSLASH, HI_EO_MED_PRIORITY, 
00051         HI_EO_CLIENT_IIS_BACKSLASH_STR },
00052     { HI_EO_CLIENT_SELF_DIR_TRAV, HI_EO_HIGH_PRIORITY,
00053         HI_EO_CLIENT_SELF_DIR_TRAV_STR },
00054     { HI_EO_CLIENT_DIR_TRAV, HI_EO_LOW_PRIORITY, HI_EO_CLIENT_DIR_TRAV_STR },
00055     { HI_EO_CLIENT_APACHE_WS, HI_EO_MED_PRIORITY, HI_EO_CLIENT_APACHE_WS_STR },
00056     { HI_EO_CLIENT_IIS_DELIMITER, HI_EO_MED_PRIORITY,
00057         HI_EO_CLIENT_IIS_DELIMITER_STR },
00058     { HI_EO_CLIENT_NON_RFC_CHAR, HI_EO_HIGH_PRIORITY,
00059         HI_EO_CLIENT_NON_RFC_CHAR_STR },
00060     { HI_EO_CLIENT_OVERSIZE_DIR, HI_EO_HIGH_PRIORITY,
00061         HI_EO_CLIENT_OVERSIZE_DIR_STR },
00062     {HI_EO_CLIENT_LARGE_CHUNK, HI_EO_HIGH_PRIORITY,
00063         HI_EO_CLIENT_LARGE_CHUNK_STR },
00064     {HI_EO_CLIENT_PROXY_USE, HI_EO_LOW_PRIORITY,
00065         HI_EO_CLIENT_PROXY_USE_STR },
00066     {HI_EO_CLIENT_WEBROOT_DIR, HI_EO_HIGH_PRIORITY,
00067         HI_EO_CLIENT_WEBROOT_DIR_STR }
00068 };
00069 
00070 static HI_EVENT_INFO anom_server_event_info[HI_EO_ANOM_SERVER_EVENT_NUM] = {
00071     {HI_EO_ANOM_SERVER, HI_EO_HIGH_PRIORITY, HI_EO_ANOM_SERVER_STR }
00072 };
00073 
00074 /*
00075 **  hi_eo_anom_server_event_log::
00076 */
00077 /**
00078 **  This routine logs anomalous server events to the event queue.
00079 **  
00080 **  @param Session   pointer to the HttpInspect session
00081 **  @param iEvent    the event id for the client
00082 **  @param data      pointer to the user data of the event
00083 **  @param free_data pointer to a function to free the user data
00084 **
00085 **  @return integer
00086 **
00087 **  @retval HI_SUCCESS function successful
00088 **  @retval HI_INVALID_ARG invalid arguments
00089 */
00090 int hi_eo_anom_server_event_log(HI_SESSION *Session, int iEvent, void *data,
00091         void (*free_data)(void *))
00092 {
00093     HI_ANOM_SERVER_EVENTS *anom_server_events;
00094     HI_EVENT *event;
00095     int iCtr;
00096 
00097     /*
00098     **  Check the input variables for correctness
00099     */
00100     if(!Session || (iEvent >= HI_EO_ANOM_SERVER_EVENT_NUM))
00101     {
00102         return HI_INVALID_ARG;
00103     }
00104 
00105     anom_server_events = &(Session->anom_server.event_list);
00106 
00107     /*
00108     **  This is where we cycle through the current event stack.  If the event
00109     **  to be logged is already in the queue, then we increment the event
00110     **  count, before returning.  Otherwise, we fall through the loop and
00111     **  set the event before adding it to the queue and incrementing the
00112     **  pointer.
00113     */
00114     for(iCtr = 0; iCtr < anom_server_events->stack_count; iCtr++)
00115     {
00116         if(anom_server_events->stack[iCtr] == iEvent)
00117         {
00118             anom_server_events->events[iEvent].count++;
00119             return HI_SUCCESS;
00120         }
00121     }
00122 
00123     /*
00124     **  Initialize the event before putting it in the queue.
00125     */
00126     event = &(anom_server_events->events[iEvent]);
00127     event->event_info = &anom_server_event_info[iEvent];
00128     event->count = 1;
00129     event->data = data;
00130     event->free_data = free_data;
00131 
00132     /*
00133     **  We now add the event to the stack.
00134     */
00135     anom_server_events->stack[anom_server_events->stack_count] = iEvent;
00136     anom_server_events->stack_count++;
00137 
00138     return HI_SUCCESS;
00139 }
00140 
00141 /*
00142 **  NAME
00143 **    hi_eo_client_event_log::
00144 */
00145 /**
00146 **  This function logs client events during HttpInspect processing.
00147 **
00148 **  The idea behind this event logging is modularity, but at the same time
00149 **  performance.  We accomplish this utilizing an optimized stack as an
00150 **  index into the client event array, instead of walking a list for
00151 **  already logged events.  The problem here is that we can't just log
00152 **  every event that we've already seen, because this opens us up to a 
00153 **  DOS.  So by using this method, we can quickly check if an event
00154 **  has already been logged and deal appropriately.
00155 **
00156 **  @param Session   pointer to the HttpInspect session
00157 **  @param iEvent    the event id for the client
00158 **  @param data      pointer to the user data of the event
00159 **  @param free_data pointer to a function to free the user data
00160 **
00161 **  @return integer
00162 **
00163 **  @retval HI_SUCCESS function successful
00164 **  @retval HI_INVALID_ARG invalid arguments
00165 */
00166 int hi_eo_client_event_log(HI_SESSION *Session, int iEvent, void *data,
00167         void (*free_data)(void *))
00168 {
00169     HI_CLIENT_EVENTS *client_events;
00170     HI_EVENT *event;
00171     int iCtr;
00172 
00173     /*
00174     **  Check the input variables for correctness
00175     */
00176     if(!Session || (iEvent >= HI_EO_CLIENT_EVENT_NUM))
00177     {
00178         return HI_INVALID_ARG;
00179     }
00180 
00181     client_events = &(Session->client.event_list);
00182 
00183     /*
00184     **  This is where we cycle through the current event stack.  If the event
00185     **  to be logged is already in the queue, then we increment the event
00186     **  count, before returning.  Otherwise, we fall through the loop and
00187     **  set the event before adding it to the queue and incrementing the
00188     **  pointer.
00189     */
00190     for(iCtr = 0; iCtr < client_events->stack_count; iCtr++)
00191     {
00192         if(client_events->stack[iCtr] == iEvent)
00193         {
00194             client_events->events[iEvent].count++;
00195             return HI_SUCCESS;
00196         }
00197     }
00198 
00199     /*
00200     **  Initialize the event before putting it in the queue.
00201     */
00202     event = &(client_events->events[iEvent]);
00203     event->event_info = &client_event_info[iEvent];
00204     event->count = 1;
00205     event->data = data;
00206     event->free_data = free_data;
00207 
00208     /*
00209     **  We now add the event to the stack.
00210     */
00211     client_events->stack[client_events->stack_count] = iEvent;
00212     client_events->stack_count++;
00213 
00214     return HI_SUCCESS;
00215 }

Generated on Sun May 14 14:51:15 2006 by  doxygen 1.4.2