"Fossies" - the Fresh Open Source Software Archive

Member "snort-2.9.17/src/preprocessors/HttpInspect/event_output/hi_eo_log.c" (16 Oct 2020, 16407 Bytes) of package /linux/misc/snort-2.9.17.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "hi_eo_log.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.9.16.1_vs_2.9.17.

    1 /****************************************************************************
    2  *
    3  * Copyright (C) 2014-2020 Cisco and/or its affiliates. All rights reserved.
    4  * Copyright (C) 2003-2013 Sourcefire, Inc.
    5  *
    6  * This program is free software; you can redistribute it and/or modify
    7  * it under the terms of the GNU General Public License Version 2 as
    8  * published by the Free Software Foundation.  You may not use, modify or
    9  * distribute this program under any other version of the GNU General
   10  * Public License.
   11  *
   12  * This program is distributed in the hope that it will be useful,
   13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15  * GNU General Public License for more details.
   16  *
   17  * You should have received a copy of the GNU General Public License
   18  * along with this program; if not, write to the Free Software
   19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   20  *
   21  ****************************************************************************/
   22 
   23 /**
   24 **  @file       hi_eo_log.c
   25 **
   26 **  @author     Daniel Roelker <droelker@sourcefire.com>
   27 **
   28 **  @brief      This file contains the event output functionality that
   29 **              HttpInspect uses to log events and data associated with
   30 **              the events.
   31 **
   32 **  Log events, retrieve events, and select events that HttpInspect
   33 **  generates.
   34 **
   35 **  Logging Events:
   36 **    Since the object behind this is no memset()s, we have to rely on the
   37 **    stack interface to make sure we don't log the same event twice.  So
   38 **    if there are events in the stack we cycle through to make sure that
   39 **    there are none available before we add a new event and increment the
   40 **    stack count.  Then to reset the event queue, we just need to set the
   41 **    stack count back to zero.
   42 **
   43 **  NOTES:
   44 **    - Initial development.  DJR
   45 */
   46 #include <stdlib.h>
   47 
   48 #ifdef HAVE_CONFIG_H
   49 #include "config.h"
   50 #endif
   51 
   52 #include "hi_si.h"
   53 #include "hi_eo.h"
   54 #include "hi_util_xmalloc.h"
   55 #include "hi_return_codes.h"
   56 
   57 /*
   58 **  The client events and the priorities are listed here.
   59 **  Any time that a new client event is added, we have to
   60 **  add the event id and the priority here.  If you want to
   61 **  change either of those characteristics, you have to change
   62 **  them here.
   63 */
   64 static HI_EVENT_INFO client_event_info[HI_EO_CLIENT_EVENT_NUM] = {
   65     { HI_EO_CLIENT_ASCII, HI_EO_LOW_PRIORITY, HI_EO_CLIENT_ASCII_STR },
   66     { HI_EO_CLIENT_DOUBLE_DECODE, HI_EO_HIGH_PRIORITY,
   67         HI_EO_CLIENT_DOUBLE_DECODE_STR },
   68     { HI_EO_CLIENT_U_ENCODE, HI_EO_MED_PRIORITY, HI_EO_CLIENT_U_ENCODE_STR },
   69     { HI_EO_CLIENT_BARE_BYTE, HI_EO_HIGH_PRIORITY, HI_EO_CLIENT_BARE_BYTE_STR},
   70     /* Base36 is deprecated - leave here so events keep the same number */
   71     { HI_EO_CLIENT_BASE36, HI_EO_HIGH_PRIORITY, HI_EO_CLIENT_BASE36_STR },
   72     { HI_EO_CLIENT_UTF_8, HI_EO_LOW_PRIORITY, HI_EO_CLIENT_UTF_8_STR },
   73     { HI_EO_CLIENT_IIS_UNICODE, HI_EO_LOW_PRIORITY,
   74         HI_EO_CLIENT_IIS_UNICODE_STR },
   75     { HI_EO_CLIENT_MULTI_SLASH, HI_EO_MED_PRIORITY,
   76         HI_EO_CLIENT_MULTI_SLASH_STR },
   77     { HI_EO_CLIENT_IIS_BACKSLASH, HI_EO_MED_PRIORITY,
   78         HI_EO_CLIENT_IIS_BACKSLASH_STR },
   79     { HI_EO_CLIENT_SELF_DIR_TRAV, HI_EO_HIGH_PRIORITY,
   80         HI_EO_CLIENT_SELF_DIR_TRAV_STR },
   81     { HI_EO_CLIENT_DIR_TRAV, HI_EO_LOW_PRIORITY, HI_EO_CLIENT_DIR_TRAV_STR },
   82     { HI_EO_CLIENT_APACHE_WS, HI_EO_MED_PRIORITY, HI_EO_CLIENT_APACHE_WS_STR },
   83     { HI_EO_CLIENT_IIS_DELIMITER, HI_EO_MED_PRIORITY,
   84         HI_EO_CLIENT_IIS_DELIMITER_STR },
   85     { HI_EO_CLIENT_NON_RFC_CHAR, HI_EO_HIGH_PRIORITY,
   86         HI_EO_CLIENT_NON_RFC_CHAR_STR },
   87     { HI_EO_CLIENT_OVERSIZE_DIR, HI_EO_HIGH_PRIORITY,
   88         HI_EO_CLIENT_OVERSIZE_DIR_STR },
   89     {HI_EO_CLIENT_LARGE_CHUNK, HI_EO_HIGH_PRIORITY,
   90         HI_EO_CLIENT_LARGE_CHUNK_STR },
   91     {HI_EO_CLIENT_PROXY_USE, HI_EO_LOW_PRIORITY,
   92         HI_EO_CLIENT_PROXY_USE_STR },
   93     {HI_EO_CLIENT_WEBROOT_DIR, HI_EO_HIGH_PRIORITY,
   94         HI_EO_CLIENT_WEBROOT_DIR_STR },
   95     {HI_EO_CLIENT_LONG_HDR, HI_EO_LOW_PRIORITY,
   96         HI_EO_CLIENT_LONG_HDR_STR},
   97     {HI_EO_CLIENT_MAX_HEADERS, HI_EO_LOW_PRIORITY,
   98         HI_EO_CLIENT_MAX_HEADERS_STR},
   99     {HI_EO_CLIENT_MULTIPLE_CONTLEN, HI_EO_HIGH_PRIORITY,
  100         HI_EO_CLIENT_MULTIPLE_CONTLEN_STR},
  101     {HI_EO_CLIENT_CHUNK_SIZE_MISMATCH, HI_EO_HIGH_PRIORITY,
  102         HI_EO_CLIENT_CHUNK_SIZE_MISMATCH_STR},
  103     {HI_EO_CLIENT_INVALID_TRUEIP, HI_EO_LOW_PRIORITY,
  104         HI_EO_CLIENT_INVALID_TRUEIP_STR},
  105     {HI_EO_CLIENT_MULTIPLE_HOST_HDRS, HI_EO_LOW_PRIORITY,
  106         HI_EO_CLIENT_MULTIPLE_HOST_HDRS_STR},
  107     {HI_EO_CLIENT_LONG_HOSTNAME, HI_EO_LOW_PRIORITY,
  108         HI_EO_CLIENT_LONG_HOSTNAME_STR},
  109     {HI_EO_CLIENT_EXCEEDS_SPACES, HI_EO_LOW_PRIORITY,
  110         HI_EO_CLIENT_EXCEEDS_SPACES_STR},
  111     {HI_EO_CLIENT_CONSECUTIVE_SMALL_CHUNKS, HI_EO_MED_PRIORITY,
  112         HI_EO_CLIENT_CONSECUTIVE_SMALL_CHUNKS_STR},
  113     {HI_EO_CLIENT_UNBOUNDED_POST, HI_EO_MED_PRIORITY,
  114         HI_EO_CLIENT_UNBOUNDED_POST_STR},
  115     {HI_EO_CLIENT_MULTIPLE_TRUEIP_IN_SESSION, HI_EO_MED_PRIORITY,
  116         HI_EO_CLIENT_MULTIPLE_TRUEIP_IN_SESSION_STR},
  117     {HI_EO_CLIENT_BOTH_TRUEIP_XFF_HDRS, HI_EO_LOW_PRIORITY,
  118         HI_EO_CLIENT_BOTH_TRUEIP_XFF_HDRS_STR},
  119     {HI_EO_CLIENT_UNKNOWN_METHOD, HI_EO_MED_PRIORITY,
  120         HI_EO_CLIENT_UNKNOWN_METHOD_STR},
  121     {HI_EO_CLIENT_SIMPLE_REQUEST, HI_EO_HIGH_PRIORITY,
  122         HI_EO_CLIENT_SIMPLE_REQUEST_STR},
  123     {HI_EO_CLIENT_UNESCAPED_SPACE_URI, HI_EO_MED_PRIORITY,
  124             HI_EO_CLIENT_UNESCAPED_SPACE_URI_STR},
  125     {HI_EO_CLIENT_PIPELINE_MAX, HI_EO_MED_PRIORITY,
  126         HI_EO_CLIENT_PIPELINE_MAX_STR},
  127     {HI_EO_CLIENT_MULTIPLE_COLON_BETN_KEY_VALUE, HI_EO_HIGH_PRIORITY,
  128         HI_EO_CLIENT_MULTIPLE_COLON_BETN_KEY_VALUE_STR},
  129     {HI_EO_CLIENT_INVALID_RANGE_UNIT_FMT, HI_EO_MED_PRIORITY,
  130         HI_EO_CLIENT_INVALID_RANGE_UNIT_FMT_STR},
  131     {HI_EO_CLIENT_RANGE_NON_GET_METHOD, HI_EO_MED_PRIORITY,
  132         HI_EO_CLIENT_RANGE_NON_GET_METHOD_STR},
  133     {HI_EO_CLIENT_RANGE_FIELD_ERROR, HI_EO_MED_PRIORITY,
  134         HI_EO_CLIENT_RANGE_FIELD_ERROR_STR}
  135 };
  136 
  137 static HI_EVENT_INFO server_event_info[HI_EO_SERVER_EVENT_NUM] = {
  138     {HI_EO_ANOM_SERVER, HI_EO_HIGH_PRIORITY, HI_EO_ANOM_SERVER_STR },
  139     {HI_EO_SERVER_INVALID_STATCODE, HI_EO_MED_PRIORITY,
  140                     HI_EO_SERVER_INVALID_STATCODE_STR},
  141     {HI_EO_SERVER_NO_CONTLEN, HI_EO_MED_PRIORITY,
  142         HI_EO_SERVER_NO_CONTLEN_STR},
  143     {HI_EO_SERVER_UTF_NORM_FAIL, HI_EO_MED_PRIORITY,
  144         HI_EO_SERVER_UTF_NORM_FAIL_STR},
  145     {HI_EO_SERVER_UTF7, HI_EO_MED_PRIORITY,
  146         HI_EO_SERVER_UTF7_STR},
  147     {HI_EO_SERVER_DECOMPR_FAILED, HI_EO_MED_PRIORITY,
  148         HI_EO_SERVER_DECOMPR_FAILED_STR},
  149     {HI_EO_SERVER_CONSECUTIVE_SMALL_CHUNKS, HI_EO_MED_PRIORITY,
  150         HI_EO_SERVER_CONSECUTIVE_SMALL_CHUNKS_STR},
  151     {HI_EO_CLISRV_MSG_SIZE_EXCEPTION, HI_EO_MED_PRIORITY,
  152         HI_EO_CLISRV_MSG_SIZE_EXCEPTION_STR},
  153     {HI_EO_SERVER_JS_OBFUSCATION_EXCD, HI_EO_MED_PRIORITY,
  154         HI_EO_SERVER_JS_OBFUSCATION_EXCD_STR},
  155     {HI_EO_SERVER_JS_EXCESS_WS, HI_EO_MED_PRIORITY,
  156         HI_EO_SERVER_JS_EXCESS_WS_STR},
  157     {HI_EO_SERVER_MIXED_ENCODINGS, HI_EO_MED_PRIORITY,
  158         HI_EO_SERVER_MIXED_ENCODINGS_STR},
  159     {HI_EO_SERVER_SWF_ZLIB_FAILURE, HI_EO_MED_PRIORITY,
  160         HI_EO_SERVER_SWF_ZLIB_FAILURE_STR},
  161     {HI_EO_SERVER_SWF_LZMA_FAILURE, HI_EO_MED_PRIORITY,
  162         HI_EO_SERVER_SWF_LZMA_FAILURE_STR},
  163     {HI_EO_SERVER_PDF_DEFL_FAILURE, HI_EO_MED_PRIORITY,
  164         HI_EO_SERVER_PDF_DEFL_FAILURE_STR},
  165     {HI_EO_SERVER_PDF_UNSUP_COMP_TYPE, HI_EO_MED_PRIORITY,
  166         HI_EO_SERVER_PDF_UNSUP_COMP_TYPE_STR},
  167     {HI_EO_SERVER_PDF_CASC_COMP, HI_EO_MED_PRIORITY,
  168         HI_EO_SERVER_PDF_CASC_COMP_STR},
  169     {HI_EO_SERVER_PDF_PARSE_FAILURE, HI_EO_MED_PRIORITY,
  170         HI_EO_SERVER_PDF_PARSE_FAILURE_STR},
  171     {HI_EO_SERVER_PROTOCOL_OTHER, HI_EO_MED_PRIORITY,
  172         HI_EO_SERVER_PROTOCOL_OTHER_STR},
  173     {HI_EO_SERVER_MULTIPLE_CONTLEN, HI_EO_HIGH_PRIORITY,
  174         HI_EO_SERVER_MULTIPLE_CONTLEN_STR},
  175     {HI_EO_SERVER_MULTIPLE_CONTENT_ENCODING, HI_EO_HIGH_PRIORITY,
  176         HI_EO_SERVER_MULTIPLE_CONTENT_ENCODING_STR},
  177     {HI_EO_SERVER_MULTIPLE_COLON_BETN_KEY_VALUE, HI_EO_HIGH_PRIORITY,
  178         HI_EO_SERVER_MULTIPLE_COLON_BETN_KEY_VALUE_STR},
  179     {HI_EO_SERVER_INVALID_CHAR_BETN_KEY_VALUE, HI_EO_HIGH_PRIORITY,
  180         HI_EO_SERVER_INVALID_CHAR_BETN_KEY_VALUE_STR},
  181     {HI_EO_CLISRV_INVALID_CHUNKED_ENCODING, HI_EO_HIGH_PRIORITY,
  182         HI_EO_CLISRV_INVALID_CHUNKED_EXCEPTION_STR},
  183     {HI_EO_SERVER_PARTIAL_DECOMPRESSION_FAIL, HI_EO_HIGH_PRIORITY,
  184         HI_EO_SERVER_PARTIAL_DECOMPRESSION_FAIL_STR},
  185     {HI_EO_SERVER_INVALID_HEADER_FOLDING, HI_EO_HIGH_PRIORITY,
  186         HI_EO_SERVER_INVALID_HEADER_FOLDING_STR},
  187     {HI_EO_SERVER_JUNK_LINE_BEFORE_RESP_HEADER,HI_EO_HIGH_PRIORITY,
  188         HI_EO_SERVER_JUNK_LINE_BEFORE_RESP_HEADER_STR},
  189     {HI_EO_SERVER_NO_RESP_HEADER_END,HI_EO_HIGH_PRIORITY,
  190         HI_EO_SERVER_NO_RESP_HEADER_END_STR},
  191     {HI_EO_SERVER_INVALID_CHUNK_SIZE,HI_EO_HIGH_PRIORITY,
  192         HI_EO_SERVER_INVALID_CHUNK_SIZE_STR},
  193     {HI_EO_SERVER_INVALID_VERSION_RESP_HEADER,HI_EO_HIGH_PRIORITY,
  194         HI_EO_SERVER_INVALID_VERSION_RESP_HEADER_STR},
  195     {HI_EO_SERVER_INVALID_CONTENT_RANGE_UNIT_FMT, HI_EO_MED_PRIORITY,
  196         HI_EO_SERVER_INVALID_CONTENT_RANGE_UNIT_FMT_STR},
  197     {HI_EO_SERVER_RANGE_FIELD_ERROR, HI_EO_MED_PRIORITY,
  198         HI_EO_SERVER_RANGE_FIELD_ERROR_STR}
  199 };
  200 
  201 /*
  202 **  hi_eo_anom_server_event_log::
  203 */
  204 /**
  205 **  This routine logs anomalous server events to the event queue.
  206 **
  207 **  @param Session   pointer to the HttpInspect session
  208 **  @param iEvent    the event id for the client
  209 **  @param data      pointer to the user data of the event
  210 **  @param free_data pointer to a function to free the user data
  211 **
  212 **  @return integer
  213 **
  214 **  @retval HI_SUCCESS function successful
  215 **  @retval HI_INVALID_ARG invalid arguments
  216 */
  217 int hi_eo_anom_server_event_log(HI_SESSION *Session, int iEvent, void *data,
  218         void (*free_data)(void *))
  219 {
  220     HI_ANOM_SERVER_EVENTS *anom_server_events;
  221     HI_EVENT *event;
  222     int iCtr;
  223 
  224     /*
  225     **  Check the input variables for correctness
  226     */
  227     if(!Session || (iEvent >= HI_EO_SERVER_EVENT_NUM))
  228     {
  229         return HI_INVALID_ARG;
  230     }
  231 
  232     anom_server_events = &(Session->anom_server.event_list);
  233 
  234     /* this won't happen since iEvent < HI_EO_SERVER_EVENT_NUM and
  235      * stack_count can at most equal HI_EO_SERVER_EVENT_NUM */
  236     if (anom_server_events->stack_count > HI_EO_SERVER_EVENT_NUM)
  237         return HI_INVALID_ARG;
  238 
  239     /*
  240     **  This is where we cycle through the current event stack.  If the event
  241     **  to be logged is already in the queue, then we increment the event
  242     **  count, before returning.  Otherwise, we fall through the loop and
  243     **  set the event before adding it to the queue and incrementing the
  244     **  pointer.
  245     */
  246     for(iCtr = 0; iCtr < anom_server_events->stack_count; iCtr++)
  247     {
  248         if(anom_server_events->stack[iCtr] == iEvent)
  249         {
  250             anom_server_events->events[iEvent].count++;
  251             return HI_SUCCESS;
  252         }
  253     }
  254 
  255     /* this won't happen since iEvent will have been found above
  256      * before this happens */
  257     if (anom_server_events->stack_count >= HI_EO_SERVER_EVENT_NUM)
  258         return HI_INVALID_ARG;
  259 
  260     /*
  261     **  Initialize the event before putting it in the queue.
  262     */
  263     event = &(anom_server_events->events[iEvent]);
  264     event->event_info = &server_event_info[iEvent];
  265     event->count = 1;
  266     event->data = data;
  267     event->free_data = free_data;
  268 
  269     /*
  270     **  We now add the event to the stack.
  271     */
  272     anom_server_events->stack[anom_server_events->stack_count] = iEvent;
  273     anom_server_events->stack_count++;
  274 
  275     return HI_SUCCESS;
  276 }
  277 
  278 /*
  279 **  NAME
  280 **    hi_eo_client_event_log::
  281 */
  282 /**
  283 **  This function logs client events during HttpInspect processing.
  284 **
  285 **  The idea behind this event logging is modularity, but at the same time
  286 **  performance.  We accomplish this utilizing an optimized stack as an
  287 **  index into the client event array, instead of walking a list for
  288 **  already logged events.  The problem here is that we can't just log
  289 **  every event that we've already seen, because this opens us up to a
  290 **  DOS.  So by using this method, we can quickly check if an event
  291 **  has already been logged and deal appropriately.
  292 **
  293 **  @param Session   pointer to the HttpInspect session
  294 **  @param iEvent    the event id for the client
  295 **  @param data      pointer to the user data of the event
  296 **  @param free_data pointer to a function to free the user data
  297 **
  298 **  @return integer
  299 **
  300 **  @retval HI_SUCCESS function successful
  301 **  @retval HI_INVALID_ARG invalid arguments
  302 */
  303 int hi_eo_client_event_log(HI_SESSION *Session, int iEvent, void *data,
  304         void (*free_data)(void *))
  305 {
  306     HI_CLIENT_EVENTS *client_events;
  307     HI_EVENT *event;
  308     int iCtr;
  309 
  310     /*
  311     **  Check the input variables for correctness
  312     */
  313     if(!Session || (iEvent >= HI_EO_CLIENT_EVENT_NUM))
  314     {
  315         return HI_INVALID_ARG;
  316     }
  317 
  318     client_events = &(Session->client.event_list);
  319 
  320     /*
  321     **  This is where we cycle through the current event stack.  If the event
  322     **  to be logged is already in the queue, then we increment the event
  323     **  count, before returning.  Otherwise, we fall through the loop and
  324     **  set the event before adding it to the queue and incrementing the
  325     **  pointer.
  326     */
  327     for(iCtr = 0; iCtr < client_events->stack_count; iCtr++)
  328     {
  329         if(client_events->stack[iCtr] == iEvent)
  330         {
  331             client_events->events[iEvent].count++;
  332             return HI_SUCCESS;
  333         }
  334     }
  335 
  336     /*
  337     **  Initialize the event before putting it in the queue.
  338     */
  339     event = &(client_events->events[iEvent]);
  340     event->event_info = &client_event_info[iEvent];
  341     event->count = 1;
  342     event->data = data;
  343     event->free_data = free_data;
  344 
  345     /*
  346     **  We now add the event to the stack.
  347     */
  348     client_events->stack[client_events->stack_count] = iEvent;
  349     client_events->stack_count++;
  350 
  351     return HI_SUCCESS;
  352 }
  353 
  354 /*
  355 **  NAME
  356 **    hi_eo_server_event_log::
  357 */
  358 /**
  359 **  This function logs server events during HttpInspect processing.
  360 **
  361 **  The idea behind this event logging is modularity, but at the same time
  362 **  performance.  We accomplish this utilizing an optimized stack as an
  363 **  index into the server event array, instead of walking a list for
  364 **  already logged events.  The problem here is that we can't just log
  365 **  every event that we've already seen, because this opens us up to a
  366 **  DOS.  So by using this method, we can quickly check if an event
  367 **  has already been logged and deal appropriately.
  368 **
  369 **  @param Session   pointer to the HttpInspect session
  370 **  @param iEvent    the event id for the server
  371 **  @param data      pointer to the user data of the event
  372 **  @param free_data pointer to a function to free the user data
  373 **
  374 **  @return integer
  375 **
  376 **  @retval HI_SUCCESS function successful
  377 **  @retval HI_INVALID_ARG invalid arguments
  378 */
  379 int hi_eo_server_event_log(HI_SESSION *Session, int iEvent, void *data,
  380         void (*free_data)(void *))
  381 {
  382     HI_SERVER_EVENTS *server_events;
  383     HI_EVENT *event;
  384     int iCtr;
  385 
  386     /*
  387     **  Check the input variables for correctness
  388     */
  389     if(!Session || (iEvent >= HI_EO_SERVER_EVENT_NUM))
  390     {
  391         return HI_INVALID_ARG;
  392     }
  393 
  394     server_events = &(Session->server.event_list);
  395 
  396     /*
  397     **  This is where we cycle through the current event stack.  If the event
  398     **  to be logged is already in the queue, then we increment the event
  399     **  count, before returning.  Otherwise, we fall through the loop and
  400     **  set the event before adding it to the queue and incrementing the
  401     **  pointer.
  402     */
  403     for(iCtr = 0; iCtr < server_events->stack_count; iCtr++)
  404     {
  405         if(server_events->stack[iCtr] == iEvent)
  406         {
  407             server_events->events[iEvent].count++;
  408             return HI_SUCCESS;
  409         }
  410     }
  411 
  412     /*
  413     **  Initialize the event before putting it in the queue.
  414     */
  415     event = &(server_events->events[iEvent]);
  416     event->event_info = &server_event_info[iEvent];
  417     event->count = 1;
  418     event->data = data;
  419     event->free_data = free_data;
  420 
  421     /*
  422     **  We now add the event to the stack.
  423     */
  424     server_events->stack[server_events->stack_count] = iEvent;
  425     server_events->stack_count++;
  426 
  427     return HI_SUCCESS;
  428 }