"Fossies" - the Fresh Open Source Software Archive

Member "snort-2.9.17/src/preprocessors/spp_httpinspect.c" (16 Oct 2020, 81030 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 "spp_httpinspect.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       preproc_setup.c
   25 **
   26 **  @author     Daniel Roelker <droelker@sourcefire.com>
   27 **
   28 **  @brief      This file initializes HttpInspect as a Snort
   29 **              preprocessor.
   30 **
   31 **  This file registers the HttpInspect initialization function,
   32 **  adds the HttpInspect function into the preprocessor list, reads
   33 **  the user configuration in the snort.conf file, and prints out
   34 **  the configuration that is read.
   35 **
   36 **  In general, this file is a wrapper to HttpInspect functionality,
   37 **  by interfacing with the Snort preprocessor functions.  The rest
   38 **  of HttpInspect should be separate from the preprocessor hooks.
   39 **
   40 **  NOTES
   41 **
   42 **  - 2.10.03:  Initial Development.  DJR
   43 */
   44 
   45 #include <assert.h>
   46 #include <string.h>
   47 #include <sys/types.h>
   48 
   49 #ifdef HAVE_CONFIG_H
   50 #include "config.h"
   51 #endif
   52 
   53 #include "decode.h"
   54 #include "plugbase.h"
   55 #include "snort_debug.h"
   56 #include "util.h"
   57 #include "parser.h"
   58 
   59 #include "hi_ui_config.h"
   60 #include "hi_ui_server_lookup.h"
   61 #include "hi_client.h"
   62 #include "hi_norm.h"
   63 #include "snort_httpinspect.h"
   64 #include "hi_util_kmap.h"
   65 #include "hi_util_xmalloc.h"
   66 #include "hi_cmd_lookup.h"
   67 #include "hi_paf.h"
   68 #include "h2_paf.h"
   69 
   70 #ifdef DUMP_BUFFER
   71 #include "hi_buffer_dump.h"
   72 #endif
   73 
   74 #include "file_decomp.h"
   75 
   76 #include "snort.h"
   77 #include "profiler.h"
   78 #include "mstring.h"
   79 #include "sp_preprocopt.h"
   80 #include "detection_util.h"
   81 
   82 #ifdef TARGET_BASED
   83 #include "session_api.h"
   84 #include "stream_api.h"
   85 #include "sftarget_protocol_reference.h"
   86 #endif
   87 
   88 #include "sfPolicy.h"
   89 #include "mempool.h"
   90 #include "file_api.h"
   91 #include "sf_email_attach_decode.h"
   92 
   93 #ifdef SNORT_RELOAD
   94 #include "reload.h"
   95 #include "file_mime_process.h"
   96 #ifdef REG_TEST
   97 #include "reg_test.h"
   98 #endif
   99 #endif
  100 
  101 #if defined(FEAT_OPEN_APPID)
  102 #include "spp_stream6.h"
  103 #endif /* defined(FEAT_OPEN_APPID) */
  104 
  105 /*
  106 **  Defines for preprocessor initialization
  107 */
  108 /**
  109 **  snort.conf preprocessor keyword
  110 */
  111 #define GLOBAL_KEYWORD   "http_inspect"
  112 #define SERVER_KEYWORD   "http_inspect_server"
  113 
  114 const char *PROTOCOL_NAME = "HTTP";
  115 
  116 /**
  117 **  The length of the error string buffer.
  118 */
  119 #define ERRSTRLEN 1000
  120 
  121 /*
  122 **  External Global Variables
  123 **  Variables that we need from Snort to log errors correctly and such.
  124 */
  125 extern char *file_name;
  126 extern int file_line;
  127 
  128 /*
  129 **  Global Variables
  130 **  This is the only way to work with Snort preprocessors because
  131 **  the user configuration must be kept between the Init function
  132 **  the actual preprocessor.  There is no interaction between the
  133 **  two except through global variable usage.
  134 */
  135 tSfPolicyUserContextId hi_config = NULL;
  136 
  137 #ifdef TARGET_BASED
  138 /* Store the protocol id received from the stream reassembler */
  139 int16_t hi_app_protocol_id;
  140 int16_t h2_app_protocol_id;
  141 #endif
  142 
  143 #ifdef PERF_PROFILING
  144 PreprocStats hiPerfStats;
  145 PreprocStats hi2PerfStats;
  146 PreprocStats hi2InitPerfStats;
  147 PreprocStats hi2PayloadPerfStats;
  148 PreprocStats hi2PseudoPerfStats;
  149 PreprocStats hiDetectPerfStats;
  150 int hiDetectCalled = 0;
  151 #endif
  152 
  153 static tSfPolicyId httpCurrentPolicy = 0;
  154 
  155 MemPool *hi_gzip_mempool = NULL;
  156 fd_config_t hi_fd_conf;
  157 uint8_t decompression_buffer[65535];
  158 
  159 uint8_t dechunk_buffer[65535];
  160 
  161 MemPool *http_mempool = NULL;
  162 MemPool *mime_decode_mempool = NULL;
  163 MemPool *mime_log_mempool = NULL;
  164 int hex_lookup[256];
  165 int valid_lookup[256];
  166 
  167 char** xffFields = NULL;
  168 static char** oldXffFields = NULL;
  169 
  170 /*
  171 ** Prototypes
  172 */
  173 static void HttpInspectDropStats(int);
  174 static void HttpInspect(Packet *, void *);
  175 static void HttpInspectCleanExit(int, void *);
  176 static void HttpInspectReset(int, void *);
  177 static void HttpInspectResetStats(int, void *);
  178 static void HttpInspectInit(struct _SnortConfig *, char *);
  179 static void addServerConfPortsToStream(struct _SnortConfig *sc, void *);
  180 static void HttpInspectFreeConfigs(tSfPolicyUserContextId);
  181 static void HttpInspectFreeConfig(HTTPINSPECT_GLOBAL_CONF *);
  182 static int HttpInspectCheckConfig(struct _SnortConfig *);
  183 static void HttpInspectAddPortsOfInterest(struct _SnortConfig *, HTTPINSPECT_GLOBAL_CONF *, tSfPolicyId);
  184 static int HttpEncodeInit(struct _SnortConfig *, char *, char *, void **);
  185 static int HttpEncodeEval(void *, const uint8_t **, void *);
  186 static void HttpEncodeCleanup(void *);
  187 static void HttpInspectRegisterRuleOptions(struct _SnortConfig *);
  188 static void HttpInspectRegisterXtraDataFuncs(HTTPINSPECT_GLOBAL_CONF *);
  189 static inline void InitLookupTables(void);
  190 #ifdef TARGET_BASED
  191 static void HttpInspectAddServicesOfInterest(struct _SnortConfig *, HTTPINSPECT_GLOBAL_CONF *, tSfPolicyId);
  192 #endif
  193 
  194 #ifdef SNORT_RELOAD
  195 static int HttpMempoolFreeUsedBucket(MemPool *memory_pool);
  196 static unsigned HttpMempoolAdjust(MemPool *memory_pool, unsigned httpMaxWork);
  197 static bool HttpGzipReloadAdjust(bool idle, tSfPolicyId raPolicyId, void* userData);
  198 static bool HttpFdReloadAdjust(bool idle, tSfPolicyId raPolicyId, void* userData);
  199 static bool HttpMempoolReloadAdjust(bool idle, tSfPolicyId raPolicyId, void* userData);
  200 static bool HttpMimeReloadAdjust(bool idle, tSfPolicyId raPolicyId, void* userData);
  201 static bool HttpLogReloadAdjust(bool idle, tSfPolicyId raPolicyId, void* userData);
  202 #ifdef REG_TEST
  203 static void display_http_mempool(MemPool *mempool, const char* old_new, const char *pool_type);
  204 static int HttpInspectUnlimitedDecompressIterate(void *data);
  205 static int HttpInspectUnlimitedDecompress(struct _SnortConfig *sc, tSfPolicyUserContextId config, tSfPolicyId policyId, void *pData);
  206 static void display_gzip_fd_config_changes(HTTPINSPECT_GLOBAL_CONF* configOld, HTTPINSPECT_GLOBAL_CONF* configNew,
  207                                            bool old_gzip, bool new_gzip, bool old_fd, bool new_fd, bool old_ud, bool new_ud);
  208 #endif
  209 static void update_gzip_mempool(bool old_gzip, bool new_gzip, uint32_t max_sessions);
  210 static void update_fd_mempool(bool old_fd, bool new_fd, uint32_t max_sessions);
  211 static void update_gzip_fd_mempools(HTTPINSPECT_GLOBAL_CONF* configNew, bool old_gzip, bool new_gzip, bool old_fd, bool new_fd);
  212 static void update_http_mempool(uint32_t new_memcap, uint32_t old_memcap);
  213 static void HttpInspectReloadGlobal(struct _SnortConfig *, char *, void **);
  214 static void HttpInspectReload(struct _SnortConfig *, char *, void **);
  215 static int HttpInspectReloadVerify(struct _SnortConfig *, void *);
  216 static void * HttpInspectReloadSwap(struct _SnortConfig *, void *);
  217 static void HttpInspectReloadSwapFree(void *);
  218 #endif
  219 
  220 
  221 /*
  222 **  NAME
  223 **    HttpInspect::
  224 */
  225 /**
  226 **  This function wraps the functionality in the generic HttpInspect
  227 **  processing.  We get a Packet structure and pass this into the
  228 **  HttpInspect module where the first stage in HttpInspect is the
  229 **  Session Inspection stage where most of the other Snortisms are
  230 **  taken care of.  After that, the modules should be fairly generic,
  231 **  and that's what we're trying to do here.
  232 **
  233 **  @param p a Packet structure that contains Snort info about the
  234 **  packet.
  235 **
  236 **  @return void
  237 */
  238 static void HttpInspect(Packet *p, void *context)
  239 {
  240     tSfPolicyId policy_id = getNapRuntimePolicy();
  241     HTTPINSPECT_GLOBAL_CONF *pPolicyConfig = NULL ;
  242     PROFILE_VARS;
  243     sfPolicyUserPolicySet (hi_config, policy_id);
  244     pPolicyConfig = (HTTPINSPECT_GLOBAL_CONF *)sfPolicyUserDataGetCurrent(hi_config);
  245 
  246     if ( pPolicyConfig == NULL)
  247         return;
  248 
  249     // preconditions - what we registered for
  250     assert(IsTCP(p) && p->dsize && p->data);
  251 
  252     PREPROC_PROFILE_START(hiPerfStats);
  253 
  254     /*
  255     **  Pass in the configuration and the packet.
  256     */
  257     SnortHttpInspect(pPolicyConfig, p);
  258 
  259     ClearHttpBuffers();
  260 
  261     /* XXX:
  262      * NOTE: this includes the HTTPInspect directly
  263      * calling the detection engine -
  264      * to get the true HTTPInspect only stats, have another
  265      * var inside SnortHttpInspect that tracks the time
  266      * spent in Detect().
  267      * Subtract the ticks from this if iCallDetect == 0
  268      */
  269     PREPROC_PROFILE_END(hiPerfStats);
  270 #ifdef PERF_PROFILING
  271     if (hiDetectCalled)
  272     {
  273         hiPerfStats.ticks -= hiDetectPerfStats.ticks;
  274         /* And Reset ticks to 0 */
  275         hiDetectPerfStats.ticks = 0;
  276         hiDetectCalled = 0;
  277     }
  278 #endif
  279 
  280     return;
  281 }
  282 
  283 static void HttpInspectDropStats(int exiting)
  284 {
  285     if(!hi_stats.total)
  286         return;
  287 
  288     LogMessage("HTTP Inspect - encodings (Note: stream-reassembled "
  289                "packets included):\n");
  290 
  291 #ifdef WIN32
  292     LogMessage("    POST methods:                         %-10I64u\n", hi_stats.post);
  293     LogMessage("    GET methods:                          %-10I64u\n", hi_stats.get);
  294     LogMessage("    HTTP Request Headers extracted:       %-10I64u\n", hi_stats.req_headers);
  295 #ifdef DEBUG
  296     if (hi_stats.req_headers == 0)
  297     LogMessage("    Avg Request Header length:            %-10s\n", "n/a");
  298     else
  299     LogMessage("    Avg Request Header length:            %-10.2f\n", (double)hi_stats.req_header_len / (double)hi_stats.req_headers);
  300 #endif
  301     LogMessage("    HTTP Request cookies extracted:       %-10I64u\n", hi_stats.req_cookies);
  302 #ifdef DEBUG
  303     if (hi_stats.req_cookies == 0)
  304     LogMessage("    Avg Request Cookie length:            %-10s\n", "n/a");
  305     else
  306     LogMessage("    Avg Request Cookie length:            %-10.2f\n", (double)hi_stats.req_cookie_len / (double)hi_stats.req_cookies);
  307 #endif
  308     LogMessage("    Post parameters extracted:            %-10I64u\n", hi_stats.post_params);
  309     LogMessage("    HTTP Response Headers extracted:      %-10I64u\n", hi_stats.resp_headers);
  310 #ifdef DEBUG
  311     if (hi_stats.resp_headers == 0)
  312     LogMessage("    Avg Response Header length:           %-10s\n", "n/a");
  313     else
  314     LogMessage("    Avg Response Header length:           %-10.2f\n", (double)hi_stats.resp_header_len / (double)hi_stats.resp_headers);
  315 #endif
  316     LogMessage("    HTTP Response cookies extracted:      %-10I64u\n", hi_stats.resp_cookies);
  317 #ifdef DEBUG
  318     if (hi_stats.resp_cookies == 0)
  319     LogMessage("    Avg Response Cookie length:           %-10s\n", "n/a");
  320     else
  321     LogMessage("    Avg Response Cookie length:           %-10.2f\n", (double)hi_stats.resp_cookie_len / (double)hi_stats.resp_cookies);
  322 #endif
  323     LogMessage("    Unicode:                              %-10I64u\n", hi_stats.unicode);
  324     LogMessage("    Double unicode:                       %-10I64u\n", hi_stats.double_unicode);
  325     LogMessage("    Non-ASCII representable:              %-10I64u\n", hi_stats.non_ascii);
  326     LogMessage("    Directory traversals:                 %-10I64u\n", hi_stats.dir_trav);
  327     LogMessage("    Extra slashes (\"//\"):                 %-10I64u\n", hi_stats.slashes);
  328     LogMessage("    Self-referencing paths (\"./\"):        %-10I64u\n", hi_stats.self_ref);
  329     LogMessage("    HTTP Response Gzip packets extracted: %-10I64u\n", hi_stats.gzip_pkts);
  330     if (hi_stats.gzip_pkts == 0)
  331     {
  332     LogMessage("    Gzip Compressed Data Processed:       %-10s\n", "n/a");
  333     LogMessage("    Gzip Decompressed Data Processed:     %-10s\n", "n/a");
  334     }
  335     else
  336     {
  337     LogMessage("    Gzip Compressed Data Processed:       %-10.2f\n", (double)hi_stats.compr_bytes_read);
  338     LogMessage("    Gzip Decompressed Data Processed:     %-10.2f\n", (double)hi_stats.decompr_bytes_read);
  339     }
  340     LogMessage("    Http/2 Rebuilt Packets:               %-10I64u\n", hi_stats.h2_rebuilt_packets);
  341     LogMessage("    Total packets processed:              %-10I64u\n", hi_stats.total);
  342     LogMessage("    Non-mempool session memory:           %-10I64u\n", hi_stats.mem_used + 
  343                                                        (hi_paf_get_size() * hi_stats.session_count));
  344     LogMessage("    http_mempool used:                    %-10I64u\n",
  345                                                        http_mempool ? http_mempool->used_memory:0);
  346     LogMessage("    hi_gzip_mempool used:                    %-10I64u\n",
  347                                                        hi_gzip_mempool ? hi_gzip_mempool->used_memory:0);
  348     LogMessage("    mime_decode_mempool used:                    %-10I64u\n",
  349                                                        mime_decode_mempool ? mime_decode_mempool->used_memory:0);
  350     LogMessage("    mime_log_mempool used:                    %-10I64u\n",
  351                                                        mime_log_mempool ? mime_log_mempool->used_memory:0);
  352     LogMessage("    Current active session:               %-10I64u\n", hi_stats.session_count);
  353 #else
  354     LogMessage("    POST methods:                         "FMTu64("-10")"\n", hi_stats.post);
  355     LogMessage("    GET methods:                          "FMTu64("-10")"\n", hi_stats.get);
  356     LogMessage("    HTTP Request Headers extracted:       "FMTu64("-10")"\n", hi_stats.req_headers);
  357 #ifdef DEBUG
  358     if (hi_stats.req_headers == 0)
  359     LogMessage("    Avg Request Header length:            %-10s\n", "n/a");
  360     else
  361     LogMessage("    Avg Request Header length:            %-10.2f\n", (double)hi_stats.req_header_len / (double)hi_stats.req_headers);
  362 #endif
  363     LogMessage("    HTTP Request Cookies extracted:       "FMTu64("-10")"\n", hi_stats.req_cookies);
  364 #ifdef DEBUG
  365     if (hi_stats.req_cookies == 0)
  366     LogMessage("    Avg Request Cookie length:            %-10s\n", "n/a");
  367     else
  368     LogMessage("    Avg Request Cookie length:            %-10.2f\n", (double)hi_stats.req_cookie_len / (double)hi_stats.req_cookies);
  369 #endif
  370     LogMessage("    Post parameters extracted:            "FMTu64("-10")"\n", hi_stats.post_params);
  371     LogMessage("    HTTP response Headers extracted:      "FMTu64("-10")"\n", hi_stats.resp_headers);
  372 #ifdef DEBUG
  373     if (hi_stats.resp_headers == 0)
  374     LogMessage("    HTTP response Avg Header length:      %-10s\n", "n/a");
  375     else
  376     LogMessage("    Avg Response Header length:           %-10.2f\n", (double)hi_stats.resp_header_len / (double)hi_stats.resp_headers);
  377 #endif
  378     LogMessage("    HTTP Response Cookies extracted:      "FMTu64("-10")"\n", hi_stats.resp_cookies);
  379 #ifdef DEBUG
  380     if (hi_stats.resp_cookies == 0)
  381     LogMessage("    Avg Response Cookie length:           %-10s\n", "n/a");
  382     else
  383     LogMessage("    Avg Response Cookie length:           %-10.2f\n", (double)hi_stats.resp_cookie_len / (double)hi_stats.resp_cookies);
  384 #endif
  385     LogMessage("    Unicode:                              "FMTu64("-10")"\n", hi_stats.unicode);
  386     LogMessage("    Double unicode:                       "FMTu64("-10")"\n", hi_stats.double_unicode);
  387     LogMessage("    Non-ASCII representable:              "FMTu64("-10")"\n", hi_stats.non_ascii);
  388     LogMessage("    Directory traversals:                 "FMTu64("-10")"\n", hi_stats.dir_trav);
  389     LogMessage("    Extra slashes (\"//\"):                 "FMTu64("-10")"\n", hi_stats.slashes);
  390     LogMessage("    Self-referencing paths (\"./\"):        "FMTu64("-10")"\n", hi_stats.self_ref);
  391     LogMessage("    HTTP Response Gzip packets extracted: "FMTu64("-10")"\n", hi_stats.gzip_pkts);
  392     if (hi_stats.gzip_pkts == 0)
  393     {
  394     LogMessage("    Gzip Compressed Data Processed:       %-10s\n", "n/a");
  395     LogMessage("    Gzip Decompressed Data Processed:     %-10s\n", "n/a");
  396     }
  397     else
  398     {
  399     LogMessage("    Gzip Compressed Data Processed:       %-10.2f\n", (double)hi_stats.compr_bytes_read);
  400     LogMessage("    Gzip Decompressed Data Processed:     %-10.2f\n", (double)hi_stats.decompr_bytes_read);
  401     }
  402     LogMessage("    Http/2 Rebuilt Packets:               "FMTu64("-10")"\n", hi_stats.h2_rebuilt_packets);
  403     LogMessage("    Total packets processed:              "FMTu64("-10")"\n", hi_stats.total);
  404     LogMessage("    Non-mempool session memory:           "FMTu64("-10")"\n", hi_stats.mem_used + 
  405                                                        (hi_paf_get_size() * hi_stats.session_count));
  406     LogMessage("    http_mempool used:                    "FMTu64("-10")"\n",
  407                                                        http_mempool ? http_mempool->used_memory:0);
  408     LogMessage("    hi_gzip_mempool used:                 "FMTu64("-10")"\n",
  409                                                        hi_gzip_mempool ? hi_gzip_mempool->used_memory:0);
  410     LogMessage("    mime_decode_mempool used:             "FMTu64("-10")"\n",
  411                                                        mime_decode_mempool ? mime_decode_mempool->used_memory:0);
  412     LogMessage("    mime_log_mempool used:                "FMTu64("-10")"\n",
  413                                                        mime_log_mempool ? mime_log_mempool->used_memory:0);
  414     LogMessage("    Current active session:               "FMTu64("-10")"\n", hi_stats.session_count);
  415 #endif
  416 }
  417 
  418 static void HttpInspectCleanExit(int signal, void *data)
  419 {
  420     (void)File_Decomp_CleanExit();
  421 
  422     hi_paf_term();
  423 
  424     HI_SearchFree();
  425 
  426     oldXffFields = xffFields;
  427     HttpInspectFreeConfigs(hi_config);
  428 
  429     if (mempool_destroy(hi_gzip_mempool) == 0)
  430     {
  431         free(hi_gzip_mempool);
  432         hi_gzip_mempool = NULL;
  433     }
  434 
  435     if (mempool_destroy(http_mempool) == 0)
  436     {
  437         free(http_mempool);
  438         http_mempool = NULL;
  439     }
  440     if (mempool_destroy(mime_decode_mempool) == 0)
  441     {
  442         free(mime_decode_mempool);
  443         mime_decode_mempool = NULL;
  444     }
  445     if (mempool_destroy(mime_log_mempool) == 0)
  446     {
  447         free(mime_log_mempool);
  448         mime_log_mempool = NULL;
  449     }
  450 }
  451 
  452 static void HttpInspectReset(int signal, void *data)
  453 {
  454     return;
  455 }
  456 
  457 static void HttpInspectResetStats(int signal, void *data)
  458 {
  459     memset(&hi_stats, 0, sizeof(hi_stats));
  460 }
  461 
  462 static void CheckGzipConfig(HTTPINSPECT_GLOBAL_CONF *pPolicyConfig,
  463         tSfPolicyUserContextId context)
  464 {
  465     HTTPINSPECT_GLOBAL_CONF *defaultConfig =
  466         (HTTPINSPECT_GLOBAL_CONF *)sfPolicyUserDataGetDefault(context);
  467 
  468     if (pPolicyConfig == defaultConfig)
  469     {
  470         if (!pPolicyConfig->max_gzip_mem)
  471             pPolicyConfig->max_gzip_mem = DEFAULT_MAX_GZIP_MEM;
  472 
  473         if (!pPolicyConfig->compr_depth)
  474             pPolicyConfig->compr_depth = DEFAULT_COMP_DEPTH;
  475 
  476         if (!pPolicyConfig->decompr_depth)
  477             pPolicyConfig->decompr_depth = DEFAULT_DECOMP_DEPTH;
  478 
  479         /* Until we determine exact usage of extract_gzip and file_decomp options
  480            we will set the max_gzip_sessions to the minimal/conservative value. */
  481         pPolicyConfig->max_gzip_sessions = pPolicyConfig->max_gzip_mem /
  482                               (sizeof(DECOMPRESS_STATE) + sizeof(fd_session_t));
  483     }
  484     else if (defaultConfig == NULL)
  485     {
  486         if (pPolicyConfig->max_gzip_mem)
  487         {
  488             FatalError("http_inspect: max_gzip_mem must be "
  489                     "configured in the default policy.\n");
  490         }
  491 
  492         if (pPolicyConfig->compr_depth)
  493         {
  494             FatalError("http_inspect: compress_depth must be "
  495                     "configured in the default policy.\n");
  496         }
  497 
  498         if (pPolicyConfig->decompr_depth)
  499         {
  500             FatalError("http_inspect: decompress_depth must be "
  501                     "configured in the default policy.\n");
  502         }
  503     }
  504     else
  505     {
  506         pPolicyConfig->max_gzip_mem = defaultConfig->max_gzip_mem;
  507         pPolicyConfig->compr_depth = defaultConfig->compr_depth;
  508         pPolicyConfig->decompr_depth = defaultConfig->decompr_depth;
  509         pPolicyConfig->max_gzip_sessions = defaultConfig->max_gzip_sessions;
  510     }
  511 }
  512 
  513 
  514 static void CheckMemcap(HTTPINSPECT_GLOBAL_CONF *pPolicyConfig,
  515         tSfPolicyUserContextId context)
  516 {
  517     HTTPINSPECT_GLOBAL_CONF *defaultConfig =
  518         (HTTPINSPECT_GLOBAL_CONF *)sfPolicyUserDataGetDefault(context);
  519 
  520     if (pPolicyConfig == defaultConfig)
  521     {
  522         if (!pPolicyConfig->memcap)
  523             pPolicyConfig->memcap = DEFAULT_HTTP_MEMCAP;
  524 
  525     }
  526     else if (defaultConfig == NULL)
  527     {
  528         if (pPolicyConfig->memcap)
  529         {
  530             FatalError("http_inspect: memcap must be "
  531                     "configured in the default policy.\n");
  532         }
  533 
  534     }
  535     else
  536     {
  537         pPolicyConfig->memcap = defaultConfig->memcap;
  538     }
  539 }
  540 
  541 #ifdef REG_TEST
  542 static inline void PrintHTTPSize(void)
  543 {
  544     LogMessage("\nHTTP Session Size: %lu\n", (long unsigned int)sizeof(HttpSessionData));
  545 }
  546 #endif
  547 
  548 /*
  549  **  NAME
  550  **    HttpInspectInit::
  551 */
  552 /**
  553 **  This function initializes HttpInspect with a user configuration.
  554 **
  555 **  The function is called when HttpInspect is configured in
  556 **  snort.conf.  It gets passed a string of arguments, which gets
  557 **  parsed into configuration constructs that HttpInspect understands.
  558 **
  559 **  This function gets called for every HttpInspect configure line.  We
  560 **  use this characteristic to split up the configuration, so each line
  561 **  is a configuration construct.  We need to keep track of what part
  562 **  of the configuration has been configured, so we don't configure one
  563 **  part, then configure it again.
  564 **
  565 **  Any upfront memory is allocated here (if necessary).
  566 **
  567 **  @param args a string to the preprocessor arguments.
  568 **
  569 **  @return void
  570 */
  571 static void HttpInspectInit(struct _SnortConfig *sc, char *args)
  572 {
  573     char ErrorString[ERRSTRLEN];
  574     int  iErrStrLen = ERRSTRLEN;
  575     int  iRet;
  576     char *pcToken;
  577     char *saveptr;
  578     HTTPINSPECT_GLOBAL_CONF *pPolicyConfig = NULL;
  579     tSfPolicyId policy_id = getParserPolicy(sc);
  580 
  581     ErrorString[0] = '\0';
  582 
  583 #ifdef REG_TEST
  584     PrintHTTPSize();
  585 #endif
  586 
  587     if ((args == NULL) || (strlen(args) == 0))
  588         ParseError("No arguments to HttpInspect configuration.");
  589 
  590     /* Find out what is getting configured */
  591     pcToken = strtok_r(args, CONF_SEPARATORS, &saveptr);
  592     if (pcToken == NULL)
  593     {
  594         FatalError("%s(%d)strtok returned NULL when it should not.",
  595                    __FILE__, __LINE__);
  596     }
  597 
  598     if (!xffFields)
  599     {
  600         if ((xffFields = calloc(1, HTTP_MAX_XFF_FIELDS * sizeof(char *))) == NULL)
  601         {
  602             FatalError("http_inspect: %s(%d) failed to allocate memory for XFF fields\n", 
  603                        __FILE__, __LINE__);
  604         }
  605     }
  606 
  607     if (hi_config == NULL)
  608     {
  609         hi_config = sfPolicyConfigCreate();
  610         memset(&hi_stats, 0, sizeof(HIStats));
  611 
  612         /*
  613          **  Remember to add any cleanup functions into the appropriate
  614          **  lists.
  615          */
  616         AddFuncToPreprocCleanExitList(HttpInspectCleanExit, NULL, PRIORITY_APPLICATION, PP_HTTPINSPECT);
  617         AddFuncToPreprocResetList(HttpInspectReset, NULL, PRIORITY_APPLICATION, PP_HTTPINSPECT);
  618         AddFuncToPreprocResetStatsList(HttpInspectResetStats, NULL, PRIORITY_APPLICATION, PP_HTTPINSPECT);
  619         AddFuncToConfigCheckList(sc, HttpInspectCheckConfig);
  620 
  621         RegisterPreprocStats("http_inspect", HttpInspectDropStats);
  622 
  623 #ifdef PERF_PROFILING
  624         RegisterPreprocessorProfile("httpinspect", &hiPerfStats, 0, &totalPerfStats, NULL);
  625         RegisterPreprocessorProfile("http2inspect", &hi2PerfStats, 0, &totalPerfStats, NULL);
  626         RegisterPreprocessorProfile("h2_init", &hi2InitPerfStats, 1, &hi2PerfStats, NULL);
  627         RegisterPreprocessorProfile("h2_payload", &hi2PayloadPerfStats, 1, &hi2PerfStats, NULL);
  628         RegisterPreprocessorProfile("h2_pseudo", &hi2PseudoPerfStats, 1, &hi2PerfStats, NULL);
  629 #endif
  630 
  631 #ifdef TARGET_BASED
  632         /* Find and cache protocol ID for packet comparison */
  633         hi_app_protocol_id = AddProtocolReference("http");
  634         h2_app_protocol_id = AddProtocolReference("http2");
  635         // register with session to handle applications
  636         session_api->register_service_handler( PP_HTTPINSPECT, hi_app_protocol_id );
  637         session_api->register_service_handler( PP_HTTPINSPECT, h2_app_protocol_id);
  638 
  639 #endif
  640         hi_paf_init(0);  // FIXTHIS is cap needed?
  641         HI_SearchInit();
  642     }
  643 
  644     /*
  645     **  Global Configuration Processing
  646     **  We only process the global configuration once, but always check for
  647     **  user mistakes, like configuring more than once.  That's why we
  648     **  still check for the global token even if it's been checked.
  649     **  Force the first configuration to be the global one.
  650     */
  651     sfPolicyUserPolicySet (hi_config, policy_id);
  652     pPolicyConfig = (HTTPINSPECT_GLOBAL_CONF *)sfPolicyUserDataGetCurrent(hi_config);
  653     if (pPolicyConfig == NULL)
  654     {
  655         if (strcasecmp(pcToken, GLOBAL) != 0)
  656         {
  657             ParseError("Must configure the http inspect global "
  658                        "configuration first.");
  659         }
  660 
  661         HttpInspectRegisterRuleOptions(sc);
  662 
  663         pPolicyConfig = (HTTPINSPECT_GLOBAL_CONF *)SnortAlloc(sizeof(HTTPINSPECT_GLOBAL_CONF));
  664         if (!pPolicyConfig)
  665         {
  666              ParseError("HTTP INSPECT preprocessor: memory allocate failed.\n");
  667         }
  668 
  669         sfPolicyUserDataSetCurrent(hi_config, pPolicyConfig);
  670 
  671         iRet = HttpInspectInitializeGlobalConfig(pPolicyConfig,
  672                                                  ErrorString, iErrStrLen);
  673         if (iRet == 0)
  674         {
  675             iRet = ProcessGlobalConf(pPolicyConfig, ErrorString, iErrStrLen, &saveptr);
  676 
  677             if (iRet == 0)
  678             {
  679                 CheckGzipConfig(pPolicyConfig, hi_config);
  680                 CheckMemcap(pPolicyConfig, hi_config);
  681                 PrintGlobalConf(pPolicyConfig);
  682 
  683                 /* Add HttpInspect into the preprocessor list */
  684                 if ( pPolicyConfig->disabled )
  685                     return;
  686                 AddFuncToPreprocList(sc, HttpInspect, PRIORITY_APPLICATION, PP_HTTPINSPECT, PROTO_BIT__TCP);
  687             }
  688         }
  689     }
  690     else
  691     {
  692         if (strcasecmp(pcToken, SERVER) != 0)
  693         {
  694             if (strcasecmp(pcToken, GLOBAL) != 0)
  695                 ParseError("Must configure the http inspect global configuration first.");
  696             else
  697                 ParseError("Invalid http inspect token: %s.", pcToken);
  698         }
  699 
  700         iRet = ProcessUniqueServerConf(sc, pPolicyConfig, ErrorString, iErrStrLen, &saveptr);
  701     }
  702 
  703 
  704 
  705     if (iRet)
  706     {
  707         if(iRet > 0)
  708         {
  709             /*
  710             **  Non-fatal Error
  711             */
  712             if(*ErrorString)
  713             {
  714                 ErrorMessage("%s(%d) => %s\n",
  715                         file_name, file_line, ErrorString);
  716             }
  717         }
  718         else
  719         {
  720             /*
  721             **  Fatal Error, log error and exit.
  722             */
  723             if(*ErrorString)
  724             {
  725                 FatalError("%s(%d) => %s\n",
  726                         file_name, file_line, ErrorString);
  727             }
  728             else
  729             {
  730                 /*
  731                 **  Check if ErrorString is undefined.
  732                 */
  733                 if(iRet == -2)
  734                 {
  735                     FatalError("%s(%d) => ErrorString is undefined.\n",
  736                             file_name, file_line);
  737                 }
  738                 else
  739                 {
  740                     FatalError("%s(%d) => Undefined Error.\n",
  741                             file_name, file_line);
  742                 }
  743             }
  744         }
  745     }
  746 
  747 }
  748 
  749 /*
  750 **  NAME
  751 **    SetupHttpInspect::
  752 */
  753 /**
  754 **  This function initializes HttpInspect as a Snort preprocessor.
  755 **
  756 **  It registers the preprocessor keyword for use in the snort.conf
  757 **  and sets up the initialization module for the preprocessor, in
  758 **  case it is configured.
  759 **
  760 **  This function must be called in InitPreprocessors() in plugbase.c
  761 **  in order to be recognized by Snort.
  762 **
  763 **  @param none
  764 **
  765 **  @return void
  766 */
  767 void SetupHttpInspect(void)
  768 {
  769 #ifndef SNORT_RELOAD
  770     RegisterPreprocessor(GLOBAL_KEYWORD, HttpInspectInit);
  771     RegisterPreprocessor(SERVER_KEYWORD, HttpInspectInit);
  772 #else
  773     RegisterPreprocessor(GLOBAL_KEYWORD, HttpInspectInit, HttpInspectReloadGlobal,
  774                          HttpInspectReloadVerify, HttpInspectReloadSwap,
  775                          HttpInspectReloadSwapFree);
  776     RegisterPreprocessor(SERVER_KEYWORD, HttpInspectInit,
  777                          HttpInspectReload, NULL, NULL, NULL);
  778 #endif
  779 #ifdef DUMP_BUFFER
  780     RegisterBufferTracer(getHTTPDumpBuffers, HTTP_BUFFER_DUMP_FUNC);
  781 #endif
  782     InitLookupTables();
  783     InitJSNormLookupTable();
  784     (void)File_Decomp_OneTimeInit();
  785 
  786     DEBUG_WRAP(DebugMessage(DEBUG_HTTPINSPECT, "Preprocessor: HttpInspect is "
  787                 "setup . . .\n"););
  788 }
  789 
  790 static void HttpInspectRegisterRuleOptions(struct _SnortConfig *sc)
  791 {
  792     RegisterPreprocessorRuleOption(sc, "http_encode", &HttpEncodeInit,
  793                                     &HttpEncodeEval, &HttpEncodeCleanup , NULL, NULL, NULL, NULL );
  794 }
  795 
  796 static void HttpInspectRegisterXtraDataFuncs(HTTPINSPECT_GLOBAL_CONF *pPolicyConfig)
  797 {
  798     if (!stream_api || !pPolicyConfig)
  799         return;
  800 
  801     pPolicyConfig->xtra_trueip_id = stream_api->reg_xtra_data_cb(GetHttpTrueIP);
  802     pPolicyConfig->xtra_uri_id = stream_api->reg_xtra_data_cb(GetHttpUriData);
  803     pPolicyConfig->xtra_hname_id = stream_api->reg_xtra_data_cb(GetHttpHostnameData);
  804 #ifndef SOURCEFIRE
  805     pPolicyConfig->xtra_gzip_id = stream_api->reg_xtra_data_cb(GetHttpGzipData);
  806     pPolicyConfig->xtra_jsnorm_id = stream_api->reg_xtra_data_cb(GetHttpJSNormData);
  807 #endif
  808 
  809 }
  810 
  811 static void updateConfigFromFileProcessing (struct _SnortConfig *sc, HTTPINSPECT_GLOBAL_CONF *pPolicyConfig)
  812 {
  813     HTTPINSPECT_CONF *ServerConf = pPolicyConfig->global_server;
  814     /*Either one is unlimited*/
  815     int64_t fileDepth = file_api->get_max_file_depth(sc, true);
  816 
  817     /*Config file policy*/
  818     if (fileDepth > -1)
  819     {
  820         ServerConf->inspect_response = 1;
  821         ServerConf->extract_gzip = 1;
  822         ServerConf->log_uri = 1;
  823         ServerConf->unlimited_decompress = 1;
  824         pPolicyConfig->mime_conf.log_filename = 1;
  825         ServerConf->file_policy = 1;
  826     }
  827 
  828     if (!fileDepth || (!ServerConf->server_flow_depth))
  829         ServerConf->server_extract_size = 0;
  830     else if (ServerConf->server_flow_depth > fileDepth)
  831         ServerConf->server_extract_size = ServerConf->server_flow_depth;
  832     else
  833         ServerConf->server_extract_size = fileDepth;
  834 
  835     if (!fileDepth || (!ServerConf->post_depth))
  836         ServerConf->post_extract_size = 0;
  837     else if (ServerConf->post_depth > fileDepth)
  838         ServerConf->post_extract_size = ServerConf->post_depth;
  839     else
  840         ServerConf->post_extract_size = fileDepth;
  841 
  842 }
  843 
  844 static int HttpInspectVerifyPolicy(struct _SnortConfig *sc, tSfPolicyUserContextId config,
  845         tSfPolicyId policyId, void* pData)
  846 {
  847     HTTPINSPECT_GLOBAL_CONF *pPolicyConfig = (HTTPINSPECT_GLOBAL_CONF *)pData;
  848 
  849     HttpInspectRegisterXtraDataFuncs(pPolicyConfig);
  850 
  851     if ( pPolicyConfig->disabled )
  852         return 0;
  853 
  854     if (!stream_api || (stream_api->version < STREAM_API_VERSION5))
  855     {
  856         ErrorMessage("HttpInspectConfigCheck() Streaming & reassembly "
  857                      "must be enabled\n");
  858         return -1;
  859     }
  860 
  861 
  862     if (pPolicyConfig->global_server == NULL)
  863     {
  864         ErrorMessage("HttpInspectConfigCheck() default server configuration "
  865                      "not specified\n");
  866         return -1;
  867     }
  868 
  869 #ifdef TARGET_BASED
  870     HttpInspectAddServicesOfInterest(sc, pPolicyConfig, policyId);
  871 #endif
  872     updateConfigFromFileProcessing(sc, pPolicyConfig);
  873     HttpInspectAddPortsOfInterest(sc, pPolicyConfig, policyId);
  874 #if defined(FEAT_OPEN_APPID)
  875     if (IsAnybodyRegisteredForHttpHeader())
  876     {
  877         pPolicyConfig->global_server->appid_enabled = 1;
  878     }
  879 #endif /* defined(FEAT_OPEN_APPID) */
  880     return 0;
  881 }
  882 
  883 
  884 /** Add ports configured for http preprocessor to stream5 port filtering so that if
  885  * any_any rules are being ignored them the the packet still reaches http-inspect.
  886  *
  887  * For ports in global_server configuration, server_lookup,
  888  * add the port to stream5 port filter list.
  889  */
  890 static void HttpInspectAddPortsOfInterest(struct _SnortConfig *sc, HTTPINSPECT_GLOBAL_CONF *config, tSfPolicyId policy_id)
  891 {
  892     if (config == NULL)
  893         return;
  894 
  895     httpCurrentPolicy = policy_id;
  896 
  897     addServerConfPortsToStream(sc, (void *)config->global_server);
  898     hi_ui_server_iterate(sc, config->server_lookup, addServerConfPortsToStream);
  899 }
  900 
  901 /**Add server ports from http_inspect preprocessor from snort.conf file to pass through
  902  * port filtering.
  903  */
  904 static void addServerConfPortsToStream(struct _SnortConfig *sc, void *pData)
  905 {
  906     unsigned int i;
  907 
  908     HTTPINSPECT_CONF *pConf = (HTTPINSPECT_CONF *)pData;
  909     if (pConf)
  910     {
  911         for (i = 0; i < MAXPORTS; i++)
  912         {
  913             if( isPortEnabled( pConf->ports, i ) )
  914             {
  915                 bool client = (pConf->client_flow_depth > -1);
  916                 bool server = (pConf->server_extract_size > -1);
  917                 int64_t fileDepth = file_api->get_max_file_depth(sc, true);
  918 
  919                 //Add port the port
  920                 stream_api->set_port_filter_status(sc, IPPROTO_TCP,
  921                                                    (uint16_t) i, 
  922                                                    PORT_MONITOR_SESSION,
  923                                                    httpCurrentPolicy, 
  924                                                    1);
  925 
  926                 // there is a fundamental issue here in that both hi and s5
  927                 // can configure ports per ip independently of each other.
  928                 // as is, we enable paf for all http servers if any server
  929                 // has a flow depth enabled (per direction).  still, if eg
  930                 // all server_flow_depths are -1, we will only enable client.
  931                 if (fileDepth > 0)
  932                 {
  933                     hi_paf_register_port(sc, (uint16_t)i, client, server, httpCurrentPolicy, true);
  934 #ifdef HAVE_LIBNGHTTP2
  935                     if (pConf->h2_mode)
  936                         h2_paf_register_port(sc, (uint16_t)i, client, server, httpCurrentPolicy, true);
  937 #endif /* HAVE_LIBNGHTTP2 */
  938                 }
  939                 else
  940                 {
  941                     hi_paf_register_port(sc, (uint16_t)i, client, server, httpCurrentPolicy, false);
  942 #ifdef HAVE_LIBNGHTTP2
  943                     if (pConf->h2_mode)
  944                         h2_paf_register_port(sc, (uint16_t)i, client, server, httpCurrentPolicy, false);
  945 #endif /* HAVE_LIBNGHTTP2 */
  946                 }
  947             }
  948         }
  949     }
  950 }
  951 
  952 #ifdef TARGET_BASED
  953 /**
  954  * @param service ordinal number of service.
  955  */
  956 static void HttpInspectAddServicesOfInterest(struct _SnortConfig *sc, HTTPINSPECT_GLOBAL_CONF *config, tSfPolicyId policy_id)
  957 {
  958     if ((config == NULL) || (!config->global_server))
  959         return;
  960 
  961     /* Add ordinal number for the service into stream5 */
  962     if (hi_app_protocol_id != SFTARGET_UNKNOWN_PROTOCOL)
  963     {
  964         stream_api->set_service_filter_status(sc, hi_app_protocol_id, PORT_MONITOR_SESSION, policy_id, 1);
  965 
  966         if (file_api->get_max_file_depth(sc, true) > 0)
  967         {
  968             hi_paf_register_service(sc, hi_app_protocol_id, true, true, policy_id, true);
  969 #ifdef HAVE_LIBNGHTTP2
  970             if (config->global_server->h2_mode)
  971                 h2_paf_register_service(sc, hi_app_protocol_id, true, true, policy_id, true);
  972 #endif
  973         }
  974         else
  975         {
  976             hi_paf_register_service(sc, hi_app_protocol_id, true, true, policy_id, false);
  977 #ifdef HAVE_LIBNGHTTP2
  978             if (config->global_server->h2_mode)
  979                 h2_paf_register_service(sc, hi_app_protocol_id, true, true, policy_id, false);
  980 #endif
  981         }
  982     }
  983 
  984 /*
  985 #ifdef HAVE_LIBNGHTTP2
  986     if ((config == NULL) || (!config->global_server))
  987         return;
  988 
  989     if ((h2_app_protocol_id != SFTARGET_UNKNOWN_PROTOCOL) && (config->global_server->h2_mode))
  990     {
  991         stream_api->set_service_filter_status(sc, h2_app_protocol_id, PORT_MONITOR_SESSION, policy_id, 1);
  992 
  993         if (file_api->get_max_file_depth() > 0)
  994             h2_paf_register_service(sc, h2_app_protocol_id, true, true, policy_id, true);
  995         else
  996             h2_paf_register_service(sc, h2_app_protocol_id, true, true, policy_id, false);
  997     }
  998 
  999 #endif */ /* HAVE_LIBNGHTTP2 */
 1000 }
 1001 #endif
 1002 
 1003 typedef struct _HttpEncodeData
 1004 {
 1005     int http_type;
 1006     int encode_type;
 1007 }HttpEncodeData;
 1008 
 1009 static int HttpEncodeInit(struct _SnortConfig *sc, char *name, char *parameters, void **dataPtr)
 1010 {
 1011     char **toks, **toks1;
 1012     int num_toks, num_toks1;
 1013     int i;
 1014     char *etype;
 1015     char *btype;
 1016     char *findStr1, *findStr2;
 1017     int negate_flag = 0;
 1018     unsigned pos;
 1019     HttpEncodeData *idx= NULL;
 1020 
 1021     idx = (HttpEncodeData *) SnortAlloc(sizeof(HttpEncodeData));
 1022     hi_stats.mem_used += sizeof(HttpEncodeData);
 1023 
 1024     if(idx == NULL)
 1025     {
 1026         FatalError("%s(%d): Failed allocate data for %s option\n",
 1027             file_name, file_line, name);
 1028     }
 1029 
 1030 
 1031     toks = mSplit(parameters, ",", 2, &num_toks, 0);
 1032 
 1033     if(num_toks != 2 )
 1034     {
 1035         FatalError("%s (%d): %s option takes two parameters \n",
 1036             file_name, file_line, name);
 1037     }
 1038 
 1039     btype = toks[0];
 1040     if(!strcasecmp(btype, "uri"))
 1041     {
 1042         idx->http_type = HTTP_BUFFER_URI;
 1043     }
 1044     else if(!strcasecmp(btype, "header"))
 1045     {
 1046         idx->http_type = HTTP_BUFFER_HEADER;
 1047     }
 1048     /* This keyword will not be used until post normalization is turned on */
 1049     /*else if(!strcasecmp(btype, "post"))
 1050     {
 1051         idx->http_type = HTTP_BUFFER_CLIENT_BODY;
 1052     }*/
 1053     else if(!strcasecmp(btype, "cookie"))
 1054     {
 1055         idx->http_type = HTTP_BUFFER_COOKIE;
 1056     }
 1057     /*check for a negation when OR is present. OR and negation is not supported*/
 1058     findStr1 = strchr(toks[1], '|');
 1059     if( findStr1 )
 1060     {
 1061         findStr2 = strchr(toks[1], '!' );
 1062         if( findStr2 )
 1063         {
 1064             FatalError("%s (%d): \"|\" is not supported in conjunction with \"!\" for %s option \n",
 1065                     file_name, file_line, name);
 1066         }
 1067 
 1068         pos = findStr1 - toks[1];
 1069         if ( pos == 0 || pos == (strlen(toks[1]) - 1) )
 1070         {
 1071             FatalError("%s (%d): Invalid Parameters for %s option \n",
 1072                     file_name, file_line, name);
 1073         }
 1074     }
 1075 
 1076      toks1 = mSplit(toks[1], "|", 0, &num_toks1, 0);
 1077 
 1078      for(i = 0; i < num_toks1; i++)
 1079      {
 1080          etype = toks1[i];
 1081 
 1082          if( *etype == '!' )
 1083          {
 1084              negate_flag = 1;
 1085              etype++;
 1086              while(isspace((int)*etype)) {etype++;}
 1087          }
 1088 
 1089          if(!strcasecmp(etype, "utf8"))
 1090          {
 1091              if(negate_flag)
 1092                  idx->encode_type &= ~HTTP_ENCODE_TYPE__UTF8_UNICODE;
 1093              else
 1094                  idx->encode_type |= HTTP_ENCODE_TYPE__UTF8_UNICODE;
 1095          }
 1096 
 1097          else if(!strcasecmp(etype, "double_encode"))
 1098          {
 1099              if(negate_flag)
 1100                  idx->encode_type &= ~HTTP_ENCODE_TYPE__DOUBLE_ENCODE;
 1101              else idx->encode_type |= HTTP_ENCODE_TYPE__DOUBLE_ENCODE;
 1102          }
 1103 
 1104          else if(!strcasecmp(etype, "non_ascii"))
 1105          {
 1106              if(negate_flag) idx->encode_type &= ~HTTP_ENCODE_TYPE__NONASCII;
 1107              else
 1108                  idx->encode_type |= HTTP_ENCODE_TYPE__NONASCII;
 1109          }
 1110 
 1111          /* Base 36 is deprecated and essentially a noop */
 1112          else if(!strcasecmp(etype, "base36"))
 1113          {
 1114              ErrorMessage("WARNING: %s (%d): The \"base36\" argument to the "
 1115                      "\"http_encode\" rule option is deprecated and void "
 1116                      "of functionality.\n", file_name, file_line);
 1117 
 1118              /* Set encode type so we can check below to see if base36 was the
 1119               * only argument in the encode chain */
 1120              idx->encode_type |= HTTP_ENCODE_TYPE__BASE36;
 1121          }
 1122 
 1123          else if(!strcasecmp(etype, "uencode"))
 1124          {
 1125              if(negate_flag)
 1126                  idx->encode_type &= ~HTTP_ENCODE_TYPE__UENCODE;
 1127              else
 1128                  idx->encode_type |= HTTP_ENCODE_TYPE__UENCODE;
 1129          }
 1130 
 1131          else if(!strcasecmp(etype, "bare_byte"))
 1132          {
 1133              if(negate_flag)
 1134                  idx->encode_type &= ~HTTP_ENCODE_TYPE__BARE_BYTE;
 1135              else
 1136                  idx->encode_type |= HTTP_ENCODE_TYPE__BARE_BYTE;
 1137          }
 1138          else if (!strcasecmp(etype, "iis_encode"))
 1139          {
 1140              if(negate_flag)
 1141                  idx->encode_type &= ~HTTP_ENCODE_TYPE__IIS_UNICODE;
 1142              else
 1143                  idx->encode_type |= HTTP_ENCODE_TYPE__IIS_UNICODE;
 1144          }
 1145          else if  (!strcasecmp(etype, "ascii"))
 1146          {
 1147              if(negate_flag)
 1148                  idx->encode_type &= ~HTTP_ENCODE_TYPE__ASCII;
 1149              else
 1150                  idx->encode_type |= HTTP_ENCODE_TYPE__ASCII;
 1151          }
 1152 
 1153          else
 1154          {
 1155              FatalError("%s(%d): Unknown modifier \"%s\" for option \"%s\"\n",
 1156                      file_name, file_line, toks1[i], name);
 1157          }
 1158          negate_flag = 0;
 1159      }
 1160 
 1161      /* Only got base36 parameter which is deprecated.  If it's the only
 1162       * parameter in the chain make it so it always matches as if the
 1163       * entire rule option were non-existent. */
 1164      if (idx->encode_type == HTTP_ENCODE_TYPE__BASE36)
 1165      {
 1166          idx->encode_type = 0xffffffff;
 1167      }
 1168 
 1169      *dataPtr = idx;
 1170      mSplitFree(&toks,num_toks);
 1171      mSplitFree(&toks1,num_toks1);
 1172 
 1173      return 0;
 1174 }
 1175 
 1176 
 1177 static int HttpEncodeEval(void *p, const uint8_t **cursor, void *dataPtr)
 1178 {
 1179     Packet* pkt = p;
 1180     HttpEncodeData* idx = (HttpEncodeData *)dataPtr;
 1181     const HttpBuffer* hb;
 1182 
 1183     if ( !pkt || !idx )
 1184         return DETECTION_OPTION_NO_MATCH;
 1185 
 1186     hb = GetHttpBuffer(idx->http_type);
 1187 
 1188     if ( hb && (hb->encode_type & idx->encode_type) )
 1189         return DETECTION_OPTION_MATCH;
 1190 
 1191     return DETECTION_OPTION_NO_MATCH;
 1192 }
 1193 
 1194 static void HttpEncodeCleanup(void *dataPtr)
 1195 {
 1196     HttpEncodeData *idx = dataPtr;
 1197     if (idx)
 1198     {
 1199         free(idx);
 1200         hi_stats.mem_used -= sizeof(HttpEncodeData);
 1201     }
 1202 }
 1203 
 1204 static int HttpInspectFileDecompIterate(void *data)
 1205 {
 1206     HTTPINSPECT_CONF *server = (HTTPINSPECT_CONF *)data;
 1207 
 1208     if (server == NULL)
 1209         return 0;
 1210 
 1211     if (server->file_decomp_modes != 0)
 1212         return 1;
 1213 
 1214     return 0;
 1215 }
 1216 
 1217 static int HttpInspectFileDecomp(struct _SnortConfig *sc,
 1218         tSfPolicyUserContextId config,
 1219         tSfPolicyId policyId, void *pData)
 1220 {
 1221     HTTPINSPECT_GLOBAL_CONF *context = (HTTPINSPECT_GLOBAL_CONF *)pData;
 1222 
 1223     if (pData == NULL)
 1224         return 0;
 1225 
 1226     if(context->disabled)
 1227         return 0;
 1228 
 1229     if ((context->global_server != NULL) && (context->global_server->file_decomp_modes != 0))
 1230         return 1;
 1231 
 1232     if (context->server_lookup != NULL)
 1233     {
 1234         if (sfrt_iterate2(context->server_lookup, HttpInspectFileDecompIterate) != 0)
 1235             return 1;
 1236     }
 1237 
 1238     return 0;
 1239 }
 1240 
 1241 
 1242 static int HttpInspectExtractGzipIterate(void *data)
 1243 {
 1244     HTTPINSPECT_CONF *server = (HTTPINSPECT_CONF *)data;
 1245 
 1246     if (server == NULL)
 1247         return 0;
 1248 
 1249     if (server->extract_gzip)
 1250         return 1;
 1251 
 1252     return 0;
 1253 }
 1254 
 1255 static int HttpInspectExtractGzip(struct _SnortConfig *sc,
 1256         tSfPolicyUserContextId config,
 1257         tSfPolicyId policyId, void *pData)
 1258 {
 1259     HTTPINSPECT_GLOBAL_CONF *context = (HTTPINSPECT_GLOBAL_CONF *)pData;
 1260 
 1261     if (pData == NULL)
 1262         return 0;
 1263 
 1264     if(context->disabled)
 1265         return 0;
 1266 
 1267     if ((context->global_server != NULL) && context->global_server->extract_gzip)
 1268         return 1;
 1269 
 1270     if (context->server_lookup != NULL)
 1271     {
 1272         if (sfrt_iterate2(context->server_lookup, HttpInspectExtractGzipIterate) != 0)
 1273             return 1;
 1274     }
 1275 
 1276     return 0;
 1277 }
 1278 
 1279 static int HttpInspectExtractUriHostIterate(void *data)
 1280 {
 1281     HTTPINSPECT_CONF *server = (HTTPINSPECT_CONF *)data;
 1282 
 1283     if (server == NULL)
 1284         return 0;
 1285 
 1286 #if defined(FEAT_OPEN_APPID)
 1287     if (server->log_uri || server->log_hostname || server->appid_enabled)
 1288 #else
 1289     if (server->log_uri || server->log_hostname)
 1290 #endif /* defined(FEAT_OPEN_APPID) */
 1291         return 1;
 1292 
 1293     return 0;
 1294 }
 1295 
 1296 static int HttpInspectExtractUriHost(struct _SnortConfig *sc,
 1297                 tSfPolicyUserContextId config,
 1298                 tSfPolicyId policyId, void *pData)
 1299 {
 1300     HTTPINSPECT_GLOBAL_CONF *context = (HTTPINSPECT_GLOBAL_CONF *)pData;
 1301 
 1302     if (pData == NULL)
 1303         return 0;
 1304 
 1305     if(context->disabled)
 1306         return 0;
 1307 
 1308 #if defined(FEAT_OPEN_APPID)
 1309     if ((context->global_server != NULL) && (context->global_server->log_uri || context->global_server->log_hostname || context->global_server->appid_enabled))
 1310 #else
 1311     if ((context->global_server != NULL) && (context->global_server->log_uri || context->global_server->log_hostname))
 1312 #endif /* defined(FEAT_OPEN_APPID) */
 1313         return 1;
 1314 
 1315     if (context->server_lookup != NULL)
 1316     {
 1317         if (sfrt_iterate2(context->server_lookup, HttpInspectExtractUriHostIterate) != 0)
 1318             return 1;
 1319     }
 1320 
 1321     return 0;
 1322 }
 1323 
 1324 static int HttpEnableDecoding(struct _SnortConfig *sc,
 1325             tSfPolicyUserContextId config,
 1326             tSfPolicyId policyId, void *pData)
 1327 {
 1328     HTTPINSPECT_GLOBAL_CONF *context = (HTTPINSPECT_GLOBAL_CONF *)pData;
 1329 
 1330     if (pData == NULL)
 1331         return 0;
 1332 
 1333     if(context->disabled)
 1334         return 0;
 1335 
 1336     if((context->global_server != NULL) && (context->global_server->post_extract_size > -1)
 1337             && (file_api->is_decoding_enabled(&(context->decode_conf))))
 1338         return 1;
 1339 
 1340     return 0;
 1341 }
 1342 
 1343 static int HttpEnableMimeLog(struct _SnortConfig *sc,
 1344             tSfPolicyUserContextId config,
 1345             tSfPolicyId policyId, void *pData)
 1346 {
 1347     HTTPINSPECT_GLOBAL_CONF *context = (HTTPINSPECT_GLOBAL_CONF *)pData;
 1348 
 1349     if (pData == NULL)
 1350         return 0;
 1351 
 1352     if(context->disabled)
 1353         return 0;
 1354 
 1355     if((context->global_server != NULL) && (context->global_server->post_extract_size > -1)
 1356             && (file_api->is_mime_log_enabled(&(context->mime_conf))))
 1357         return 1;
 1358 
 1359     return 0;
 1360 }
 1361 
 1362 static int ProcessGzipAndFDMemPools( struct _SnortConfig *sc,
 1363                                       tSfPolicyUserContextId my_hi_config,
 1364                                       HTTPINSPECT_GLOBAL_CONF *my_defaultConfig )
 1365 {
 1366     bool have_gzip, have_fd;
 1367     uint32_t max_sessions = 0;
 1368     uint32_t block_size = 0;
 1369 
 1370     have_fd = (sfPolicyUserDataIterate(sc, my_hi_config, HttpInspectFileDecomp) != 0);
 1371     have_gzip = (sfPolicyUserDataIterate(sc, my_hi_config, HttpInspectExtractGzip) != 0);
 1372 
 1373     if( have_fd || have_gzip )
 1374     {
 1375         if (my_defaultConfig == NULL)
 1376         {
 1377             WarningMessage("http_inspect: Must configure a default global "
 1378                            "configuration if you want to enable gzip or file decomp in any "
 1379                            "server configuration.\n");
 1380             return( -1 );
 1381         }
 1382 
 1383         if( have_fd )
 1384             block_size += sizeof( fd_session_t );
 1385         if( have_gzip )
 1386             block_size += sizeof( DECOMPRESS_STATE );
 1387 
 1388         if( block_size > my_defaultConfig->max_gzip_mem )
 1389             FatalError("http_inspect: Error setting the \"max_gzip_mem\" \n");
 1390 
 1391         max_sessions = my_defaultConfig->max_gzip_mem / block_size;
 1392         my_defaultConfig->max_gzip_sessions = max_sessions;
 1393 
 1394         if( have_fd )
 1395         {
 1396             hi_fd_conf.Max_Memory = (max_sessions * sizeof( fd_session_t ));
 1397             if( File_Decomp_Config(&(hi_fd_conf)) != File_Decomp_OK )
 1398                 FatalError("http_inspect: Could not allocate file decomp mempool.\n");
 1399         }
 1400         else
 1401             hi_fd_conf.fd_MemPool = NULL;
 1402 
 1403         if( have_gzip )
 1404         {
 1405             hi_gzip_mempool = (MemPool *)SnortAlloc(sizeof(MemPool));
 1406 
 1407             if( (hi_gzip_mempool == 0) ||
 1408                 (mempool_init(hi_gzip_mempool, max_sessions,
 1409                               sizeof(DECOMPRESS_STATE)) != 0) )
 1410                 FatalError("http_inspect: Could not allocate gzip mempool.\n");
 1411         }
 1412         else
 1413             hi_gzip_mempool = NULL;
 1414     }
 1415     return( 0 );
 1416  }
 1417 
 1418 static int CheckFilePolicyConfig(
 1419         struct _SnortConfig *sc,
 1420         tSfPolicyUserContextId config,
 1421         tSfPolicyId policyId,
 1422         void* pData
 1423         )
 1424 {
 1425     HTTPINSPECT_GLOBAL_CONF *context = (HTTPINSPECT_GLOBAL_CONF*)pData;
 1426 
 1427     context->decode_conf.file_depth = file_api->get_max_file_depth(sc, true);
 1428     if (context->decode_conf.file_depth > -1)
 1429         context->mime_conf.log_filename = 1;
 1430     updateMaxDepth(context->decode_conf.file_depth, &context->decode_conf.max_depth);
 1431 
 1432     return 0;
 1433 }
 1434 
 1435 /*
 1436 **  NAME
 1437 **    HttpInspectCheckConfig::
 1438 */
 1439 /**
 1440 **  This function verifies the HttpInspect configuration is complete
 1441 **
 1442 **  @return none
 1443 */
 1444 static int HttpInspectCheckConfig(struct _SnortConfig *sc)
 1445 {
 1446     HTTPINSPECT_GLOBAL_CONF *defaultConfig;
 1447 
 1448     if (hi_config == NULL)
 1449         return 0;
 1450 
 1451     if (sfPolicyUserDataIterate (sc, hi_config, HttpInspectVerifyPolicy))
 1452         return -1;
 1453 
 1454     if (sfPolicyUserDataIterate (sc, hi_config, CheckFilePolicyConfig))
 1455         return -1;
 1456 
 1457     defaultConfig = (HTTPINSPECT_GLOBAL_CONF *)sfPolicyUserDataGetDefault(hi_config);
 1458 
 1459     if( ProcessGzipAndFDMemPools( sc, hi_config, defaultConfig ) != 0 )
 1460         return( -1 );
 1461 
 1462     if (sfPolicyUserDataIterate(sc, hi_config, HttpInspectExtractUriHost) != 0)
 1463     {
 1464         uint32_t max_sessions_logged;
 1465         if (defaultConfig == NULL)
 1466         {
 1467             WarningMessage("http_inspect:  Must configure a default global "
 1468                         "configuration if you want to enable logging of uri or hostname in any "
 1469                         "server configuration.\n");
 1470             return -1;
 1471         }
 1472 
 1473         max_sessions_logged = defaultConfig->memcap / (MAX_URI_EXTRACTED + MAX_HOSTNAME);
 1474 
 1475         http_mempool = (MemPool *)SnortAlloc(sizeof(MemPool));
 1476         if (mempool_init(http_mempool, max_sessions_logged, (MAX_URI_EXTRACTED + MAX_HOSTNAME)) != 0)
 1477         {
 1478             FatalError("http_inspect:  Could not allocate HTTP mempool.\n");
 1479         }
 1480     }
 1481 
 1482     if (sfPolicyUserDataIterate(sc, hi_config, HttpEnableDecoding) != 0)
 1483     {
 1484         if (defaultConfig == NULL)
 1485         {
 1486             WarningMessage("http_inspect:  Must configure a default global "
 1487                     "configuration if you want to enable decoding in any "
 1488                     "server configuration.\n");
 1489             return -1;
 1490         }
 1491         mime_decode_mempool = (MemPool *)file_api->init_mime_mempool(defaultConfig->decode_conf.max_mime_mem,
 1492                 defaultConfig->decode_conf.max_depth, mime_decode_mempool, PROTOCOL_NAME);
 1493     }
 1494 
 1495     if (sfPolicyUserDataIterate(sc, hi_config, HttpEnableMimeLog) != 0)
 1496     {
 1497         if (defaultConfig == NULL)
 1498         {
 1499             ErrorMessage("http_inspect:  Must configure a default global "
 1500                     "configuration if you want to enable mime log in any "
 1501                     "server configuration.\n");
 1502             return -1;
 1503         }
 1504         mime_log_mempool = (MemPool *)file_api->init_log_mempool(0,
 1505                 defaultConfig->mime_conf.memcap, mime_log_mempool, "HTTP");
 1506     }
 1507     return 0;
 1508 }
 1509 
 1510 static int HttpInspectFreeConfigPolicy(tSfPolicyUserContextId config,tSfPolicyId policyId, void* pData )
 1511 {
 1512     HTTPINSPECT_GLOBAL_CONF *pPolicyConfig = (HTTPINSPECT_GLOBAL_CONF *)pData;
 1513     HttpInspectFreeConfig(pPolicyConfig);
 1514     sfPolicyUserDataClear (config, policyId);
 1515     return 0;
 1516 }
 1517 
 1518 static void HttpInspectFreeConfigs(tSfPolicyUserContextId config)
 1519 {
 1520     int i;
 1521 
 1522     if(oldXffFields)
 1523     {
 1524         for (i = 0; (i < HTTP_MAX_XFF_FIELDS) && (oldXffFields[i]); i++)
 1525         {
 1526             free(oldXffFields[i]);
 1527             oldXffFields[i] = NULL;
 1528         }
 1529        
 1530         free(oldXffFields);
 1531         oldXffFields = NULL;
 1532     }
 1533 
 1534     if (config == NULL)
 1535         return;
 1536     sfPolicyUserDataFreeIterate (config, HttpInspectFreeConfigPolicy);
 1537     sfPolicyConfigDelete(config);
 1538 
 1539 }
 1540 
 1541 static void HttpInspectFreeConfig(HTTPINSPECT_GLOBAL_CONF *config)
 1542 {
 1543     if (config == NULL)
 1544         return;
 1545 
 1546     hi_ui_server_lookup_destroy(config->server_lookup);
 1547 
 1548     xfree(config->iis_unicode_map_filename);
 1549     xfree(config->iis_unicode_map);
 1550 
 1551     if (config->global_server != NULL)
 1552     {
 1553         int i;
 1554         for( i=0; i<HTTP_MAX_XFF_FIELDS; i++ )
 1555             if( config->global_server->xff_headers[i] != NULL )
 1556             {
 1557                 free(  config->global_server->xff_headers[i] );
 1558                 config->global_server->xff_headers[i] = NULL;
 1559             }
 1560 
 1561         http_cmd_lookup_cleanup(&(config->global_server->cmd_lookup));
 1562         free(config->global_server);
 1563     }
 1564 
 1565     free(config);
 1566 }
 1567 
 1568 #ifdef SNORT_RELOAD
 1569 static void _HttpInspectReload(struct _SnortConfig *sc, tSfPolicyUserContextId hi_swap_config, char *args)
 1570 {
 1571     char ErrorString[ERRSTRLEN];
 1572     int  iErrStrLen = ERRSTRLEN;
 1573     int  iRet;
 1574     HTTPINSPECT_GLOBAL_CONF *pPolicyConfig = NULL;
 1575     char *pcToken;
 1576     char *saveptr;
 1577     tSfPolicyId policy_id = getParserPolicy(sc);
 1578 
 1579     ErrorString[0] = '\0';
 1580 
 1581     if ((args == NULL) || (strlen(args) == 0))
 1582         ParseError("No arguments to HttpInspect configuration.");
 1583 
 1584     /* Find out what is getting configured */
 1585     pcToken = strtok_r(args, CONF_SEPARATORS, &saveptr);
 1586     if (pcToken == NULL)
 1587     {
 1588         FatalError("%s(%d)strtok returned NULL when it should not.",
 1589                    __FILE__, __LINE__);
 1590     }
 1591 
 1592     if (!oldXffFields)
 1593     {
 1594         oldXffFields = xffFields;
 1595         if ((xffFields = calloc(1, HTTP_MAX_XFF_FIELDS * sizeof(char *))) == NULL)
 1596         {
 1597             FatalError("http_inspect: %s(%d) failed to allocate memory for XFF fields\n", 
 1598                        __FILE__, __LINE__);
 1599         }
 1600     }
 1601 
 1602     /*
 1603     **  Global Configuration Processing
 1604     **  We only process the global configuration once, but always check for
 1605     **  user mistakes, like configuring more than once.  That's why we
 1606     **  still check for the global token even if it's been checked.
 1607     **  Force the first configuration to be the global one.
 1608     */
 1609     sfPolicyUserPolicySet (hi_swap_config, policy_id);
 1610     pPolicyConfig = (HTTPINSPECT_GLOBAL_CONF *)sfPolicyUserDataGetCurrent(hi_swap_config);
 1611     if (pPolicyConfig == NULL)
 1612     {
 1613         if (strcasecmp(pcToken, GLOBAL) != 0)
 1614             ParseError("Must configure the http inspect global configuration first.");
 1615 
 1616         HttpInspectRegisterRuleOptions(sc);
 1617 
 1618         pPolicyConfig = (HTTPINSPECT_GLOBAL_CONF *)SnortAlloc(sizeof(HTTPINSPECT_GLOBAL_CONF));
 1619         if (!pPolicyConfig)
 1620         {
 1621              ParseError("HTTP INSPECT preprocessor: memory allocate failed.\n");
 1622         }
 1623         sfPolicyUserDataSetCurrent(hi_swap_config, pPolicyConfig);
 1624         iRet = HttpInspectInitializeGlobalConfig(pPolicyConfig,
 1625                                                  ErrorString, iErrStrLen);
 1626         if (iRet == 0)
 1627         {
 1628             iRet = ProcessGlobalConf(pPolicyConfig, ErrorString, iErrStrLen, &saveptr);
 1629 
 1630             if (iRet == 0)
 1631             {
 1632                 CheckGzipConfig(pPolicyConfig, hi_swap_config);
 1633                 CheckMemcap(pPolicyConfig, hi_swap_config);
 1634                 PrintGlobalConf(pPolicyConfig);
 1635 
 1636                 /* Add HttpInspect into the preprocessor list */
 1637                 if ( pPolicyConfig->disabled )
 1638                     return;
 1639                 AddFuncToPreprocList(sc, HttpInspect, PRIORITY_APPLICATION, PP_HTTPINSPECT, PROTO_BIT__TCP);
 1640 
 1641             }
 1642         }
 1643     }
 1644     else
 1645     {
 1646         if (strcasecmp(pcToken, SERVER) != 0)
 1647         {
 1648             if (strcasecmp(pcToken, GLOBAL) != 0)
 1649                 ParseError("Must configure the http inspect global configuration first.");
 1650             else
 1651                 ParseError("Invalid http inspect token: %s.", pcToken);
 1652         }
 1653 
 1654         iRet = ProcessUniqueServerConf(sc, pPolicyConfig, ErrorString, iErrStrLen, &saveptr);
 1655     }
 1656 
 1657     if (iRet)
 1658     {
 1659         if(iRet > 0)
 1660         {
 1661             /*
 1662             **  Non-fatal Error
 1663             */
 1664             if(*ErrorString)
 1665             {
 1666                 ErrorMessage("%s(%d) => %s\n",
 1667                         file_name, file_line, ErrorString);
 1668             }
 1669         }
 1670         else
 1671         {
 1672             /*
 1673             **  Fatal Error, log error and exit.
 1674             */
 1675             if(*ErrorString)
 1676             {
 1677                 FatalError("%s(%d) => %s\n",
 1678                         file_name, file_line, ErrorString);
 1679             }
 1680             else
 1681             {
 1682                 /*
 1683                 **  Check if ErrorString is undefined.
 1684                 */
 1685                 if(iRet == -2)
 1686                 {
 1687                     FatalError("%s(%d) => ErrorString is undefined.\n",
 1688                             file_name, file_line);
 1689                 }
 1690                 else
 1691                 {
 1692                     FatalError("%s(%d) => Undefined Error.\n",
 1693                             file_name, file_line);
 1694                 }
 1695             }
 1696         }
 1697     }
 1698 }
 1699 
 1700 static void HttpInspectReloadGlobal(struct _SnortConfig *sc, char *args, void **new_config)
 1701 {
 1702     tSfPolicyUserContextId hi_swap_config = (tSfPolicyUserContextId)*new_config;
 1703     if (!hi_swap_config)
 1704     {
 1705         hi_swap_config = sfPolicyConfigCreate();
 1706         if (!hi_swap_config)
 1707             FatalError("No memory to allocate http inspect swap_configuration.\n");
 1708         *new_config = hi_swap_config;
 1709     }
 1710     _HttpInspectReload(sc, hi_swap_config, args);
 1711 }
 1712 
 1713 static void HttpInspectReload(struct _SnortConfig *sc, char *args, void **new_config)
 1714 {
 1715     tSfPolicyUserContextId hi_swap_config;
 1716     hi_swap_config = (tSfPolicyUserContextId)GetRelatedReloadData(sc, GLOBAL_KEYWORD);
 1717     _HttpInspectReload(sc, hi_swap_config, args);
 1718 }
 1719 
 1720 static int HttpMempoolFreeUsedBucket(MemPool *memory_pool)
 1721 {
 1722     MemBucket *lru_bucket = NULL;
 1723 
 1724     lru_bucket = mempool_get_lru_bucket(memory_pool);
 1725     if(lru_bucket)
 1726     {
 1727         session_api->set_application_data(lru_bucket->scbPtr, PP_HTTPINSPECT, NULL, NULL);
 1728         return 1;
 1729     }
 1730     return 0;
 1731 }
 1732 
 1733 static unsigned HttpMempoolAdjust(MemPool *memory_pool, unsigned httpMaxWork)
 1734 {
 1735     int retVal;
 1736 
 1737     /* deleting MemBucket from free list in HTTP Mempool */
 1738     httpMaxWork = mempool_prune_freelist(memory_pool, memory_pool->max_memory, httpMaxWork);
 1739 
 1740     for( ; httpMaxWork && ((memory_pool->used_memory + memory_pool->free_memory) > memory_pool->max_memory); httpMaxWork--)
 1741     {
 1742         /* deleting least recently used MemBucket from Used list in HTTP Mempool */
 1743         retVal = HttpMempoolFreeUsedBucket(memory_pool);
 1744         if(!retVal)
 1745            break;
 1746     }
 1747 
 1748     return httpMaxWork;
 1749 }
 1750 
 1751 static bool HttpGzipReloadAdjust(bool idle, tSfPolicyId raPolicyId, void* userData)
 1752 {
 1753     unsigned initialMaxWork = idle ? 512 : 5;
 1754     unsigned maxWork;
 1755 
 1756     maxWork = HttpMempoolAdjust(hi_gzip_mempool, initialMaxWork);
 1757     /* This check will be true, when the gzip_mempool is disabled and mempool cleaning is also completed  */
 1758     if( hi_gzip_mempool->used_memory + hi_gzip_mempool->free_memory == 0 )
 1759     {
 1760         free(hi_gzip_mempool);
 1761         hi_gzip_mempool = NULL;
 1762         return true;
 1763     }
 1764 
 1765     return (maxWork == initialMaxWork) ? true : false;
 1766 }
 1767 
 1768 static bool HttpFdReloadAdjust(bool idle, tSfPolicyId raPolicyId, void* userData)
 1769 {
 1770     unsigned initialMaxWork = idle ? 512 : 5;
 1771     unsigned maxWork;
 1772 
 1773     maxWork = HttpMempoolAdjust(hi_fd_conf.fd_MemPool, initialMaxWork);
 1774     /* This check will be true, when the fd_mempool is disabled and mempool cleaning is also completed  */
 1775     if( hi_fd_conf.fd_MemPool->used_memory + hi_fd_conf.fd_MemPool->free_memory == 0 )
 1776     {
 1777         free(hi_fd_conf.fd_MemPool);
 1778         hi_fd_conf.fd_MemPool = NULL;
 1779         return true;
 1780     }
 1781 
 1782     return (maxWork == initialMaxWork) ? true : false;
 1783 }
 1784 
 1785 static bool HttpMempoolReloadAdjust(bool idle, tSfPolicyId raPolicyId, void* userData)
 1786 {
 1787     unsigned initialMaxWork = idle ? 512 : 5;
 1788     unsigned maxWork;
 1789 
 1790     /* If new memcap is less than old configured memcap, need to adjust HTTP Mempool.
 1791      * In order to adjust to new max_memory of http mempool, delete buckets from free list.
 1792      * After deleting buckets from free list, still new max_memory is less than old value , delete buckets
 1793      * (least recently used i.e head node of used list )from used list till total memory reaches to new max_memory.
 1794      */
 1795     maxWork = HttpMempoolAdjust(http_mempool, initialMaxWork);
 1796 
 1797     return (maxWork == initialMaxWork) ? true : false;
 1798 }
 1799 
 1800 static bool HttpMimeReloadAdjust(bool idle, tSfPolicyId raPolicyId, void* userData)
 1801 {
 1802     unsigned initialMaxWork = idle ? 512 : 5;
 1803     unsigned maxWork;
 1804 
 1805     /* If new max_mime_mem is less than old configured max_mime_mem, need to adjust HTTP Mime Mempool.
 1806      * In order to adjust to new max_memory of mime mempool, delete buckets from free list.
 1807      * After deleting buckets from free list, still new max_memory is less than old value , delete buckets
 1808      * (least recently used i.e head node of used list )from used list till total memory reaches to new max_memory.
 1809      */
 1810     maxWork = HttpMempoolAdjust(mime_decode_mempool, initialMaxWork);
 1811 
 1812     return (maxWork == initialMaxWork) ? true : false;
 1813 }
 1814 
 1815 static bool HttpLogReloadAdjust(bool idle, tSfPolicyId raPolicyId, void* userData)
 1816 {
 1817     unsigned initialMaxWork = idle ? 512 : 5;
 1818     unsigned maxWork;
 1819 
 1820     /* If new memcap is less than old configured memcap, need to adjust HTTP Log Mempool.
 1821      * In order to adjust to new max_memory of log mempool, delete buckets from free list.
 1822      * After deleting buckets from free list, still new max_memory is less than old value , delete buckets
 1823      * (least recently used i.e head node of used list )from used list till total memory reaches to new max_memory.
 1824      */
 1825     maxWork = HttpMempoolAdjust(mime_log_mempool, initialMaxWork);
 1826 
 1827     return (maxWork == initialMaxWork) ? true : false;
 1828 }
 1829 
 1830 static int HttpInspectReloadVerify(struct _SnortConfig *sc, void *swap_config)
 1831 {
 1832     tSfPolicyUserContextId hi_swap_config = (tSfPolicyUserContextId)swap_config;
 1833     HTTPINSPECT_GLOBAL_CONF *defaultConfig;
 1834     HTTPINSPECT_GLOBAL_CONF *defaultSwapConfig;
 1835     bool swap_gzip, swap_fd, curr_gzip, curr_fd;
 1836     tSfPolicyId policy_id = 0;
 1837 
 1838     if (hi_swap_config == NULL)
 1839         return 0;
 1840 
 1841     if (sfPolicyUserDataIterate (sc, hi_swap_config, HttpInspectVerifyPolicy))
 1842         return -1;
 1843 
 1844     defaultConfig = (HTTPINSPECT_GLOBAL_CONF *)sfPolicyUserDataGetDefault(hi_config);
 1845     defaultSwapConfig = (HTTPINSPECT_GLOBAL_CONF *)sfPolicyUserDataGetDefault(hi_swap_config);
 1846 
 1847     if (!defaultConfig)
 1848         return 0;
 1849 
 1850     curr_gzip = (hi_gzip_mempool != NULL);
 1851     curr_fd = (hi_fd_conf.fd_MemPool != NULL);
 1852 
 1853     policy_id = getParserPolicy(sc);
 1854 
 1855     LogMessage("HTTPInspect: gzip old=%s, fd old=%s\n", curr_gzip ? "true": "false", curr_fd ? "true": "false");
 1856     if( curr_gzip || curr_fd )
 1857     {
 1858         /* Look for the case where the current and swap configs have differing gzip & fd options. */
 1859         swap_fd = (sfPolicyUserDataIterate(sc, hi_swap_config, HttpInspectFileDecomp) != 0);
 1860         swap_gzip = (sfPolicyUserDataIterate(sc, hi_swap_config, HttpInspectExtractGzip) != 0);
 1861 
 1862         LogMessage("HTTPInspect: gzip new=%s, fd new=%s\n", swap_gzip ? "true": "false", swap_fd ? "true": "false");
 1863         if(defaultSwapConfig)
 1864         {
 1865              LogMessage("HTTPInspect: old gzip memcap=%u, new gzip memcap=%u\n", defaultConfig->max_gzip_mem, defaultSwapConfig->max_gzip_mem);
 1866              if(curr_gzip)
 1867                  LogMessage("HTTPInspect: HTTP-GZIP-MEMPOOL used=%zu, free=%zu, max=%zu, obj_size=%zu\n",
 1868                          hi_gzip_mempool->used_memory, hi_gzip_mempool->free_memory, hi_gzip_mempool->max_memory, hi_gzip_mempool->obj_size);
 1869              if(curr_fd)
 1870                  LogMessage("HTTPInspect: HTTP-FD-MEMPOOL used=%zu, free=%zu, max=%zu, obj_size=%zu\n",
 1871                          hi_fd_conf.fd_MemPool->used_memory, hi_fd_conf.fd_MemPool->free_memory, hi_fd_conf.fd_MemPool->max_memory, hi_fd_conf.fd_MemPool->obj_size);
 1872              if(defaultSwapConfig->max_gzip_mem < defaultConfig->max_gzip_mem)
 1873              {
 1874                   /* Change in max_gzip_mem value changes the number of max_sessions of hi_gzip_mempool and max_gzip_sessions.
 1875                      This value also changes  max_memory and max_sessions of hi_fd_conf.fd_Mempool.
 1876                      So registering here to adjust these mempools when max_gzip_mem cahnges.
 1877                    */
 1878                    if( curr_gzip && curr_fd && swap_gzip && swap_fd )
 1879                    {
 1880                         ReloadAdjustRegister(sc, "HTTP-GZIP-MEMPOOL", policy_id, &HttpGzipReloadAdjust, NULL, NULL);
 1881                         ReloadAdjustRegister(sc, "HTTP-FD-MEMPOOL", policy_id, &HttpFdReloadAdjust, NULL, NULL);
 1882                    }
 1883                    if( curr_gzip && !curr_fd && swap_gzip)
 1884                         ReloadAdjustRegister(sc, "HTTP-GZIP-MEMPOOL", policy_id, &HttpGzipReloadAdjust, NULL, NULL);
 1885                    if( !curr_gzip && curr_fd && swap_fd)
 1886                         ReloadAdjustRegister(sc, "HTTP-FD-MEMPOOL", policy_id, &HttpFdReloadAdjust, NULL, NULL);
 1887              }
 1888              if(curr_gzip && !swap_gzip)
 1889                  ReloadAdjustRegister(sc, "HTTP-GZIP-MEMPOOL", policy_id, &HttpGzipReloadAdjust, NULL, NULL);
 1890              if(curr_fd && !swap_fd)
 1891                  ReloadAdjustRegister(sc, "HTTP-FD-MEMPOOL", policy_id, &HttpFdReloadAdjust, NULL, NULL);
 1892         }
 1893     }
 1894     else if (defaultSwapConfig != NULL)
 1895     {
 1896         ProcessGzipAndFDMemPools( sc, hi_swap_config, defaultSwapConfig );
 1897     }
 1898 
 1899     if (http_mempool != NULL)
 1900     {
 1901         if (defaultSwapConfig != NULL)
 1902         {
 1903             LogMessage("HTTPInspect: HTTP-MEMPOOL old memcap=%d, new_memcap=%d, used=%zu, free=%zu, max=%zu, obj_size=%zu\n",
 1904                     defaultConfig->memcap, defaultSwapConfig->memcap, http_mempool->used_memory, http_mempool->free_memory, http_mempool->max_memory, http_mempool->obj_size);
 1905              if (defaultSwapConfig->memcap < defaultConfig->memcap)
 1906                   ReloadAdjustRegister(sc, "HTTP-MEMPOOL", policy_id, &HttpMempoolReloadAdjust, NULL, NULL);
 1907         }
 1908     }
 1909     else
 1910     {
 1911         if (sfPolicyUserDataIterate(sc, hi_swap_config, HttpInspectExtractUriHost) != 0)
 1912         {
 1913             uint32_t max_sessions_logged;
 1914 
 1915             if (defaultSwapConfig == NULL)
 1916             {
 1917                 ErrorMessage("http_inspect:  Must configure a default global "
 1918                             "configuration if you want to enable logging of uri or hostname in any "
 1919                             "server configuration.\n");
 1920                 return -1;
 1921             }
 1922 
 1923             max_sessions_logged = defaultSwapConfig->memcap / (MAX_URI_EXTRACTED + MAX_HOSTNAME);
 1924 
 1925             http_mempool = (MemPool *)SnortAlloc(sizeof(MemPool));
 1926 
 1927             if (mempool_init(http_mempool, max_sessions_logged,(MAX_URI_EXTRACTED + MAX_HOSTNAME)) != 0)
 1928             {
 1929                 FatalError("http_inspect:  Could not allocate HTTP mempool.\n");
 1930             }
 1931         }
 1932 
 1933     }
 1934     if (mime_decode_mempool != NULL)
 1935     {
 1936         if (sfPolicyUserDataIterate (sc, hi_swap_config, CheckFilePolicyConfig))
 1937             return -1;
 1938 
 1939         /* If max_mime_mem changes, mime mempool need to be adjusted bcz mempool max_memory will be changed.
 1940          * Registering here to adjust Mime memory Pool when max_mime_mem changes.
 1941          */
 1942         if(defaultSwapConfig)
 1943         {
 1944             LogMessage("HTTPInspect: HTTP-MIME-MEMPOOL old memcap=%d, new_memcap=%d, used=%zu, free=%zu, max=%zu, obj_size=%zu\n",
 1945                     defaultConfig->decode_conf.max_mime_mem, defaultSwapConfig->decode_conf.max_mime_mem, mime_decode_mempool->used_memory,
 1946                     mime_decode_mempool->free_memory, mime_decode_mempool->max_memory, mime_decode_mempool->obj_size);
 1947              if( defaultSwapConfig->decode_conf.max_mime_mem  < defaultConfig->decode_conf.max_mime_mem )
 1948                   ReloadAdjustRegister(sc, "HTTP-MIME-MEMPOOL", policy_id, &HttpMimeReloadAdjust, NULL, NULL);
 1949         }
 1950 
 1951     }
 1952     else
 1953     {
 1954         if (sfPolicyUserDataIterate(sc, hi_swap_config, HttpEnableDecoding) != 0)
 1955         {
 1956             if (defaultSwapConfig == NULL)
 1957             {
 1958                 ErrorMessage("http_inspect:  Must configure a default global "
 1959                         "configuration if you want to enable decoding in any "
 1960                         "server configuration.\n");
 1961                 return -1;
 1962             }
 1963             mime_decode_mempool = (MemPool *)file_api->init_mime_mempool(defaultSwapConfig->decode_conf.max_mime_mem,
 1964                     defaultSwapConfig->decode_conf.max_depth, mime_decode_mempool, PROTOCOL_NAME);
 1965         }
 1966     }
 1967     if (mime_log_mempool != NULL)
 1968     {
 1969        if(defaultSwapConfig)
 1970        {
 1971             /* If memcap of HTTP mIme changes, log mempool need to be adjusted bcz mempool max_mempory will be changed.
 1972               * Registering here to adjust Log memory Pool when memcap changes.
 1973               */
 1974             LogMessage("HTTPInspect: HTTP-LOG-MEMPOOL old memcap=%d, new_memcap=%d, used=%zu, free=%zu, max=%zu, obj_size=%zu\n",
 1975                     defaultConfig->mime_conf.memcap, defaultSwapConfig->mime_conf.memcap, mime_log_mempool->used_memory, mime_log_mempool->free_memory,
 1976                     mime_log_mempool->max_memory, mime_log_mempool->obj_size);
 1977             if (defaultSwapConfig->mime_conf.memcap < defaultConfig->mime_conf.memcap)
 1978                  ReloadAdjustRegister(sc, "HTTP-LOG-MEMPOOL", policy_id, &HttpLogReloadAdjust, NULL, NULL);
 1979        }
 1980 
 1981     }
 1982     else
 1983     {
 1984         if (sfPolicyUserDataIterate(sc, hi_swap_config, HttpEnableMimeLog) != 0)
 1985         {
 1986             if (defaultSwapConfig == NULL)
 1987             {
 1988                 ErrorMessage("http_inspect:  Must configure a default global "
 1989                         "configuration if you want to enable mime log in any "
 1990                         "server configuration.\n");
 1991                 return -1;
 1992             }
 1993             mime_log_mempool = (MemPool *)file_api->init_log_mempool(0,
 1994                     defaultSwapConfig->mime_conf.memcap, mime_log_mempool, PROTOCOL_NAME);
 1995         }
 1996     }
 1997 
 1998     return 0;
 1999 }
 2000 
 2001 #ifdef REG_TEST
 2002 static void display_http_mempool(MemPool *mempool, const char* old_new, const char *pool_type)
 2003 {
 2004     if(mempool)
 2005     {
 2006         printf("\n========== START# %s HTTP %s_mempool VALUES ==============================\n", old_new, pool_type);
 2007         printf("%s_mempool object size: %s VALUE # %zu \n",pool_type, old_new, mempool->obj_size);
 2008         printf("%s_mempool max memory : %s VALUE # %zu \n",pool_type, old_new, mempool->max_memory);
 2009         if(mempool->obj_size)
 2010             printf("%s_mempool total number of buckets: %s VALUE # %u \n",pool_type, old_new,(unsigned)(mempool->max_memory / mempool->obj_size));
 2011         printf("========== END# %s HTTP %s_mempool VALUES ==============================\n", old_new, pool_type);
 2012         fflush(stdout);
 2013     }
 2014 }
 2015 #endif
 2016 
 2017 static void update_gzip_mempool(bool old_gzip, bool new_gzip, uint32_t max_sessions)
 2018 {
 2019      if(old_gzip && !new_gzip)
 2020      {
 2021          if(hi_gzip_mempool)
 2022             hi_gzip_mempool->max_memory = 0;
 2023      }
 2024      else
 2025      {  
 2026          if(hi_gzip_mempool)
 2027          {
 2028               hi_gzip_mempool->max_memory = (max_sessions * sizeof( DECOMPRESS_STATE ) );
 2029               hi_gzip_mempool->obj_size = sizeof(DECOMPRESS_STATE);
 2030          }
 2031      }
 2032 }
 2033 static void update_fd_mempool(bool old_fd, bool new_fd, uint32_t max_sessions)
 2034 {
 2035      if(old_fd && !new_fd)
 2036      {
 2037           if(hi_fd_conf.fd_MemPool)
 2038           {
 2039               hi_fd_conf.Max_Memory = 0;
 2040               hi_fd_conf.fd_MemPool->max_memory = 0;
 2041           }
 2042      }
 2043      else
 2044      {
 2045           if(hi_fd_conf.fd_MemPool)
 2046           {
 2047                hi_fd_conf.Max_Memory = (max_sessions * sizeof( fd_session_t ));
 2048                hi_fd_conf.fd_MemPool->max_memory = (max_sessions * sizeof( fd_session_t ));
 2049                hi_fd_conf.fd_MemPool->obj_size = sizeof( fd_session_t );
 2050           }
 2051      }
 2052 }
 2053 static void update_gzip_fd_mempools(HTTPINSPECT_GLOBAL_CONF* configNew,
 2054             bool old_gzip, bool new_gzip, bool old_fd, bool new_fd)
 2055 {
 2056     uint32_t max_sessions = 0;
 2057     uint32_t block_size = 0;
 2058 
 2059     if( old_fd || old_gzip )
 2060     {
 2061          if( new_fd )
 2062               block_size += sizeof( fd_session_t );
 2063          if( new_gzip )
 2064               block_size += sizeof( DECOMPRESS_STATE );
 2065 
 2066          if( block_size > configNew->max_gzip_mem )
 2067                FatalError("http_inspect: Error setting the \"max_gzip_mem\" \n");
 2068 
 2069          if(block_size)
 2070             max_sessions = configNew->max_gzip_mem / block_size;
 2071          configNew->max_gzip_sessions = max_sessions;
 2072 
 2073          update_fd_mempool(old_fd, new_fd, max_sessions);
 2074          update_gzip_mempool(old_gzip, new_gzip, max_sessions);
 2075     }
 2076 
 2077 }
 2078 
 2079 static void update_http_mempool(uint32_t new_memcap, uint32_t old_memcap)
 2080 {
 2081     uint32_t max_sessions_logged = 0;
 2082     size_t obj_size = 0;
 2083 
 2084     obj_size = (MAX_URI_EXTRACTED + MAX_HOSTNAME);
 2085 
 2086     if(obj_size)
 2087         max_sessions_logged = new_memcap / obj_size;
 2088 
 2089 #ifdef REG_TEST
 2090     if(REG_TEST_EMAIL_FLAG_HTTP_MEMPOOL_ADJUST & getRegTestFlagsForEmail())
 2091     {
 2092         printf("\nhttp memcap value is #(OLD VALUE) %u \n", old_memcap);
 2093         display_http_mempool(http_mempool, "OLD", "http");
 2094         printf("\nSetting memcap to new value # (NEW VALUE )%u\n",new_memcap);
 2095     }
 2096 #endif
 2097 
 2098     http_mempool->max_memory = max_sessions_logged * obj_size;
 2099     http_mempool->obj_size = obj_size;
 2100 
 2101 #ifdef REG_TEST
 2102     if(REG_TEST_EMAIL_FLAG_HTTP_MEMPOOL_ADJUST & getRegTestFlagsForEmail())
 2103         display_http_mempool(http_mempool, "NEW", "http");
 2104 #endif
 2105 }
 2106 
 2107 #ifdef REG_TEST
 2108 static int HttpInspectUnlimitedDecompressIterate(void *data)
 2109 {
 2110     HTTPINSPECT_CONF *server = (HTTPINSPECT_CONF *)data;
 2111 
 2112     if (server == NULL)
 2113         return 0;
 2114 
 2115     if (server->unlimited_decompress)
 2116         return 1;
 2117 
 2118     return 0;
 2119 }
 2120 
 2121 static int HttpInspectUnlimitedDecompress(struct _SnortConfig *sc,
 2122            tSfPolicyUserContextId config,
 2123            tSfPolicyId policyId, void *pData)
 2124 {
 2125     HTTPINSPECT_GLOBAL_CONF *context = (HTTPINSPECT_GLOBAL_CONF *)pData;
 2126 
 2127     if (pData == NULL)
 2128         return 0;
 2129 
 2130     if(context->disabled)
 2131         return 0;
 2132 
 2133     if ((context->global_server != NULL) && context->global_server->unlimited_decompress)
 2134         return 1;
 2135 
 2136     if (context->server_lookup != NULL)
 2137     {
 2138         if (sfrt_iterate2(context->server_lookup, HttpInspectUnlimitedDecompressIterate) != 0)
 2139             return 1;
 2140     }
 2141     return 0;
 2142 }
 2143 static void display_gzip_fd_config_changes(HTTPINSPECT_GLOBAL_CONF* configOld, HTTPINSPECT_GLOBAL_CONF* configNew,
 2144                                            bool old_gzip, bool new_gzip, bool old_fd, bool new_fd, bool old_ud, bool new_ud)
 2145 {
 2146     if(configOld->max_gzip_mem  != configNew->max_gzip_mem )
 2147     {
 2148          printf("\nmax_gzip_mem value is # %u",configOld->max_gzip_mem);
 2149          printf("\nSetting max_gzip_value to new value # ( NEW VALUE ) %u\n", configNew->max_gzip_mem);
 2150     }
 2151     if(configOld->compr_depth != configNew->compr_depth)
 2152     {
 2153          printf("\nHttp Global Compression Depth is # OLD VALUE # %u",configOld->compr_depth);
 2154          printf("\nSetting Http Global Compression depth to # NEW VALUE # %u\n", configNew->compr_depth);
 2155     }
 2156     if(configOld->decompr_depth != configNew->decompr_depth)
 2157     {
 2158          printf("\nHttp Global Decompression Depth is # OLD VALUE # %u",configOld->decompr_depth);
 2159          printf("\nSetting Http Global Decompression depth to # NEW VALUE # %u\n", configNew->decompr_depth);
 2160     }
 2161     if( old_gzip != new_gzip )
 2162     {
 2163          printf("\nExtract GZIP is Enabled # OLD VALUE # %s",configOld->global_server->extract_gzip ? "YES" : "NO");
 2164          printf("\n[Setting] Extract GZIP is Enabled # NEW VALUE # %s\n",configNew->global_server->extract_gzip ? "YES" : "NO");
 2165     }
 2166     if( old_fd != new_fd )
 2167     {
 2168          printf("\nFile Decompression modes # OLD VALUE # %lu",configOld->global_server->file_decomp_modes);
 2169          printf("\nSetting File decompression modes to # NEW VALUE # %lu\n",configNew->global_server->file_decomp_modes);
 2170     }
 2171     if( old_ud != new_ud )
 2172     {
 2173          printf("\nUnlimited Decompression Enabled # OLD VALUE # %s",configOld->global_server->unlimited_decompress ? "YES" : "NO");
 2174          printf("\n[Setting] Unlimited Decompression Enabled# NEW VALUE # %s\n",configNew->global_server->unlimited_decompress ? "YES" : "NO");
 2175     }
 2176 }
 2177 #endif
 2178 
 2179 static void * HttpInspectReloadSwap(struct _SnortConfig *sc, void *swap_config)
 2180 {
 2181     tSfPolicyUserContextId hi_swap_config = (tSfPolicyUserContextId)swap_config;
 2182     tSfPolicyUserContextId old_config = hi_config;
 2183     HTTPINSPECT_GLOBAL_CONF *configNew = NULL, *configOld = NULL;
 2184     bool old_fd, old_gzip, new_fd, new_gzip;
 2185 #ifdef REG_TEST
 2186     bool old_ud, new_ud;
 2187 #endif
 2188 
 2189     if (hi_swap_config == NULL)
 2190         return NULL;
 2191 
 2192     configNew = (HTTPINSPECT_GLOBAL_CONF *)sfPolicyUserDataGetDefault(hi_swap_config);
 2193     configOld = (HTTPINSPECT_GLOBAL_CONF *)sfPolicyUserDataGetDefault(old_config);
 2194 
 2195     old_fd = (sfPolicyUserDataIterate(sc, old_config, HttpInspectFileDecomp) != 0);
 2196     old_gzip = (sfPolicyUserDataIterate(sc, old_config, HttpInspectExtractGzip) != 0);
 2197 
 2198     new_fd = (sfPolicyUserDataIterate(sc, hi_swap_config, HttpInspectFileDecomp) != 0);
 2199     new_gzip = (sfPolicyUserDataIterate(sc, hi_swap_config, HttpInspectExtractGzip) != 0);
 2200 
 2201 
 2202     if( configNew && configOld)
 2203     {
 2204          if(hi_gzip_mempool || hi_fd_conf.fd_MemPool)
 2205          {
 2206 #ifdef REG_TEST
 2207               if( (REG_TEST_EMAIL_FLAG_GZIP_MEMPOOL_ADJUST & getRegTestFlagsForEmail() ) ||
 2208                   (REG_TEST_EMAIL_FLAG_FD_MEMPOOL_ADJUST & getRegTestFlagsForEmail()) )
 2209               {
 2210                     old_ud = (sfPolicyUserDataIterate(sc, old_config, HttpInspectUnlimitedDecompress) != 0);
 2211                     new_ud = (sfPolicyUserDataIterate(sc, hi_swap_config, HttpInspectUnlimitedDecompress) != 0);
 2212                     display_gzip_fd_config_changes(configOld, configNew, old_gzip, new_gzip, old_fd, new_fd, old_ud, new_ud);
 2213               }
 2214 #endif
 2215               if((configOld->max_gzip_mem  != configNew->max_gzip_mem) ||
 2216                  (old_gzip != new_gzip) ||
 2217                  (old_fd != new_fd) )
 2218               {
 2219                    update_gzip_fd_mempools(configNew, old_gzip, new_gzip, old_fd, new_fd);
 2220               }
 2221 
 2222          }
 2223          if(http_mempool)
 2224          {
 2225               if(configOld->memcap != configNew->memcap)
 2226               {
 2227                    update_http_mempool(configNew->memcap, configOld->memcap);
 2228               }
 2229          }
 2230          if(mime_decode_mempool)
 2231          {
 2232               if( (configOld->decode_conf.max_mime_mem != configNew->decode_conf.max_mime_mem) ||
 2233                   (configOld->decode_conf.max_depth != configNew->decode_conf.max_depth) )
 2234               {
 2235 #ifdef REG_TEST
 2236                   displayMimeMempool(mime_decode_mempool,&(configOld->decode_conf), &(configNew->decode_conf));
 2237 #endif
 2238                   /* Update the mime_decode_mempool with new max_memmory and object size when max_mime_mem changes. */
 2239                   update_mime_mempool(mime_decode_mempool, configNew->decode_conf.max_mime_mem, configNew->decode_conf.max_depth);
 2240              }
 2241          }
 2242          if(mime_log_mempool)
 2243          {
 2244               if(configOld->mime_conf.memcap != configNew->mime_conf.memcap )
 2245               {
 2246 #ifdef REG_TEST
 2247                   displayLogMempool(mime_log_mempool, configOld->mime_conf.memcap, configNew->mime_conf.memcap);
 2248 #endif
 2249                   /* Update the mime_log_mempool with new max_memory and objest size when memcap changes. */
 2250                   update_log_mempool(mime_log_mempool, configNew->mime_conf.memcap, 0);
 2251               }
 2252           }
 2253 #ifdef REG_TEST
 2254           displayDecodeDepth(&(configOld->decode_conf), &(configNew->decode_conf));
 2255 #endif
 2256 
 2257     }
 2258 
 2259     hi_config = hi_swap_config;
 2260 
 2261     return (void *)old_config;
 2262 }
 2263 
 2264 static void HttpInspectReloadSwapFree(void *data)
 2265 {
 2266     if (data == NULL)
 2267         return;
 2268 
 2269     HttpInspectFreeConfigs((tSfPolicyUserContextId)data);
 2270 }
 2271 #endif
 2272 
 2273 static inline void InitLookupTables(void)
 2274 {
 2275     int iNum;
 2276     int iCtr;
 2277 
 2278     memset(hex_lookup, INVALID_HEX_VAL, sizeof(hex_lookup));
 2279     memset(valid_lookup, INVALID_HEX_VAL, sizeof(valid_lookup));
 2280 
 2281     iNum = 0;
 2282     for(iCtr = 48; iCtr < 58; iCtr++)
 2283     {
 2284         hex_lookup[iCtr] = iNum;
 2285         valid_lookup[iCtr] = HEX_VAL;
 2286         iNum++;
 2287     }
 2288 
 2289     /*
 2290     * Set the upper case values.
 2291     */
 2292     iNum = 10;
 2293     for(iCtr = 65; iCtr < 71; iCtr++)
 2294     {
 2295         hex_lookup[iCtr] = iNum;
 2296         valid_lookup[iCtr] = HEX_VAL;
 2297         iNum++;
 2298     }
 2299 
 2300     /*
 2301      *  Set the lower case values.
 2302      */
 2303     iNum = 10;
 2304     for(iCtr = 97; iCtr < 103; iCtr++)
 2305     {
 2306         hex_lookup[iCtr] = iNum;
 2307         valid_lookup[iCtr] = HEX_VAL;
 2308         iNum++;
 2309    }
 2310 }
 2311