📄 hi_client.c
字号:
Client->request.pipeline_req = NULL; end = data + dsize; ptr = start; /* ** Apache and IIS strike again . . . Thanks Kanatoko ** - Ignore CRLFs at the beginning of the request. */ while(hi_util_in_bounds(start, end, ptr)) { if(*ptr < 0x21) { if(*ptr < 0x0E && *ptr > 0x08) { ptr++; continue; } else { if(*ptr == 0x20) { ptr++; continue; } } } break; } len = end - ptr; mthd = method_ptr.uri = ptr; while(hi_util_in_bounds(start, end, mthd)) { if (ServerConf->whitespace[*mthd] || (lookup_table[*mthd] == NextNonWhiteSpace)) { method_end = mthd++; break; } /* isascii returns non-zero if it is ascii */ if (isascii((int)*mthd) == 0) { /* Possible post data or something else strange... */ method_end = mthd++; non_ascii_mthd = 1; break; } mthd++; } if (method_end) { method_ptr.uri_end = method_end; } else { method_ptr.uri_end = end; } method_len = method_ptr.uri_end - method_ptr.uri; /* Need slightly special handling for POST requests * Since we don't normalize on the request method itself, * just do a strcmp here and skip the characters below. */ if(method_len == 4 && !strncasecmp("POST", (const char *)method_ptr.uri, 4)) { hi_stats.post++; Client->request.method = HI_POST_METHOD; } else if(method_len == 3 && !strncasecmp("GET", (const char *)method_ptr.uri, 3)) { hi_stats.get++; Client->request.method = HI_GET_METHOD; } else { Client->request.method = HI_UNKNOWN_METHOD; } if (Client->request.method == HI_UNKNOWN_METHOD) { if (IsHttpVersion(&ptr, end)) { sans_uri = 1; iRet = URI_END; method_ptr.uri = method_ptr.uri_end = NULL; } else if (method_len == len) { sans_uri = 1; iRet = URI_END; method_ptr.uri = method_ptr.uri_end = NULL; } else if (SnortStrnPbrk((const char *)method_ptr.uri, method_len, "()<>@,;:\\\"/[]?={} \t") != NULL) { /* Look for the seperator charactors as part of the method */ sans_uri = 1; iRet = URI_END; method_ptr.uri = method_ptr.uri_end = NULL; } else if (non_ascii_mthd == 1) { sans_uri = 1; iRet = URI_END; method_ptr.uri = method_ptr.uri_end = NULL; } } if (!sans_uri ) { uri_ptr.uri = ptr; uri_ptr.uri_end = end; /* This will set up the URI pointers - effectively extracting * the URI. */ iRet = hi_client_extract_uri( Session, ServerConf, Client, start, end, ptr, &uri_ptr); } /* Check if the URI exceeds the max header field length */ /* Only check if we succesfully observed a GET or POST method, otherwise, * this may very well be a POST body */ if(iRet == URI_END && hi_eo_generate_event(Session, ServerConf->max_hdr_len) && ((uri_ptr.uri_end - uri_ptr.uri) >= ServerConf->max_hdr_len)) { hi_eo_client_event_log(Session, HI_EO_CLIENT_LONG_HDR, NULL, NULL); } if(iRet == URI_END && (Client->request.method & (HI_POST_METHOD | HI_GET_METHOD))) { Client->request.method_raw = method_ptr.uri; Client->request.method_size = method_ptr.uri_end - method_ptr.uri; ///XXX ///Copy out the header into its own buffer..., /// set ptr to end of header. // // uri_ptr.end points to end of URI & HTTP version identifier. if (hi_util_in_bounds(start, end, uri_ptr.uri_end + 1)) ptr = hi_client_extract_header(Session, ServerConf, Client, &header_ptr, uri_ptr.uri_end+1, end); if (header_ptr.header.uri) { Client->request.header_raw = header_ptr.header.uri; Client->request.header_raw_size = header_ptr.header.uri_end - header_ptr.header.uri; if ((int)Client->request.header_raw_size <= 0) { CLR_HEADER(Client); } else { hi_stats.headers++; Client->request.header_norm = header_ptr.header.norm; if (header_ptr.cookie.cookie) { hi_stats.cookies++; Client->request.cookie.cookie = header_ptr.cookie.cookie; Client->request.cookie.cookie_end = header_ptr.cookie.cookie_end; Client->request.cookie.next = header_ptr.cookie.next; } else { Client->request.cookie.cookie = NULL; Client->request.cookie.cookie_end = NULL; Client->request.cookie.next = NULL; } } } else { CLR_HEADER(Client); } /* Need to skip over header and get to the body. * The unaptly named FindPipelineReq will do that. */ ptr = FindPipelineReq(Session, uri_ptr.delimiter, end); //ptr = FindPipelineReq(Session, ptr, end); if(ptr) { u_int8_t *tmp = memchr(ptr, (int)' ', end - ptr); if(tmp && ( (tmp - (u_int8_t*)ptr) < 8 )) { Client->request.pipeline_req = ptr; CLR_POST(Client); } else { post_ptr.uri = ptr; post_ptr.uri_end = end; if((POST_END == hi_client_extract_post( Session, ServerConf, ptr, end, &post_ptr))) { hi_stats.post_params++; Client->request.post_raw = post_ptr.uri; Client->request.post_raw_size = post_ptr.uri_end - post_ptr.uri; Client->request.post_norm = post_ptr.norm; } else { CLR_POST(Client); } } } else { CLR_POST(Client); ptr = uri_ptr.delimiter; } } else { CLR_POST(Client); if (method_ptr.uri) { Client->request.method_raw = method_ptr.uri; Client->request.method_size = method_ptr.uri_end - method_ptr.uri; } ptr = uri_ptr.delimiter; } /* ** If there is a pipelined request in this packet, we should always ** see the first space followed by text (which is the URI). Without ** that first space, then we never get to the URI, so we should just ** return, since there is nothing else to inspect. */ if(Client->request.pipeline_req) { if(uri_ptr.uri != uri_ptr.first_sp_end) { if(Session->server_conf->chunk_length) CheckChunkEncoding(Session, start, end); return HI_NONFATAL_ERR; } } /* ** We set the HI_CLIENT variables from the URI_PTR structure. We also ** do error checking for the values in this routine as well. */ iRet = SetClientVars(Client, &uri_ptr, dsize); if (iRet) { return iRet; } /* ** One last check for an oversize directory. This gets the long ** directory when there is a beginning slash and no other slashes ** until the end of the packet. ** ** We do this check after we set the variables, just in case there ** was some errors while setting the variables. This could save some ** false positives on a bad URI setting. */ if(uri_ptr.uri_end) CheckLongDir(Session, &uri_ptr, uri_ptr.uri_end); /* ** Check for absolute URI and alert for proxy comm if necessary ** ** NOTE: ** Also check ClientConf for proxy configuration so we don't ** alert on outbound requests from legitimate proxies. */ if(uri_ptr.proxy && Session->global_conf->proxy_alert && (!ServerConf->allow_proxy && !ClientConf->allow_proxy)) { if(hi_eo_generate_event(Session, HI_EO_CLIENT_PROXY_USE)) { hi_eo_client_event_log(Session, HI_EO_CLIENT_PROXY_USE, NULL, NULL); } } /* ** Find the next pipeline request, if one is there. If we don't find ** a pipeline request, then we return NULL here, so this is always ** set to the correct value. */ if(!ServerConf->no_pipeline) { if(post_ptr.uri) { Client->request.pipeline_req = FindPipelineReq(Session, post_ptr.delimiter, end); } else if(!Client->request.pipeline_req && uri_ptr.uri) { Client->request.pipeline_req = FindPipelineReq(Session, ptr, end); } } else { Client->request.pipeline_req = NULL; } if(Session->server_conf->chunk_length) CheckChunkEncoding(Session, uri_ptr.delimiter, end); return HI_SUCCESS;}int hi_client_inspection(void *S, const unsigned char *data, int dsize){ HTTPINSPECT_GLOBAL_CONF *GlobalConf; HI_SESSION *Session; int iRet; if(!S || !data || dsize < 1) { return HI_INVALID_ARG; } Session = (HI_SESSION *)S; if(!Session->global_conf) { return HI_INVALID_ARG; } GlobalConf = Session->global_conf; /* ** We inspect the HTTP protocol in either stateful mode or ** stateless mode. */ if(GlobalConf->inspection_type == HI_UI_CONFIG_STATEFUL) { /* ** This is where we do stateful inspection. */ return HI_NONFATAL_ERR; } else { /* ** Otherwise we assume stateless inspection */ iRet = StatelessInspection(Session, data, dsize); if (iRet) { return iRet; } } return HI_SUCCESS;}/*** NAME** hi_client_init::*//**** Initializes arrays and search algorithms depending on the type of** inspection that we are doing.** ** @param GlobalConf pointer to the global configuration** ** @return integer** ** @retval HI_SUCCESS function successful.*/int hi_client_init(HTTPINSPECT_GLOBAL_CONF *GlobalConf){ int iCtr; int iNum; if(GlobalConf->inspection_type == HI_UI_CONFIG_STATEFUL) { /* ** We don't have to do anything here yet. */ } else { memset(lookup_table, 0x00, sizeof(lookup_table)); memset(hex_lookup, -1, sizeof(hex_lookup)); /* ** Set up the non-ASCII register for processing. */ for(iCtr = 0x80; iCtr <= 0xff; iCtr++) { lookup_table[iCtr] = SetBinaryNorm; } lookup_table[0x00] = SetBinaryNorm; lookup_table[' '] = NextNonWhiteSpace; lookup_table['\r'] = find_rfc_delimiter; lookup_table['\n'] = find_non_rfc_delimiter; /* ** ASCII encoding */ lookup_table['%'] = SetPercentNorm; /* ** Looking for multiple slashes */ lookup_table['/'] = SetSlashNorm; /* ** Looking for backslashs */ lookup_table['\\'] = SetBackSlashNorm; /* ** Look up parameter field, so we don't alert on long directory ** strings, when the next slash in the parameter field. */ lookup_table['?'] = SetParamField; /* ** Look for absolute URI and proxy communication. */ lookup_table[':'] = SetProxy; /* ** Set up the hex array */ iNum = 0; for(iCtr = 48; iCtr < 58; iCtr++) { hex_lookup[iCtr] = iNum; iNu
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -