private TrafficViewerFile removeSimilar(TrafficViewerFile source) { TrafficViewerFile dest = new TrafficViewerFile(); TVRequestInfo info; int id = -1; List <int> _reqHashes = new List <int>(); while ((info = source.GetNext(ref id)) != null) { byte[] request = source.LoadRequestData(info.Id); HttpRequestInfo reqInfo = new HttpRequestInfo(request, true); int hash = reqInfo.GetHashCode(TrafficServerMode.BrowserFriendly); if (!_reqHashes.Contains(hash)) { byte[] response = source.LoadResponseData(info.Id); dest.AddRequestResponse(request, response); _reqHashes.Add(hash); } } //copy profile over dest.Profile = source.Profile; return(dest); }
public void EditTVF() { TrafficViewerFile tvf = UnitTestUtils.GenerateTestTvf(); //check delete int initialCount = tvf.RequestCount; //get the first request id int i = -1; TVRequestInfo first = tvf.GetNext(ref i); TVRequestInfo second = tvf.GetNext(ref i); HttpRequestInfo secondRequest = new HttpRequestInfo(tvf.LoadRequestData(second.Id)); HttpResponseInfo secondResponse = new HttpResponseInfo(); byte [] respBytes = tvf.LoadResponseData(second.Id); secondResponse.ProcessResponse(respBytes); int referenceResponseStatus = secondResponse.Status; int referenceHash = secondRequest.GetHashCode(); Assert.IsTrue(tvf.RemoveRequest(first.Id)); Assert.AreEqual(initialCount - 1, tvf.RequestCount); Assert.IsNull(tvf.GetPrevious(ref i)); RequestDataCache.Instance.Clear(); //check that //check add TVRequestInfo reqInfo = new TVRequestInfo(); reqInfo.RequestLine = "GET /newrequest HTTP/1.1"; string request = "GET /newrequest HTTP/1.1\r\nHeader1:1\r\n\r\n"; string response = "HTTP 200 OK\r\nHeader1:1\r\n\r\n<html><body>Added request</body></html>"; RequestResponseBytes reqData = new RequestResponseBytes(); reqData.AddToRequest(Constants.DefaultEncoding.GetBytes(request)); reqData.AddToResponse(Constants.DefaultEncoding.GetBytes(response)); tvf.AddRequestInfo(reqInfo); tvf.SaveRequest(reqInfo.Id, reqData); tvf.SaveResponse(reqInfo.Id, reqData); //Check that the request was added response = Constants.DefaultEncoding.GetString(tvf.LoadResponseData(reqInfo.Id)); Assert.AreEqual(38, response.IndexOf("Added request")); Assert.AreEqual(65, response.Length); //modify the recently added request slightly }
/// <summary> /// Gets the next unsent request /// </summary> /// <returns>Http Request Info</returns> private HttpRequestInfo GetNextRequest() { TVRequestInfo tvReqInfo = null; HttpRequestInfo httpReqInfo = null; ICacheable cacheEntry = null; //get the next unvisited request bool isCached = true; int hash = 0; do { tvReqInfo = Source.GetNext(ref _currId); if (tvReqInfo != null) { isCached = true; //skip js files and images if (!Utils.IsMatch(tvReqInfo.RequestLine, KNOWN_RESOURCE_EXTENSIONS)) { byte[] requestBytes = Source.LoadRequestData(tvReqInfo.Id); httpReqInfo = new HttpRequestInfo(requestBytes); //skip invalid requests if (httpReqInfo.Path.Contains("/")) { hash = httpReqInfo.GetHashCode(); //check the cache for the request to see if it was already visited //allow the same request to be sent more than once if (hash != _lastRequestHash) { cacheEntry = TrafficServerCache.Instance.GetEntry(hash); isCached = cacheEntry != null; } } } } //keep doing this until the end of requests or until we found a request that is not cached }while (tvReqInfo != null && isCached); if (hash != _lastRequestHash) { _lastRequestHash = hash; //clear the cache so we don't skip any repeats of the previous request TrafficServerCache.Instance.Clear(); } return(httpReqInfo); }
/// <summary> /// Compares two requests infos /// </summary> /// <param name="first"></param> /// <param name="second"></param> /// <param name="mode"></param> /// <returns></returns> public static bool IsMatch(HttpRequestInfo first, HttpRequestInfo second, TrafficServerMode mode) { bool result; if (mode == TrafficServerMode.IgnoreCookies) { result = first.QueryVariables.GetHashCode() == second.QueryVariables.GetHashCode() && first.BodyVariables.GetHashCode() == second.BodyVariables.GetHashCode(); } else if (mode == TrafficServerMode.Strict) { result = first.GetHashCode() == second.GetHashCode(); } else { result = first.QueryVariables.GetHashCode(false) == second.QueryVariables.GetHashCode(false) && first.BodyVariables.GetHashCode(false) == second.BodyVariables.GetHashCode(false); } return(result); }
private void RequestHandlerThread() { while (IsListening) { HttpRequestInfo reqInfo = null; HttpResponseInfo respInfo = null; int thisThreadRequestIndex = -1; lock (_lock) { reqInfo = null; if (_requestsToTest.Count > 0) { thisThreadRequestIndex = _requestsToTest.Dequeue(); _currentTestReqIdx = thisThreadRequestIndex; reqInfo = _requestIndex[thisThreadRequestIndex]; respInfo = _responseIndex[thisThreadRequestIndex]; } } if (reqInfo != null) { bool isSecure = reqInfo.IsSecure; string rawRequest = reqInfo.ToString(); string rawResponse = respInfo != null?respInfo.ToString() : String.Empty; if (ShouldBeTested(rawRequest)) { //parse parameters reqInfo = new HttpRequestInfo(rawRequest, true); reqInfo.IsSecure = isSecure; int hash = reqInfo.GetHashCode(TrafficServerMode.IgnoreCookies); lock (_lock) { if (_testedRequestHashes.Contains(hash)) { HttpServerConsole.Instance.WriteLine(LogMessageType.Warning, "Request already tested: '{0}'", reqInfo.FullUrl); continue; //we tested this request before } else { _testedRequestHashes.Add(hash); } } Uri reqUri = new Uri(reqInfo.FullUrl); MultiThreadedTestExecution testExecution = new MultiThreadedTestExecution(_tester, rawRequest, rawResponse, reqUri, _numThreads); lock (_lock) { GenerateEntities(thisThreadRequestIndex, reqInfo); testExecution.TestsQueue = _workList[thisThreadRequestIndex]; } testExecution.StartTestsAsync(); while (testExecution.IsRunning) { if (!IsListening) { testExecution.CancelTests(); break; } HttpServerConsole.Instance.WriteLine(LogMessageType.Notification, "Requests in queue: {0}, Tests in queue for current request: {1}, testing with {2} threads.", _requestsToTest.Count, testExecution.TestsQueue.Count, _numThreads); Thread.Sleep(1000); } HttpServerConsole.Instance.WriteLine(LogMessageType.Notification, "Test execution completed."); } } Thread.Sleep(10); } HttpServerConsole.Instance.WriteLine(LogMessageType.Notification, "Drive by Attack Proxy stopped."); }
/// <summary> /// Actually gets a matching response from the mock data /// </summary> /// <param name="requestInfo"></param> /// <returns></returns> public HttpResponseInfo SendRequest(HttpRequestInfo requestInfo) { HttpResponseInfo responseInfo = null; string currentRequestString = requestInfo.ToString(); string currentAlertId = Utils.RegexFirstGroupValue(currentRequestString, ALERT_MATCH); TrafficServerMode currentMatchMode = _matchMode; if (!String.IsNullOrEmpty(currentAlertId)) //override the redundancy tuning if we are trying to match a alert { currentMatchMode = TrafficServerMode.BrowserFriendly; } //parse the request variables because we will need them to construct the hash requestInfo.ParseVariables(); TrafficServerResponseSet responseSet = null; //look in the server cache for the request ICacheable entry = TrafficServerCache.Instance.GetEntry(requestInfo.GetHashCode(currentMatchMode)); if (entry != null) { responseSet = entry.Reserve() as TrafficServerResponseSet; entry.Release(); } TrafficServerResponseSet similarRequests = new TrafficServerResponseSet(); if (responseSet == null) { //create a new empty response set responseSet = new TrafficServerResponseSet(); RequestSearcher searcher = new RequestSearcher(); SearchCriteriaSet criteriaSet; criteriaSet = GetCriteriaSet(requestInfo, currentMatchMode); RequestMatches matches = new RequestMatches(); //do the search! searcher.Search(_sourceStore, criteriaSet, matches); //normalize the matches and keep only the ones that have the same variables and values if (matches.Count > 0) { HttpRequestInfo original; HttpRequestInfo found; byte[] requestBytes; int i, n = matches.Count; for (i = 0; i < n & i < MATCHES_LIMIT; i++) { int match = matches[i]; TVRequestInfo header = _sourceStore.GetRequestInfo(match); if (_ignoreAuth) { if ( String.Compare(header.ResponseStatus, "401", true) == 0 || String.Compare(header.ResponseStatus, "407", true) == 0) { HttpServerConsole.Instance.WriteLine(LogMessageType.Warning, "Skipping authentication challenge"); //simply skip 401 matches continue; } } if (String.Compare(header.Description, Resources.TrafficLogProxyDescription, true) == 0) { //is likely that the source store is also the save store and this may be //the current request being saved HttpServerConsole.Instance.WriteLine(LogMessageType.Warning, "Skipping request to traffic store"); continue; } requestBytes = _sourceStore.LoadRequestData(match); string requestString = Constants.DefaultEncoding.GetString(requestBytes); if (String.IsNullOrEmpty(requestString)) { continue; //skip the current match is incorrect } original = new HttpRequestInfo(DynamicElementsRemover.Remove(currentRequestString)); found = new HttpRequestInfo(DynamicElementsRemover.Remove(requestString)); if (RequestMatcher.IsMatch(original, found, TrafficServerMode.Strict)) { responseSet.Add(match); } else if (currentMatchMode != TrafficServerMode.Strict && RequestMatcher.IsMatch(original, found, currentMatchMode)) { similarRequests.Add(match); } } //if no exact requests were found if (responseSet.Count == 0 && similarRequests.Count > 0) { HttpServerConsole.Instance.WriteLine (LogMessageType.Warning, "Warning, exact match was not found for {0} returning a similar request.", requestInfo.RequestLine); } responseSet.AddRange(similarRequests.Matches); } //add this response set to the cache TrafficServerCache.Instance.Add(requestInfo.GetHashCode(currentMatchMode), new CacheEntry(responseSet)); } //get the next response id from the response set int requestId = responseSet.GetNext(); if (requestId == NULL_INDEX) { HttpServerConsole.Instance.WriteLine(LogMessageType.Warning, "(404) Request not found: {0}" , requestInfo.RequestLine); //the request was not found at all, return a 404 return(new HttpResponseInfo(HttpErrorResponse.GenerateHttpErrorResponse(HttpStatusCode.NotFound, "Request Not Found", "<html><head><title>Error code: 404</title><body><h1>Request was not found or variables didn't match.</h1></body></html>"))); } if (requestId != NULL_INDEX) { HttpServerConsole.Instance.WriteLine(LogMessageType.Information, "Returning response from request id: {0}", requestId); byte[] responseBytes = _sourceStore.LoadResponseData(requestId); if (responseBytes != null) { responseInfo = new HttpResponseInfo(responseBytes); if (!String.IsNullOrEmpty(currentAlertId)) { Encoding encoding = HttpUtil.GetEncoding(responseInfo.Headers["Content-Type"]); string responseString = encoding.GetString(responseBytes); responseString = Utils.ReplaceGroups(responseString, ALERT_MATCH, currentAlertId); responseInfo = new HttpResponseInfo(encoding.GetBytes(responseString)); } } //add the request id header responseInfo.Headers.Add("Traffic-Store-Req-Id", requestId.ToString()); } return(responseInfo); }
/// <summary> /// Handles a request /// </summary> /// <param name="requestInfo"></param> /// <returns></returns> public HttpRequestInfo HandleRequest(HttpRequestInfo requestInfo, out bool mutated) { lock (_lock) { mutated = false; //make a request info that we parse in order to generate a hash and entities to test _curWorkingRawRequest = requestInfo.ToString(); if (!ShouldBeTested(_curWorkingRawRequest)) { return(requestInfo); } _curWorkingReqInfo = new HttpRequestInfo(_curWorkingRawRequest, true); _curWorkingReqInfo.IsSecure = requestInfo.IsSecure; int hash = _curWorkingReqInfo.GetHashCode(TrafficServerMode.IgnoreCookies); //get a hash including only the parameter names if (_firstRequestHash == 0) { _firstRequestHash = hash; } if (hash == _firstRequestHash) { if (_currentReqIdx > _detectedFlowRequests) { _detectedFlowRequests = _currentReqIdx + 1; } //reset the counter _currentReqIdx = 0; } else { //increment the request counter _currentReqIdx++; } if (_currentTestReqIdx < 0) //this is the first request { if (String.IsNullOrEmpty(_testFile.PatternOfFirstRequestToTest)) //if this is not the first request { _currentTestReqIdx = 0; } else { if (Utils.IsMatch(_curWorkingRawRequest, _testFile.PatternOfFirstRequestToTest)) { _currentTestReqIdx = _currentReqIdx; } } } if (_currentReqIdx == _currentTestReqIdx) { if (!_workList.ContainsKey(_currentTestReqIdx)) //no tests have been generated for this request { GenerateEntities(_currentReqIdx, _curWorkingReqInfo); } //this is the test request execute the next test Queue <TestJob> testQueue = _workList[_currentTestReqIdx]; if (testQueue.Count == 0 && _curMutatedRawReqQueue.Count == 0) { _currentTestReqIdx++; } else { if (_curMutatedRawReqQueue.Count == 0) { _curTestJob = testQueue.Dequeue(); //TODO: alter the request Uri workingReqUri = new Uri(_curWorkingReqInfo.FullUrl); _curEntityId = _tester.GetEntityId(workingReqUri, _curTestJob.ParameterName); string entityString = _tester.GetEntityString(_curWorkingRawRequest, workingReqUri, _curTestJob.ParameterName, _curTestJob.ParameterValue); if (entityString == null)//we could not find the parameter name /value combination { //try to obtain an updated value for the parameter string updatedParameterValue = GetUpdatedParameterValue(_curWorkingReqInfo, _curTestJob); entityString = _tester.GetEntityString(_curWorkingRawRequest, workingReqUri, _curTestJob.ParameterName, updatedParameterValue); } _curMutatedRequestList = _tester.GenerateMutatedRequestList(_curWorkingRawRequest, _curTestJob, entityString, _curEntityId); foreach (string req in _curMutatedRequestList) { _curMutatedRawReqQueue.Enqueue(req); } _curTestResponseCollection = new Dictionary <int, List <string> >(); //re-init the current test response list for multi response validation } //check again in case for some reason requests could not be generated (empty parameters) if (_curMutatedRawReqQueue.Count > 0) { //if multiple mutations are generated for the test then they need to be executed with each flow iteration _curMutatedRawReq = _curMutatedRawReqQueue.Dequeue(); //return the mutated request requestInfo = new HttpRequestInfo(_curMutatedRawReq, false); requestInfo.IsSecure = _curWorkingReqInfo.IsSecure; mutated = true; } } } } return(requestInfo); }