00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 #include <stdlib.h>
00033 #include <string.h>
00034 #include <sys/types.h>
00035 #ifndef WIN32
00036 #include <sys/socket.h>
00037 #include <netinet/in.h>
00038 #include <arpa/inet.h>
00039 #endif
00040 
00041 #include "snort.h"
00042 #include "detect.h"
00043 #include "decode.h"
00044 #include "log.h"
00045 #include "event.h"
00046 #include "generators.h"
00047 #include "debug.h"
00048 #include "plugbase.h"
00049 #include "util.h"
00050 #include "event_queue.h"
00051 #include "stream.h"
00052 
00053 #include "hi_return_codes.h"
00054 #include "hi_ui_config.h"
00055 #include "hi_ui_iis_unicode_map.h"
00056 #include "hi_si.h"
00057 #include "hi_mi.h"
00058 #include "hi_norm.h"
00059 
00060 extern PV pv;
00061 
00062 #define MAX_FILENAME    1000
00063 
00064 
00065 
00066 
00067 
00068 #define CONF_SEPARATORS " \t\n\r"
00069 
00070 
00071 
00072 
00073 
00074 
00075 #define GLOBAL        "global"
00076 #define GLOBAL_SERVER "global_server"
00077 #define SERVER        "server"
00078 
00079 
00080 
00081 
00082 
00083 
00084 
00085 #define MAX_PIPELINE  "max_pipeline"
00086 
00087 
00088 
00089 
00090 #define ANOMALOUS_SERVERS "detect_anomalous_servers"
00091 
00092 
00093 
00094 #define PROXY_ALERT "proxy_alert"
00095 
00096 
00097 
00098 
00099 #define INSPECT_TYPE  "inspection_type"
00100 #define DEFAULT       "default"
00101 
00102 
00103 
00104 
00105 #define INSPECT_TYPE_STATELESS "stateless"
00106 #define INSPECT_TYPE_STATEFUL  "stateful"
00107 
00108 
00109 
00110 
00111 #define PORTS             "ports"
00112 #define FLOW_DEPTH        "flow_depth"
00113 #define IIS_UNICODE_MAP   "iis_unicode_map"
00114 #define CHUNK_LENGTH      "chunk_length"
00115 #define PIPELINE          "no_pipeline_req"
00116 #define ASCII             "ascii"
00117 #define DOUBLE_DECODE     "double_decode"
00118 #define U_ENCODE          "u_encode"
00119 #define BARE_BYTE         "bare_byte"
00120 #define BASE36            "base36"
00121 #define UTF_8             "utf_8"
00122 #define IIS_UNICODE       "iis_unicode"
00123 #define NON_RFC_CHAR      "non_rfc_char"
00124 #define MULTI_SLASH       "multi_slash"
00125 #define IIS_BACKSLASH     "iis_backslash"
00126 #define DIRECTORY         "directory"
00127 #define APACHE_WS         "apache_whitespace"
00128 #define IIS_DELIMITER     "iis_delimiter"
00129 #define PROFILE           "profile"
00130 #define NON_STRICT        "non_strict"
00131 #define ALLOW_PROXY       "allow_proxy_use"
00132 #define OVERSIZE_DIR      "oversize_dir_length"
00133 #define INSPECT_URI_ONLY  "inspect_uri_only"
00134 #define GLOBAL_ALERT      "no_alerts"
00135 #define WEBROOT           "webroot"
00136 #define TAB_URI_DELIMITER "tab_uri_delimiter"
00137 
00138 
00139 
00140 
00141 #define BOOL_YES     "yes"
00142 #define BOOL_NO      "no"
00143 
00144 
00145 
00146 
00147 #define APACHE        "apache"
00148 #define IIS           "iis"
00149 #define ALL           "all"
00150 
00151 
00152 
00153 
00154 #define START_PORT_LIST "{"
00155 #define END_PORT_LIST   "}"
00156 
00157 
00158 
00159 
00160 #define SERVER_DEFAULT "default"
00161 
00162 
00163 
00164 
00165 
00166 
00167 
00168 
00169 
00170 
00171 
00172 
00173 
00174 
00175 
00176 
00177 
00178 
00179 
00180 
00181 
00182 
00183 
00184 
00185 
00186 
00187 
00188 
00189 
00190 
00191 
00192 
00193 
00194 
00195 
00196 
00197 
00198 
00199 
00200 
00201 
00202 
00203 
00204 
00205 
00206 
00207 
00208 
00209 
00210 
00211 
00212 
00213 
00214 
00215 
00216 
00217 static int ProcessMaxPipeline(HTTPINSPECT_GLOBAL_CONF *GlobalConf,
00218                               char *ErrorString, int ErrStrLen)
00219 {
00220     char *pcToken;
00221     char *pcEnd = NULL;
00222 
00223     pcToken = strtok(NULL, CONF_SEPARATORS);
00224     if(pcToken == NULL)
00225     {
00226         snprintf(ErrorString, ErrStrLen,
00227                 "No argument to token '%s'.", MAX_PIPELINE);
00228 
00229         return -1;
00230     }
00231 
00232     GlobalConf->max_pipeline_requests = strtol(pcToken, &pcEnd, 10);
00233 
00234     
00235 
00236 
00237 
00238 
00239     if(*pcEnd)
00240     {
00241         snprintf(ErrorString, ErrStrLen,
00242                 "Invalid argument to token '%s'.  Must be a positive "
00243                 "number between 0 and %d.", MAX_PIPELINE,
00244                 HI_UI_CONFIG_MAX_PIPE);
00245 
00246         return -1;
00247     }
00248 
00249     if(GlobalConf->max_pipeline_requests < 0 || 
00250        GlobalConf->max_pipeline_requests > HI_UI_CONFIG_MAX_PIPE)
00251     {
00252         snprintf(ErrorString, ErrStrLen,
00253                 "Invalid argument to token '%s'.  Must be a positive "
00254                 "number between 0 and %d.", MAX_PIPELINE, HI_UI_CONFIG_MAX_PIPE);
00255 
00256         return -1;
00257     }
00258 
00259     return 0;
00260 }
00261 
00262 
00263 
00264 
00265 
00266 
00267 
00268 
00269 
00270 
00271 
00272 
00273 
00274 
00275 
00276 
00277 
00278 
00279 
00280 
00281 
00282 
00283 static int ProcessInspectType(HTTPINSPECT_GLOBAL_CONF *GlobalConf,
00284                               char *ErrorString, int ErrStrLen)
00285 {
00286     char *pcToken;
00287 
00288     pcToken = strtok(NULL, CONF_SEPARATORS);
00289     if(pcToken == NULL)
00290     {
00291         snprintf(ErrorString, ErrStrLen,
00292                 "No argument to token '%s'.", INSPECT_TYPE);
00293 
00294         return -1;
00295     }
00296 
00297     if(!strcmp(INSPECT_TYPE_STATEFUL, pcToken))
00298     {
00299         GlobalConf->inspection_type = HI_UI_CONFIG_STATEFUL;
00300 
00301         
00302 
00303 
00304 
00305         snprintf(ErrorString, ErrStrLen,
00306                  "Stateful HttpInspect processing is not yet available.  "
00307                  "Please use stateless processing for now.");
00308 
00309         return -1;
00310     }
00311     else if(!strcmp(INSPECT_TYPE_STATELESS, pcToken))
00312     {
00313         GlobalConf->inspection_type = HI_UI_CONFIG_STATELESS;
00314     }
00315     else
00316     {
00317         snprintf(ErrorString, ErrStrLen,
00318                 "Invalid argument to token '%s'.  Must be either "
00319                 "'%s' or '%s'.", INSPECT_TYPE, INSPECT_TYPE_STATEFUL,
00320                 INSPECT_TYPE_STATELESS);
00321 
00322         return -1;
00323     }
00324 
00325     return 0;
00326 }
00327 
00328 static int ProcessIISUnicodeMap(int **iis_unicode_map, 
00329                                 char **iis_unicode_map_filename,
00330                                 int *iis_unicode_map_codepage,
00331                                 char *ErrorString, int ErrStrLen)
00332 {
00333     char *pcToken;
00334     int  iRet;
00335     char filename[MAX_FILENAME];
00336     char *pcEnd;
00337     int  iCodeMap;
00338 
00339     pcToken = strtok(NULL, CONF_SEPARATORS);
00340     if(pcToken == NULL)
00341     {
00342         snprintf(ErrorString, ErrStrLen,
00343                  "No argument to token '%s'.", IIS_UNICODE_MAP);
00344 
00345         return -1;
00346     }
00347 
00348     
00349 
00350 
00351 #ifndef WIN32
00352     if(pcToken[0] == '/')
00353     {
00354         iRet = snprintf(filename, sizeof(filename), "%s", pcToken);
00355     }
00356     else
00357     {
00358         
00359 
00360 
00361         if(pv.config_dir[strlen(pv.config_dir)-1] == '/')
00362         {
00363             iRet = snprintf(filename, sizeof(filename), 
00364                             "%s%s", pv.config_dir, pcToken);
00365         }
00366         else
00367         {
00368             iRet = snprintf(filename, sizeof(filename),
00369                             "%s/%s", pv.config_dir, pcToken);
00370         }
00371     }
00372 #else
00373     if(strlen(pcToken)>3 && pcToken[1]==':' && pcToken[2]=='\\')
00374     {
00375         iRet = snprintf(filename, sizeof(filename), "%s", pcToken);
00376     }
00377     else
00378     {
00379         
00380 
00381 
00382         if(pv.config_dir[strlen(pv.config_dir)-1] == '\\' ||
00383            pv.config_dir[strlen(pv.config_dir)-1] == '/' )
00384         {
00385             iRet = snprintf(filename, sizeof(filename), 
00386                             "%s%s", pv.config_dir, pcToken);
00387         }
00388         else
00389         {
00390             iRet = snprintf(filename, sizeof(filename),
00391                             "%s\\%s", pv.config_dir, pcToken);
00392         }
00393     }
00394 #endif
00395 
00396     if(iRet < 0)
00397     {
00398         snprintf(ErrorString, ErrStrLen,
00399                  "Filename too long for token '%s'.", IIS_UNICODE_MAP);
00400 
00401         return -1;
00402     }
00403 
00404     
00405 
00406 
00407     *iis_unicode_map_filename = strdup(filename);
00408     if(*iis_unicode_map_filename == NULL)
00409     {
00410         snprintf(ErrorString, ErrStrLen,
00411                  "Could not strdup() '%s' filename.",
00412                  IIS_UNICODE_MAP);
00413 
00414         return -1;
00415     }
00416 
00417     pcToken = strtok(NULL, CONF_SEPARATORS);
00418     if(pcToken == NULL)
00419     {
00420         snprintf(ErrorString, ErrStrLen,
00421                  "No codemap to select from IIS Unicode Map file.");
00422 
00423         return -1;
00424     }
00425 
00426     
00427 
00428 
00429     iCodeMap = strtol(pcToken, &pcEnd, 10);
00430     if(*pcEnd || iCodeMap < 0)
00431     {
00432         snprintf(ErrorString, ErrStrLen,
00433                  "Invalid IIS codemap argument.");
00434 
00435         return -1;
00436     }
00437 
00438     
00439 
00440 
00441     *iis_unicode_map_codepage = iCodeMap;
00442 
00443     
00444 
00445 
00446 
00447     if((iRet = hi_ui_parse_iis_unicode_map(iis_unicode_map, 
00448                                            filename, iCodeMap)))
00449     {
00450         if(iRet == HI_INVALID_FILE)
00451         {
00452             snprintf(ErrorString, ErrStrLen,
00453                      "Unable to open the IIS Unicode Map file '%s'.",
00454                      filename);
00455         }
00456         else if(iRet == HI_FATAL_ERR)
00457         {
00458             snprintf(ErrorString, ErrStrLen,
00459                      "Did not find specified IIS Unicode codemap in "
00460                      "the specified IIS Unicode Map file.");
00461         }
00462         else
00463         {
00464             snprintf(ErrorString, ErrStrLen,
00465                      "There was an error while parsing the IIS Unicode "
00466                      "Map file.");
00467         }
00468 
00469         return -1;
00470     }
00471 
00472     return 0;
00473 }
00474 
00475 static int ProcessOversizeDir(HTTPINSPECT_CONF *ServerConf,
00476                               char *ErrorString, int ErrStrLen)
00477 {
00478     char *pcToken;
00479     char *pcEnd;
00480     int  iDirLen;
00481 
00482     pcToken = strtok(NULL, CONF_SEPARATORS);
00483     if(pcToken == NULL)
00484     {
00485         snprintf(ErrorString, ErrStrLen,
00486                  "No argument to token '%s'.", OVERSIZE_DIR);
00487 
00488         return -1;
00489     }
00490 
00491     
00492 
00493 
00494     iDirLen = strtol(pcToken, &pcEnd, 10);
00495     if(*pcEnd || iDirLen < 0)
00496     {
00497         snprintf(ErrorString, ErrStrLen,
00498                  "Invalid argument to token '%s'.", OVERSIZE_DIR);
00499         
00500         return -1;
00501     }
00502 
00503     ServerConf->long_dir = iDirLen;
00504 
00505     return 0;
00506 }
00507 
00508 
00509 
00510 
00511 
00512 
00513 
00514 
00515 
00516 
00517 
00518 
00519 
00520 
00521 
00522 
00523 
00524 
00525 
00526 
00527 
00528 
00529 
00530 
00531 
00532 
00533 
00534 
00535 
00536 
00537 
00538 
00539 
00540 
00541 static int ProcessGlobalConf(HTTPINSPECT_GLOBAL_CONF *GlobalConf,
00542                              char *ErrorString, int ErrStrLen)
00543 {
00544     int  iRet;
00545     char *pcToken;
00546     int  iTokens = 0;
00547 
00548     while((pcToken = strtok(NULL, CONF_SEPARATORS)))
00549     {
00550         
00551 
00552 
00553         iTokens = 1;
00554 
00555         
00556 
00557 
00558         if(!strcmp(MAX_PIPELINE, pcToken))
00559         {
00560             if((iRet = ProcessMaxPipeline(GlobalConf, ErrorString, ErrStrLen)))
00561             {
00562                 return iRet;
00563             }
00564         }
00565         else if(!strcmp(INSPECT_TYPE, pcToken))
00566         {
00567             if((iRet = ProcessInspectType(GlobalConf, ErrorString, ErrStrLen)))
00568             {
00569                 return iRet;
00570             }
00571         }
00572         else if(!strcmp(IIS_UNICODE_MAP, pcToken))
00573         {
00574             if((iRet = ProcessIISUnicodeMap(&GlobalConf->iis_unicode_map,
00575                                          &GlobalConf->iis_unicode_map_filename,
00576                                             &GlobalConf->iis_unicode_codepage,
00577                                             ErrorString,ErrStrLen)))
00578             {
00579                 return iRet;
00580             }
00581         }
00582         else if(!strcmp(ANOMALOUS_SERVERS, pcToken))
00583         {
00584             
00585 
00586 
00587 
00588             GlobalConf->anomalous_servers = 1;
00589         }
00590         else if(!strcmp(PROXY_ALERT, pcToken))
00591         {
00592             GlobalConf->proxy_alert = 1;
00593         }
00594         else
00595         {
00596             snprintf(ErrorString, ErrStrLen,
00597                     "Invalid keyword '%s' for '%s' configuration.", 
00598                      pcToken, GLOBAL);
00599 
00600             return -1;
00601         }
00602     }
00603 
00604     
00605 
00606 
00607 
00608 
00609     if(!iTokens)
00610     {
00611         snprintf(ErrorString, ErrStrLen,
00612                 "No tokens to '%s' configuration.", GLOBAL);
00613 
00614         return -1;
00615     }
00616 
00617     
00618 
00619 
00620     if(!GlobalConf->iis_unicode_map)
00621     {
00622         snprintf(ErrorString, ErrStrLen,
00623                  "Global configuration must contain an IIS Unicode Map "
00624                  "configuration.  Use token '%s'.", IIS_UNICODE_MAP);
00625 
00626         return -1;
00627     }
00628 
00629     return 0;
00630 }
00631 
00632 
00633 
00634 
00635 
00636 
00637 
00638 
00639 
00640 
00641 
00642 
00643 
00644 
00645 
00646 
00647 
00648 
00649 
00650 
00651 
00652 
00653 
00654 
00655 static int ProcessProfile(HTTPINSPECT_GLOBAL_CONF *GlobalConf,
00656                           HTTPINSPECT_CONF *ServerConf,
00657                           char *ErrorString, int ErrStrLen)
00658 {
00659     char *pcToken;
00660     int  iRet;
00661 
00662     pcToken = strtok(NULL, CONF_SEPARATORS);
00663     if(pcToken == NULL)
00664     {
00665         snprintf(ErrorString, ErrStrLen,
00666                 "No argument to '%s'.", PROFILE);
00667 
00668         return -1;
00669     }
00670 
00671     
00672 
00673 
00674     if(!strcmp(APACHE, pcToken))
00675     {
00676         if((iRet = hi_ui_config_set_profile_apache(ServerConf)))
00677         {
00678             if(iRet == HI_MEM_ALLOC_FAIL)
00679             {
00680                 snprintf(ErrorString, ErrStrLen,
00681                         "Memory allocation failed while setting the '%s' "
00682                         "profile.", APACHE);
00683 
00684                 return -1;
00685             }
00686             else
00687             {
00688                 snprintf(ErrorString, ErrStrLen,
00689                         "Undefined error code for set_profile_apache.");
00690 
00691                 return -1;
00692             }
00693         }
00694     }
00695     else if(!strcmp(IIS, pcToken))
00696     {
00697         if((iRet = hi_ui_config_set_profile_iis(ServerConf, 
00698                                                 GlobalConf->iis_unicode_map)))
00699         {
00700             if(iRet == HI_MEM_ALLOC_FAIL)
00701             {
00702                 snprintf(ErrorString, ErrStrLen,
00703                         "Memory allocation failed while setting the '%s' "
00704                         "profile.", IIS);
00705 
00706                 return -1;
00707             }
00708             else
00709             {
00710                 snprintf(ErrorString, ErrStrLen,
00711                         "Undefined error code for set_profile_iis.");
00712 
00713                 return -1;
00714             }
00715         }
00716     }
00717     else if(!strcmp(ALL, pcToken))
00718     {
00719         if((iRet = hi_ui_config_set_profile_all(ServerConf,
00720                                                 GlobalConf->iis_unicode_map)))
00721         {
00722             if(iRet == HI_MEM_ALLOC_FAIL)
00723             {
00724                 snprintf(ErrorString, ErrStrLen,
00725                         "Memory allocation failed while setting the '%s' "
00726                         "profile.", ALL);
00727 
00728                 return -1;
00729             }
00730             else
00731             {
00732                 snprintf(ErrorString, ErrStrLen,
00733                         "Undefined error code for set_profile_all.");
00734 
00735                 return -1;
00736             }
00737         }
00738     }
00739     else
00740     {
00741         snprintf(ErrorString, ErrStrLen,
00742                 "Invalid profile argument '%s'.", pcToken);
00743 
00744         return -1;
00745     }
00746 
00747     return 0;
00748 }
00749 
00750 
00751 
00752 
00753 
00754 
00755 
00756 
00757 
00758 
00759 
00760 
00761 
00762 
00763 
00764 
00765 
00766 
00767 
00768 
00769 
00770 
00771 static int ProcessPorts(HTTPINSPECT_CONF *ServerConf,
00772                         char *ErrorString, int ErrStrLen)
00773 {
00774     char *pcToken;
00775     char *pcEnd;
00776     int  iPort;
00777     int  iEndPorts = 0;
00778 
00779     pcToken = strtok(NULL, CONF_SEPARATORS);
00780     if(!pcToken)
00781     {
00782         snprintf(ErrorString, ErrStrLen,
00783                 "Invalid port list format.");
00784 
00785         return -1;
00786     }
00787 
00788     if(strcmp(START_PORT_LIST, pcToken))
00789     {
00790         snprintf(ErrorString, ErrStrLen,
00791                 "Must start a port list with the '%s' token.",
00792                 START_PORT_LIST);
00793 
00794         return -1;
00795     }
00796     
00797     while((pcToken = strtok(NULL, CONF_SEPARATORS)))
00798     {
00799         if(!strcmp(END_PORT_LIST, pcToken))
00800         {
00801             iEndPorts = 1;
00802             break;
00803         }
00804 
00805         iPort = strtol(pcToken, &pcEnd, 10);
00806 
00807         
00808 
00809 
00810         if(*pcEnd)
00811         {
00812             snprintf(ErrorString, ErrStrLen,
00813                     "Invalid port number.");
00814 
00815             return -1;
00816         }
00817 
00818         if(iPort < 0 || iPort > 65535)
00819         {
00820             snprintf(ErrorString, ErrStrLen,
00821                     "Invalid port number.  Must be between 0 and "
00822                     "65535.");
00823 
00824             return -1;
00825         }
00826 
00827         ServerConf->ports[iPort] = 1;
00828 
00829         if(ServerConf->port_count < 65536)
00830             ServerConf->port_count++;
00831     }
00832 
00833     if(!iEndPorts)
00834     {
00835         snprintf(ErrorString, ErrStrLen,
00836                 "Must end '%s' configuration with '%s'.",
00837                 PORTS, END_PORT_LIST);
00838 
00839         return -1;
00840     }
00841 
00842     return 0;
00843 }
00844 
00845 
00846 
00847 
00848 
00849 
00850 
00851 
00852 
00853 
00854 
00855 
00856 
00857 
00858 
00859 
00860 
00861 
00862 
00863 
00864 
00865 
00866 static int ProcessFlowDepth(HTTPINSPECT_CONF *ServerConf,
00867                             char *ErrorString, int ErrStrLen)
00868 {
00869     char *pcToken;
00870     int  iFlowDepth;
00871     char *pcEnd;
00872 
00873     pcToken = strtok(NULL, CONF_SEPARATORS);
00874     if(pcToken == NULL)
00875     {
00876         snprintf(ErrorString, ErrStrLen,
00877                 "No argument to '%s' token.", FLOW_DEPTH);
00878 
00879         return -1;
00880     }
00881 
00882     iFlowDepth = strtol(pcToken, &pcEnd, 10);
00883     if(*pcEnd)
00884     {
00885         snprintf(ErrorString, ErrStrLen,
00886                 "Invalid argument to '%s'.", FLOW_DEPTH);
00887 
00888         return -1;
00889     }
00890 
00891     
00892     if(iFlowDepth < -1 || iFlowDepth > 1460)
00893     {
00894         snprintf(ErrorString, ErrStrLen,
00895                 "Invalid argument to '%s'.  Must be between 0 and "
00896                 "1460.", FLOW_DEPTH);
00897 
00898         return -1;
00899     }
00900 
00901     ServerConf->flow_depth = iFlowDepth;
00902 
00903     return 0;
00904 }
00905 
00906 
00907 
00908 
00909 
00910 
00911 
00912 
00913 
00914 
00915 
00916 
00917 
00918 
00919 
00920 
00921 
00922 
00923 
00924 static int ProcessChunkLength(HTTPINSPECT_CONF *ServerConf,
00925                               char *ErrorString, int ErrStrLen)
00926 {
00927     char *pcToken;
00928     int  iChunkLength;
00929     char *pcEnd;
00930 
00931     pcToken = strtok(NULL, CONF_SEPARATORS);
00932     if(pcToken == NULL)
00933     {
00934         snprintf(ErrorString, ErrStrLen,
00935                 "No argument to '%s' token.", CHUNK_LENGTH);
00936 
00937         return -1;
00938     }
00939 
00940     iChunkLength = strtol(pcToken, &pcEnd, 10);
00941     if(*pcEnd)
00942     {
00943         snprintf(ErrorString, ErrStrLen,
00944                 "Invalid argument to '%s'.", CHUNK_LENGTH);
00945 
00946         return -1;
00947     }
00948 
00949     if(iChunkLength < 0)
00950     {
00951         snprintf(ErrorString, ErrStrLen,
00952                 "Invalid argument to '%s'.", CHUNK_LENGTH);
00953 
00954         return -1;
00955     }
00956 
00957     ServerConf->chunk_length = iChunkLength;
00958 
00959     return 0;
00960 }
00961 
00962 
00963 
00964 
00965 
00966 
00967 
00968 
00969 
00970 
00971 
00972 
00973 
00974 
00975 
00976 
00977 
00978 
00979 
00980 
00981 
00982 
00983 
00984 
00985 static int ProcessConfOpt(HTTPINSPECT_CONF_OPT *ConfOpt, char *Option,
00986                           char *ErrorString, int ErrStrLen)
00987 {
00988     char *pcToken;
00989 
00990     pcToken = strtok(NULL, CONF_SEPARATORS);
00991     if(pcToken == NULL)
00992     {
00993         snprintf(ErrorString, ErrStrLen,
00994                 "No argument to token '%s'.", Option);
00995 
00996         return -1;
00997     }
00998 
00999     
01000 
01001 
01002     if(!strcmp(BOOL_YES, pcToken))
01003     {
01004         ConfOpt->alert = 1;
01005     }
01006     else if(!strcmp(BOOL_NO, pcToken))
01007     {
01008         ConfOpt->alert = 0;
01009     }
01010     else
01011     {
01012         snprintf(ErrorString, ErrStrLen,
01013                 "Invalid argument to token '%s'.", Option);
01014 
01015         return -1;
01016     }
01017 
01018     ConfOpt->on = 1;
01019 
01020     return 0;
01021 }
01022 
01023 
01024 
01025 
01026 
01027 
01028 
01029 
01030 
01031 
01032 
01033 
01034 
01035 
01036 
01037 
01038 
01039 
01040 
01041 
01042 
01043 
01044 
01045 static int ProcessNonRfcChar(HTTPINSPECT_CONF *ServerConf,
01046                              char *ErrorString, int ErrStrLen)
01047 {
01048     char *pcToken;
01049     char *pcEnd;
01050     int  iChar;
01051     int  iEndChar = 0;
01052 
01053     pcToken = strtok(NULL, CONF_SEPARATORS);
01054     if(!pcToken)
01055     {
01056         snprintf(ErrorString, ErrStrLen,
01057                 "Invalid '%s' list format.", NON_RFC_CHAR);
01058 
01059         return -1;
01060     }
01061 
01062     if(strcmp(START_PORT_LIST, pcToken))
01063     {
01064         snprintf(ErrorString, ErrStrLen,
01065                 "Must start a '%s' list with the '%s' token.",
01066                 NON_RFC_CHAR, START_PORT_LIST);
01067 
01068         return -1;
01069     }
01070     
01071     while((pcToken = strtok(NULL, CONF_SEPARATORS)))
01072     {
01073         if(!strcmp(END_PORT_LIST, pcToken))
01074         {
01075             iEndChar = 1;
01076             break;
01077         }
01078 
01079         iChar = strtol(pcToken, &pcEnd, 16);
01080         if(*pcEnd)
01081         {
01082             snprintf(ErrorString, ErrStrLen,
01083                     "Invalid argument to '%s'.  Must be a single "
01084                     "character.", NON_RFC_CHAR);
01085 
01086             return -1;
01087         }
01088 
01089         if(iChar < 0 || iChar > 255)
01090         {
01091             snprintf(ErrorString, ErrStrLen,
01092                     "Invalid character value to '%s'.  Must be a single "
01093                     "character no greater than 255.", NON_RFC_CHAR);
01094 
01095             return -1;
01096         }
01097 
01098         ServerConf->non_rfc_chars[iChar] = 1;
01099     }
01100 
01101     if(!iEndChar)
01102     {
01103         snprintf(ErrorString, ErrStrLen,
01104                 "Must end '%s' configuration with '%s'.",
01105                 NON_RFC_CHAR, END_PORT_LIST);
01106 
01107         return -1;
01108     }
01109 
01110     return 0;
01111 }
01112 
01113 
01114 
01115 
01116 
01117 
01118 
01119 
01120 
01121 
01122 
01123 
01124 
01125 
01126 
01127 
01128 
01129 
01130 
01131 
01132 
01133 
01134 
01135 static int ProcessServerConf(HTTPINSPECT_GLOBAL_CONF *GlobalConf,
01136                              HTTPINSPECT_CONF *ServerConf,
01137                              char *ErrorString, int ErrStrLen)
01138 {
01139     char *pcToken;
01140     int  iRet;
01141     int  iPorts = 0;
01142     HTTPINSPECT_CONF_OPT *ConfOpt;
01143 
01144     
01145 
01146 
01147 
01148     pcToken = strtok(NULL, CONF_SEPARATORS);
01149     if(pcToken == NULL)
01150     {
01151         snprintf(ErrorString, ErrStrLen,
01152                 "No tokens to '%s' configuration.", GLOBAL);
01153 
01154         return 1;
01155     }
01156 
01157     if(!strcmp(PROFILE, pcToken))
01158     {
01159         if((iRet = ProcessProfile(GlobalConf, ServerConf,
01160                                   ErrorString, ErrStrLen)))
01161         {
01162             return iRet;
01163         }
01164 
01165         pcToken = strtok(NULL, CONF_SEPARATORS);
01166         if(pcToken == NULL)
01167         {
01168             snprintf(ErrorString, ErrStrLen,
01169                      "No port list to the profile token.");
01170 
01171             return -1;
01172         }
01173 
01174         do
01175         {
01176             if(!strcmp(PORTS, pcToken))
01177             {
01178                 if((iRet = ProcessPorts(ServerConf, 
01179                                         ErrorString, ErrStrLen)))
01180                 {
01181                     return iRet;
01182                 }
01183 
01184                 iPorts = 1;
01185             }
01186             else if(!strcmp(IIS_UNICODE_MAP, pcToken))
01187             {
01188                 if((iRet = ProcessIISUnicodeMap(&ServerConf->iis_unicode_map,
01189                                          &ServerConf->iis_unicode_map_filename,
01190                                              &ServerConf->iis_unicode_codepage,
01191                                                 ErrorString,ErrStrLen)))
01192                 {
01193                     return -1;
01194                 }
01195             }
01196             else if(!strcmp(ALLOW_PROXY, pcToken))
01197             {
01198                 ServerConf->allow_proxy = 1;
01199             }
01200             else if(!strcmp(FLOW_DEPTH, pcToken))
01201             {
01202                 if((iRet = ProcessFlowDepth(ServerConf, 
01203                                             ErrorString, ErrStrLen)))
01204                 {
01205                     return iRet;
01206                 }
01207             }
01208             else if(!strcmp(GLOBAL_ALERT, pcToken))
01209             {
01210                 ServerConf->no_alerts = 1;
01211             }
01212             else if(!strcmp(OVERSIZE_DIR, pcToken))
01213             {
01214                 if((iRet = ProcessOversizeDir(ServerConf, 
01215                                               ErrorString, ErrStrLen)))
01216                 {
01217                     return iRet;
01218                 }
01219  
01220             }
01221             else if(!strcmp(INSPECT_URI_ONLY, pcToken))
01222             {
01223                 ServerConf->uri_only = 1;
01224             }
01225             else
01226             {
01227                 snprintf(ErrorString, ErrStrLen,
01228                          "Invalid token while configuring the profile token.  "
01229                          "The only allowed tokens when configuring profiles "
01230                          "are: '%s', '%s', '%s', '%s', '%s', '%s', and '%s'.",
01231                          PORTS,IIS_UNICODE_MAP, ALLOW_PROXY, FLOW_DEPTH,
01232                          GLOBAL_ALERT, OVERSIZE_DIR, INSPECT_URI_ONLY);
01233 
01234                 return -1;
01235             }
01236 
01237         } while((pcToken = strtok(NULL, CONF_SEPARATORS)));
01238 
01239         if(!iPorts)
01240         {
01241             snprintf(ErrorString, ErrStrLen,
01242                      "No port list to the profile token.");
01243 
01244             return -1;
01245         }
01246 
01247         return 0;
01248     }
01249 
01250     
01251 
01252 
01253 
01254     do
01255     {
01256         if(!strcmp(PORTS, pcToken))
01257         {
01258             if((iRet = ProcessPorts(ServerConf, 
01259                                     ErrorString, ErrStrLen)))
01260             {
01261                 return iRet;
01262             }
01263         }
01264         else if(!strcmp(FLOW_DEPTH, pcToken))
01265         {
01266             if((iRet = ProcessFlowDepth(ServerConf, 
01267                                         ErrorString, ErrStrLen)))
01268             {
01269                 return iRet;
01270             }
01271         }
01272         else if(!strcmp(IIS_UNICODE_MAP, pcToken))
01273         {
01274             if((iRet = ProcessIISUnicodeMap(&ServerConf->iis_unicode_map,
01275                                          &ServerConf->iis_unicode_map_filename,
01276                                             &ServerConf->iis_unicode_codepage,
01277                                             ErrorString, ErrStrLen)))
01278             {
01279                 return iRet;
01280             }
01281         }
01282         else if(!strcmp(CHUNK_LENGTH, pcToken))
01283         {
01284             if((iRet = ProcessChunkLength(ServerConf,ErrorString,ErrStrLen )))
01285             {
01286                 return iRet;
01287             }
01288         }
01289         else if(!strcmp(PIPELINE, pcToken))
01290         {
01291             ServerConf->no_pipeline = 1;
01292         }
01293         else if(!strcmp(NON_STRICT, pcToken))
01294         {
01295             ServerConf->non_strict = 1;
01296         }
01297         else if(!strcmp(ALLOW_PROXY, pcToken))
01298         {
01299             ServerConf->allow_proxy = 1;
01300         }
01301         else if(!strcmp(GLOBAL_ALERT, pcToken))
01302         {
01303             ServerConf->no_alerts = 1;
01304         }
01305         else if(!strcmp(TAB_URI_DELIMITER, pcToken))
01306         {
01307             ServerConf->tab_uri_delimiter = 1;
01308         }        
01309         else if(!strcmp(OVERSIZE_DIR, pcToken))
01310         {
01311             if((iRet = ProcessOversizeDir(ServerConf, 
01312                                           ErrorString, ErrStrLen)))
01313             {
01314                 return iRet;
01315             }
01316  
01317         }
01318         else if(!strcmp(INSPECT_URI_ONLY, pcToken))
01319         {
01320             ServerConf->uri_only = 1;
01321         }
01322 
01323         
01324 
01325 
01326         else if(!strcmp(ASCII, pcToken))
01327         {
01328             ConfOpt = &ServerConf->ascii;
01329             if((iRet = ProcessConfOpt(ConfOpt, ASCII, 
01330                                       ErrorString, ErrStrLen)))
01331             {
01332                 return iRet;
01333             }
01334         }
01335         else if(!strcmp(UTF_8, pcToken))
01336         {
01337             
01338 
01339 
01340             ServerConf->ascii.on    = 1;
01341 
01342             ConfOpt = &ServerConf->utf_8;
01343             if((iRet = ProcessConfOpt(ConfOpt, UTF_8,
01344                                       ErrorString, ErrStrLen)))
01345             {
01346                 return iRet;
01347             }
01348         }
01349         else if(!strcmp(IIS_UNICODE, pcToken))
01350         {
01351             if(ServerConf->iis_unicode_map == NULL)
01352             {
01353                 ServerConf->iis_unicode_map = GlobalConf->iis_unicode_map;
01354             }
01355 
01356             
01357 
01358 
01359 
01360 
01361 
01362 
01363 
01364 
01365             ServerConf->ascii.on           = 1;
01366 
01367             ConfOpt = &ServerConf->iis_unicode;
01368             if((iRet = ProcessConfOpt(ConfOpt, IIS_UNICODE,
01369                                       ErrorString, ErrStrLen)))
01370             {
01371                 return iRet;
01372             }
01373         }
01374         else if(!strcmp(DOUBLE_DECODE, pcToken))
01375         {
01376             ServerConf->ascii.on             = 1;
01377 
01378             ConfOpt = &ServerConf->double_decoding;
01379             if((iRet = ProcessConfOpt(ConfOpt, DOUBLE_DECODE,
01380                                       ErrorString, ErrStrLen)))
01381             {
01382                 return iRet;
01383             }
01384         }
01385         else if(!strcmp(U_ENCODE, pcToken))
01386         {
01387             
01388 
01389 
01390             ServerConf->base36.on = 0;
01391             ServerConf->base36.alert = 0;
01392 
01393             
01394 
01395 
01396 
01397             if(ServerConf->iis_unicode_map == NULL)
01398             {
01399                 ServerConf->iis_unicode_map = GlobalConf->iis_unicode_map;
01400             }
01401 
01402             ConfOpt = &ServerConf->u_encoding;
01403             if((iRet = ProcessConfOpt(ConfOpt, U_ENCODE,
01404                                       ErrorString, ErrStrLen)))
01405             {
01406                 return iRet;
01407             }
01408         }
01409         else if(!strcmp(BARE_BYTE, pcToken))
01410         {
01411             ConfOpt = &ServerConf->bare_byte;
01412             if((iRet = ProcessConfOpt(ConfOpt, BARE_BYTE,
01413                                       ErrorString, ErrStrLen)))
01414             {
01415                 return iRet;
01416             }
01417         }
01418         else if(!strcmp(BASE36, pcToken))
01419         {
01420             ServerConf->ascii.on      = 1;
01421 
01422             
01423 
01424 
01425 
01426             ServerConf->u_encoding.on    = 0;
01427             ServerConf->u_encoding.alert = 0;
01428 
01429             ConfOpt = &ServerConf->base36;
01430             if((iRet = ProcessConfOpt(ConfOpt, BASE36,
01431                                       ErrorString, ErrStrLen)))
01432             {
01433                 return iRet;
01434             }
01435         }
01436         else if(!strcmp(NON_RFC_CHAR, pcToken))
01437         {
01438             if((iRet = ProcessNonRfcChar(ServerConf, ErrorString, ErrStrLen)))
01439             {
01440                 return iRet;
01441             }
01442         }
01443         else if(!strcmp(MULTI_SLASH, pcToken))
01444         {
01445             ConfOpt = &ServerConf->multiple_slash;
01446             if((iRet = ProcessConfOpt(ConfOpt, MULTI_SLASH,
01447                                       ErrorString, ErrStrLen)))
01448             {
01449                 return iRet;
01450             }
01451         }
01452         else if(!strcmp(IIS_BACKSLASH, pcToken))
01453         {
01454             ConfOpt = &ServerConf->iis_backslash;
01455             if((iRet = ProcessConfOpt(ConfOpt, IIS_BACKSLASH,
01456                                       ErrorString, ErrStrLen)))
01457             {
01458                 return iRet;
01459             }
01460         }
01461         else if(!strcmp(DIRECTORY, pcToken))
01462         {
01463             ConfOpt = &ServerConf->directory;
01464             if((iRet = ProcessConfOpt(ConfOpt, DIRECTORY,
01465                                       ErrorString, ErrStrLen)))
01466             {
01467                 return iRet;
01468             }
01469         }
01470         else if(!strcmp(APACHE_WS, pcToken))
01471         {
01472             ConfOpt = &ServerConf->apache_whitespace;
01473             if((iRet = ProcessConfOpt(ConfOpt, APACHE_WS,
01474                                       ErrorString, ErrStrLen)))
01475             {
01476                 return iRet;
01477             }
01478         }
01479         else if(!strcmp(IIS_DELIMITER, pcToken))
01480         {
01481             ConfOpt = &ServerConf->iis_delimiter;
01482             if((iRet = ProcessConfOpt(ConfOpt, IIS_DELIMITER,
01483                                       ErrorString, ErrStrLen)))
01484             {
01485                 return iRet;
01486             }
01487         }
01488         else if(!strcmp(WEBROOT, pcToken))
01489         {
01490             ConfOpt = &ServerConf->webroot;
01491             if((iRet = ProcessConfOpt(ConfOpt, WEBROOT,
01492                                       ErrorString, ErrStrLen)))
01493             {
01494                 return iRet;
01495             }
01496         }
01497         else
01498         {
01499             snprintf(ErrorString, ErrStrLen,
01500                     "Invalid keyword '%s' for server configuration.",
01501                      pcToken);
01502 
01503             return -1;
01504         }
01505     } 
01506     while((pcToken = strtok(NULL, CONF_SEPARATORS)));
01507         
01508     return 0;
01509 }
01510 
01511 static int PrintConfOpt(HTTPINSPECT_CONF_OPT *ConfOpt, char *Option)
01512 {
01513     if(!ConfOpt || !Option)
01514     {
01515         return HI_INVALID_ARG;
01516     }
01517 
01518     if(ConfOpt->on)
01519     {
01520         LogMessage("      %s: YES alert: %s\n", Option,
01521                ConfOpt->alert ? "YES" : "NO");
01522     }
01523     else
01524     {
01525         LogMessage("      %s: OFF\n", Option);
01526     }
01527 
01528     return 0;
01529 }
01530 
01531 static int PrintServerConf(HTTPINSPECT_CONF *ServerConf)
01532 {
01533     char buf[STD_BUF+1];
01534     int iCtr;
01535     int iNonRfcChar = 0;
01536 
01537     if(!ServerConf)
01538     {
01539         return HI_INVALID_ARG;
01540     }
01541 
01542     memset(buf, 0, STD_BUF+1);
01543     snprintf(buf, STD_BUF, "      Ports: ");
01544 
01545     
01546 
01547 
01548     for(iCtr = 0; iCtr < 65536; iCtr++)
01549     {
01550         if(ServerConf->ports[iCtr])
01551         {
01552             sfsnprintfappend(buf, STD_BUF, "%d ", iCtr);
01553         }
01554     }
01555 
01556     LogMessage("%s\n", buf);
01557 
01558     LogMessage("      Flow Depth: %d\n", ServerConf->flow_depth);
01559     LogMessage("      Max Chunk Length: %d\n", ServerConf->chunk_length);
01560     LogMessage("      Inspect Pipeline Requests: %s\n",
01561                ServerConf->no_pipeline ? "NO" : "YES");
01562     LogMessage("      URI Discovery Strict Mode: %s\n",
01563                ServerConf->non_strict ? "NO" : "YES");
01564     LogMessage("      Allow Proxy Usage: %s\n",
01565                ServerConf->allow_proxy ? "YES" : "NO");
01566     LogMessage("      Disable Alerting: %s\n", 
01567                ServerConf->no_alerts ? "YES":"NO");
01568     LogMessage("      Oversize Dir Length: %d\n",
01569                ServerConf->long_dir);
01570     LogMessage("      Only inspect URI: %s\n",
01571                ServerConf->uri_only ? "YES" : "NO");
01572 
01573     PrintConfOpt(&ServerConf->ascii, "Ascii");
01574     PrintConfOpt(&ServerConf->double_decoding, "Double Decoding");
01575     PrintConfOpt(&ServerConf->u_encoding, "%U Encoding");
01576     PrintConfOpt(&ServerConf->bare_byte, "Bare Byte");
01577     PrintConfOpt(&ServerConf->base36, "Base36");
01578     PrintConfOpt(&ServerConf->utf_8, "UTF 8");
01579     PrintConfOpt(&ServerConf->iis_unicode, "IIS Unicode");
01580     PrintConfOpt(&ServerConf->multiple_slash, "Multiple Slash");
01581     PrintConfOpt(&ServerConf->iis_backslash, "IIS Backslash");
01582     PrintConfOpt(&ServerConf->directory, "Directory Traversal");
01583     PrintConfOpt(&ServerConf->webroot, "Web Root Traversal");
01584     PrintConfOpt(&ServerConf->apache_whitespace, "Apache WhiteSpace");
01585     PrintConfOpt(&ServerConf->iis_delimiter, "IIS Delimiter");
01586 
01587     if(ServerConf->iis_unicode_map_filename)
01588     {
01589         LogMessage("      IIS Unicode Map Filename: %s\n",
01590                    ServerConf->iis_unicode_map_filename);
01591         LogMessage("      IIS Unicode Map Codepage: %d\n",
01592                    ServerConf->iis_unicode_codepage);
01593     }
01594     else if(ServerConf->iis_unicode_map)
01595     {
01596         LogMessage("      IIS Unicode Map: "                                    
01597                    "GLOBAL IIS UNICODE MAP CONFIG\n");
01598     }
01599     else
01600     {
01601         LogMessage("      IIS Unicode Map:  NOT CONFIGURED\n");
01602     }
01603 
01604     
01605 
01606 
01607     memset(buf, 0, STD_BUF+1);
01608     snprintf(buf, STD_BUF, "      Non-RFC Compliant Characters: ");
01609     for(iCtr = 0; iCtr < 256; iCtr++)
01610     {
01611         if(ServerConf->non_rfc_chars[iCtr])
01612         {
01613             sfsnprintfappend(buf, STD_BUF, "0x%.2x ", (u_char)iCtr);
01614             iNonRfcChar = 1;
01615         }
01616     }
01617 
01618     if(!iNonRfcChar)
01619     {
01620         sfsnprintfappend(buf, STD_BUF, "NONE");
01621     }
01622 
01623     LogMessage("%s\n", buf);
01624 
01625     return 0;
01626 }
01627 
01628 static int ProcessUniqueServerConf(HTTPINSPECT_GLOBAL_CONF *GlobalConf,
01629                              char *ErrorString, int ErrStrLen)
01630 {
01631     char *pcToken;
01632     unsigned long Ip;
01633     struct in_addr ip_addr;
01634     HTTPINSPECT_CONF *ServerConf;
01635     static int s_iDefaultServer = 0;
01636     int iRet;
01637 
01638     pcToken = strtok(NULL, CONF_SEPARATORS);
01639     if(!pcToken)
01640     {
01641         snprintf(ErrorString, ErrStrLen,
01642                 "No arguments to '%s' token.", SERVER);
01643 
01644         return -1;
01645     }
01646 
01647     
01648 
01649 
01650     if(!strcmp(SERVER_DEFAULT, pcToken))
01651     {
01652         if(s_iDefaultServer)
01653         {
01654             snprintf(ErrorString, ErrStrLen,
01655                     "Cannot configure '%s' settings more than once.",
01656                     GLOBAL_SERVER);
01657 
01658             return -1;
01659         }
01660 
01661         s_iDefaultServer = 1;
01662 
01663         ServerConf = &GlobalConf->global_server;
01664 
01665         
01666 
01667 
01668         if(hi_ui_config_reset_server(ServerConf))
01669         {
01670             snprintf(ErrorString, ErrStrLen,
01671                     "Cannot reset the HttpInspect default server configuration.");
01672 
01673             return -1;
01674         }
01675 
01676         if((iRet = ProcessServerConf(GlobalConf, ServerConf, 
01677                                      ErrorString, ErrStrLen)))
01678         {
01679             return iRet;
01680         }
01681 
01682         
01683 
01684 
01685         LogMessage("    DEFAULT SERVER CONFIG:\n");
01686     }
01687     else
01688     {
01689         
01690 
01691 
01692         Ip = inet_addr(pcToken);
01693         if(Ip == INADDR_NONE)
01694         {
01695             snprintf(ErrorString, ErrStrLen,
01696                     "Invalid IP to '%s' token.", SERVER);
01697 
01698             return -1;
01699         }
01700 
01701         
01702 
01703 
01704         ServerConf = malloc(sizeof(HTTPINSPECT_CONF));
01705         if(!ServerConf)
01706         {
01707             snprintf(ErrorString, ErrStrLen,
01708                     "Could not allocate memory for server configuration.");
01709 
01710             return -1;
01711         }
01712 
01713         memset(ServerConf, 0x00, sizeof(HTTPINSPECT_CONF));
01714 
01715         if((iRet = ProcessServerConf(GlobalConf, ServerConf, 
01716                                      ErrorString, ErrStrLen)))
01717         {
01718             return iRet;
01719         }
01720 
01721         if((iRet = hi_ui_config_add_server(GlobalConf, Ip, ServerConf)))
01722         {
01723             
01724 
01725 
01726             if(iRet == HI_NONFATAL_ERR)
01727             {
01728                 snprintf(ErrorString, ErrStrLen,
01729                         "Duplicate server configuration.");
01730 
01731                 return -1;
01732             }
01733             else
01734             {
01735                 snprintf(ErrorString, ErrStrLen,
01736                         "Error when adding server configuration.");
01737 
01738                 return -1;
01739             }
01740         }
01741 
01742         ip_addr.s_addr = Ip;
01743 
01744         
01745 
01746 
01747         LogMessage("    SERVER: %s\n", inet_ntoa(ip_addr));
01748     }
01749 
01750     
01751 
01752 
01753     PrintServerConf(ServerConf);
01754 
01755     return 0;
01756 }
01757 
01758 static int PrintGlobalConf(HTTPINSPECT_GLOBAL_CONF *GlobalConf)
01759 {
01760     LogMessage("HttpInspect Config:\n");
01761 
01762     LogMessage("    GLOBAL CONFIG\n");
01763     LogMessage("      Max Pipeline Requests:    %d\n", 
01764                GlobalConf->max_pipeline_requests);
01765     LogMessage("      Inspection Type:          %s\n",
01766                GlobalConf->inspection_type ? "STATEFUL" : "STATELESS");
01767     LogMessage("      Detect Proxy Usage:       %s\n",
01768                GlobalConf->proxy_alert ? "YES" : "NO");
01769     LogMessage("      IIS Unicode Map Filename: %s\n",
01770                GlobalConf->iis_unicode_map_filename);
01771     LogMessage("      IIS Unicode Map Codepage: %d\n",
01772                GlobalConf->iis_unicode_codepage);
01773 
01774     return 0;
01775 }
01776 
01777 
01778 
01779 
01780 
01781 
01782 
01783 
01784 
01785 
01786 
01787 
01788 
01789 
01790 
01791 
01792 
01793 
01794 
01795 
01796 
01797 
01798 
01799 
01800 
01801 
01802 
01803 
01804 
01805 
01806 
01807 
01808 int HttpInspectSnortConf(HTTPINSPECT_GLOBAL_CONF *GlobalConf, char *args, int iGlobal,
01809                          char *ErrorString, int ErrStrLen)
01810 {
01811     char        *pcToken;
01812     static int  s_iGlobal = 0;
01813     int         iRet;
01814 
01815     
01816 
01817 
01818     if(ErrorString == NULL)
01819     {
01820         return -2;
01821     }
01822     
01823     if(GlobalConf == NULL)
01824     {
01825         snprintf(ErrorString, ErrStrLen, 
01826                 "Global configuration variable undefined.");
01827 
01828         return -1;
01829     }
01830 
01831     if(args == NULL)
01832     {
01833         snprintf(ErrorString, ErrStrLen, 
01834                 "No arguments to HttpInspect configuration.");
01835 
01836         return -1;
01837     }
01838 
01839     
01840 
01841 
01842     pcToken = strtok(args, CONF_SEPARATORS);
01843     if(pcToken == NULL)
01844     {
01845         snprintf(ErrorString, ErrStrLen, 
01846                 "No arguments to HttpInspect configuration.");
01847 
01848         return -1;
01849     }
01850 
01851     
01852 
01853 
01854 
01855 
01856 
01857     if((s_iGlobal || iGlobal) && !strcmp(pcToken, GLOBAL)) 
01858     {
01859         
01860 
01861 
01862         if(s_iGlobal)
01863         {
01864             snprintf(ErrorString, ErrStrLen,
01865                     "Cannot configure '%s' settings more than once.",
01866                     GLOBAL);
01867 
01868             return -1;
01869         }
01870 
01871         
01872 
01873 
01874         if(hi_ui_config_reset_global(GlobalConf))
01875         {
01876             snprintf(ErrorString, ErrStrLen,
01877                     "Cannot reset the HttpInspect global configuration.");
01878 
01879             return -1;
01880         }
01881 
01882         
01883 
01884 
01885 
01886         if(hi_ui_config_reset_server(&GlobalConf->global_server))
01887         {
01888             snprintf(ErrorString, ErrStrLen,
01889                     "Cannot reset the HttpInspect default server configuration.");
01890 
01891             return -1;
01892         }
01893 
01894         if((iRet = ProcessGlobalConf(GlobalConf, ErrorString, ErrStrLen)))
01895         {
01896             return iRet;
01897         }
01898 
01899         s_iGlobal = 1;
01900 
01901         
01902 
01903 
01904         PrintGlobalConf(GlobalConf);
01905     }
01906     
01907 
01908 
01909     else if(!iGlobal && !strcmp(pcToken, SERVER))
01910     {
01911         if((iRet = ProcessUniqueServerConf(GlobalConf, 
01912                                            ErrorString, ErrStrLen)))
01913         {
01914             return iRet;
01915         }
01916     }
01917     
01918 
01919 
01920     else
01921     {
01922         if(iGlobal)
01923         {
01924             snprintf(ErrorString, ErrStrLen,
01925                     "Invalid configuration token '%s'.  " 
01926                     "The first configuration must start with a '%s' "
01927                     "configuration type.", pcToken, GLOBAL);
01928         }
01929         else
01930         {
01931             snprintf(ErrorString, ErrStrLen,
01932                     "Invalid configuration token '%s'.  Must be a '%s' "
01933                     "configuration.", pcToken, SERVER);
01934         }
01935 
01936         return -1;
01937     }
01938 
01939     return 0;
01940 }
01941 
01942 
01943 
01944 
01945 
01946 
01947 
01948 
01949 
01950 
01951 
01952 
01953 
01954 
01955 
01956 
01957 
01958 
01959 
01960 
01961 
01962 
01963 
01964 
01965 
01966 
01967 
01968 
01969 
01970 
01971 
01972 
01973 
01974 
01975 
01976 
01977 
01978 static inline int LogEvents(HI_SESSION *hi_ssn, Packet *p, int iInspectMode)
01979 {
01980     HI_GEN_EVENTS GenEvents;
01981     HI_EVENT      *OrigEvent;
01982     HI_EVENT      *HiEvent = NULL;
01983     Session       *ssn = NULL;
01984     u_int32_t     uiMask = 0;
01985     int           iGenerator;
01986     int           iStackCnt;
01987     int           iEvent;
01988     int           iCtr;
01989 
01990     
01991 
01992 
01993     if(p && p->ssnptr)
01994         ssn = (Session *)p->ssnptr;
01995     
01996     if(iInspectMode == HI_SI_CLIENT_MODE)
01997     {
01998         GenEvents.stack =       hi_ssn->client.event_list.stack;
01999         GenEvents.stack_count = &(hi_ssn->client.event_list.stack_count);
02000         GenEvents.events =      hi_ssn->client.event_list.events;
02001 
02002         iGenerator = GENERATOR_SPP_HTTP_INSPECT_CLIENT;
02003     }
02004     else if(iInspectMode == HI_SI_SERVER_MODE)
02005     {
02006         
02007 
02008 
02009         return 0;
02010     }
02011     else
02012     {
02013         GenEvents.stack =       hi_ssn->anom_server.event_list.stack;
02014         GenEvents.stack_count = &(hi_ssn->anom_server.event_list.stack_count);
02015         GenEvents.events =      hi_ssn->anom_server.event_list.events;
02016 
02017         iGenerator = GENERATOR_SPP_HTTP_INSPECT_ANOM_SERVER;
02018     }
02019 
02020     
02021 
02022 
02023     iStackCnt = *(GenEvents.stack_count);
02024 
02025     
02026 
02027 
02028 
02029 
02030     if(iStackCnt == 0)
02031     {
02032         return 0;
02033     }
02034 
02035     
02036 
02037 
02038 
02039     for(iCtr = 0; iCtr < iStackCnt; iCtr++)
02040     {
02041         iEvent = GenEvents.stack[iCtr];
02042         OrigEvent = &(GenEvents.events[iEvent]);
02043 
02044         
02045 
02046 
02047         if(!HiEvent)
02048         {
02049             HiEvent = OrigEvent;
02050         }
02051 
02052         
02053 
02054 
02055 
02056         if(OrigEvent->event_info->priority < HiEvent->event_info->priority)
02057         {
02058             HiEvent = OrigEvent;
02059         }
02060 
02061         
02062 
02063 
02064 
02065 
02066         OrigEvent->count = 0;
02067     }
02068 
02069     
02070 
02071 
02072 
02073 
02074 
02075 
02076 
02077     iEvent = HiEvent->event_info->alert_id + 1;
02078 
02079     uiMask = (u_int32_t)(1 << (iEvent & 31));
02080 
02081     
02082 
02083 
02084 
02085     if(ssn && (ssn->http_alert_flags & uiMask))
02086     {
02087         return 0;
02088     }
02089 
02090     SnortEventqAdd(iGenerator, iEvent, 1, 0, 3, HiEvent->event_info->alert_str,0);
02091 
02092     
02093 
02094 
02095 
02096     if(ssn)
02097         ssn->http_alert_flags |= uiMask;
02098 
02099     
02100 
02101 
02102 
02103     *(GenEvents.stack_count) = 0;
02104 
02105     return 0;
02106 }
02107 
02108 static inline int SetSiInput(HI_SI_INPUT *SiInput, Packet *p)
02109 {
02110     Session *ssnptr = NULL;
02111 
02112     SiInput->sip   = p->iph->ip_src.s_addr;
02113     SiInput->dip   = p->iph->ip_dst.s_addr;
02114     SiInput->sport = p->sp;
02115     SiInput->dport = p->dp;
02116 
02117     if(p->ssnptr)
02118     {
02119         ssnptr = (Session *)p->ssnptr;
02120     }
02121 
02122     
02123 
02124 
02125     if(ssnptr && ssnptr->session_flags & SSNFLAG_MIDSTREAM)
02126     {
02127         SiInput->pdir = HI_SI_NO_MODE;
02128     }
02129     else if(p->packet_flags & PKT_FROM_SERVER)
02130     {
02131         SiInput->pdir = HI_SI_SERVER_MODE;
02132     }
02133     else if(p->packet_flags & PKT_FROM_CLIENT)
02134     {
02135         SiInput->pdir = HI_SI_CLIENT_MODE;
02136     }
02137     else
02138     {
02139         SiInput->pdir = HI_SI_NO_MODE;
02140     }
02141 
02142     return HI_SUCCESS;
02143 
02144 }
02145 
02146 
02147 
02148 
02149 
02150 
02151 
02152 
02153 
02154 
02155 
02156 
02157 
02158 
02159 
02160 
02161 
02162 
02163 
02164 
02165 
02166 
02167 
02168 
02169 
02170 
02171 int SnortHttpInspect(HTTPINSPECT_GLOBAL_CONF *GlobalConf, Packet *p)
02172 {
02173     extern HttpUri UriBufs[URI_COUNT];
02174     extern int     do_detect;
02175     extern OptTreeNode *otn_tmp;
02176 
02177     HI_SESSION  *Session;
02178     HI_SI_INPUT SiInput;
02179     int iInspectMode = 0;
02180     int iRet;
02181     int iCallDetect = 1;
02182     
02183     if(!p->iph || !p->tcph)
02184     {
02185         return 1;
02186     }
02187 
02188     
02189 
02190 
02191 
02192 
02193     SetSiInput(&SiInput, p);
02194 
02195     
02196 
02197 
02198 
02199 
02200 
02201 
02202 
02203 
02204 
02205 
02206 
02207 
02208 
02209 
02210 
02211 
02212 
02213 
02214 
02215 
02216 
02217 
02218 
02219 
02220 
02221  
02222     
02223     
02224 
02225 
02226     if((iRet = hi_si_session_inspection(GlobalConf, &Session, &SiInput, 
02227                     &iInspectMode)))
02228     {
02229         return iRet;
02230     }
02231     
02232     
02233 
02234 
02235 
02236 
02237 
02238 
02239 
02240 
02241 
02242 
02243     do
02244     {
02245         
02246 
02247 
02248 
02249 
02250 
02251         p->uri_count = 0;
02252         UriBufs[0].decode_flags = 0;
02253 
02254         if(iInspectMode == HI_SI_SERVER_MODE)
02255         {
02256             
02257             if (Session->server_conf->flow_depth == -1)
02258             {
02259                 do_detect = 0;
02260                 p->preprocessors = 0;
02261 
02262                 p->preprocessors |= PP_PORTSCAN;
02263                 p->preprocessors |= PP_STREAM4;
02264 
02265                 return 0;
02266             }
02267         }
02268 
02269         if((iRet = hi_mi_mode_inspection(Session, iInspectMode, p->data,
02270                                          p->dsize)))
02271         {
02272             LogEvents(Session,p,iInspectMode);
02273             return iRet;
02274         }
02275 
02276         if((iRet = hi_normalization(Session, iInspectMode)))
02277         {
02278             LogEvents(Session,p,iInspectMode);
02279             return iRet;
02280         }
02281 
02282         
02283 
02284 
02285 
02286         if(iInspectMode == HI_SI_CLIENT_MODE)
02287         {
02288             if(!iCallDetect || Session->server_conf->uri_only)
02289             {
02290                 UriBufs[0].decode_flags |= HTTPURI_PIPELINE_REQ;
02291             }
02292 
02293             if(Session->client.request.uri_norm)
02294             {
02295                 UriBufs[0].uri    = Session->client.request.uri_norm;
02296                 UriBufs[0].length = Session->client.request.uri_norm_size;
02297                 p->uri_count = 1;
02298                 p->packet_flags |= PKT_HTTP_DECODE;
02299             }
02300             else if(Session->client.request.uri)
02301             {
02302                 UriBufs[0].uri    = Session->client.request.uri;
02303                 UriBufs[0].length = Session->client.request.uri_size;
02304                 p->uri_count = 1;
02305 
02306                 p->packet_flags |= PKT_HTTP_DECODE;
02307             }
02308         }
02309         else if(iInspectMode == HI_SI_SERVER_MODE)
02310         {
02311             
02312 
02313 
02314             p->dsize = Session->server.header_size;
02315 
02316             
02317 
02318 
02319 
02320 
02321 
02322 
02323 
02324             if(p->dsize == 0)
02325             {
02326                 do_detect = 0;
02327                 p->preprocessors = 0;
02328 
02329                 p->preprocessors |= PP_PORTSCAN;
02330                 p->preprocessors |= PP_STREAM4;
02331 
02332                 return 0;
02333             }
02334         }
02335         else
02336         {
02337             
02338 
02339 
02340 
02341 
02342 
02343 
02344 
02345 
02346             if(Session->anom_server.event_list.stack_count)
02347                 LogEvents(Session, p, iInspectMode);
02348 
02349             return 0;
02350         }
02351 
02352         
02353 
02354 
02355 
02356 
02357 
02358 
02359 
02360 
02361 
02362 
02363         Detect(p);
02364         otn_tmp = NULL;
02365 
02366         
02367 
02368 
02369 
02370 
02371 
02372 
02373 
02374 
02375 
02376         LogEvents(Session, p, iInspectMode);
02377 
02378         
02379 
02380 
02381 
02382         do_detect = 0;
02383         iCallDetect = 0;
02384 
02385         p->preprocessors = 0;
02386         p->preprocessors |= PP_STREAM4;
02387 
02388     } while(Session->client.request.pipeline_req);
02389 
02390     return 0;
02391 }
02392 
02393     
02394     
02395 
02396 
02397 
02398 
02399