コード例 #1
0
ファイル: ScanManager.cs プロジェクト: Hazhzeng/KuduLite
        public async Task <bool> PerformBackgroundScan(ITracer _tracer, AllSafeLinuxLock _scanLock, String folderPath, CancellationToken token, String scanId, String mainScanDirPath)
        {
            var successfulScan = true;

            await Task.Run(() =>
            {
                _scanLock.LockOperation(() =>
                {
                    _scanLock.SetLockMsg(Resources.ScanUnderwayMsg);

                    String statusFilePath = Path.Combine(folderPath, Constants.ScanStatusFile);


                    String logFilePath = Path.Combine(folderPath, Constants.ScanLogFile);
                    _tracer.Trace("Starting Scan {0}, ScanCommand: {1}, LogFile: {2}", scanId, Constants.ScanCommand, logFilePath);

                    UpdateScanStatus(folderPath, ScanStatus.Executing, null);

                    var escapedArgs           = Constants.ScanCommand + " " + logFilePath;
                    Process _executingProcess = new Process()
                    {
                        StartInfo = new ProcessStartInfo
                        {
                            FileName  = "/bin/bash",
                            Arguments = "-c \"" + escapedArgs + "\"",
                            RedirectStandardOutput = true,
                            UseShellExecute        = false,
                            CreateNoWindow         = true,
                        }
                    };
                    _executingProcess.Start();

                    string tempScanFilePath = GetTempScanFilePath(mainScanDirPath);
                    //Check if process is completing before timeout
                    while (!_executingProcess.HasExited)
                    {
                        //Process still running, but timeout is done
                        //Or Process is still running but scan has been stopped by user
                        if (token.IsCancellationRequested || (tempScanFilePath != null && !FileSystemHelpers.FileExists(tempScanFilePath)))
                        {
                            //Kill process
                            _executingProcess.Kill(true, _tracer);
                            //Wait for process to be completely killed
                            _executingProcess.WaitForExit();
                            successfulScan = false;
                            if (token.IsCancellationRequested)
                            {
                                _tracer.Trace("Scan {0} has timed out at {1}", scanId, DateTime.UtcNow.ToString("yyy-MM-dd_HH-mm-ssZ"));

                                //Update status file
                                UpdateScanStatus(folderPath, ScanStatus.TimeoutFailure, null);
                            }
                            else
                            {
                                _tracer.Trace("Scan {0} has been force stopped at {1}", scanId, DateTime.UtcNow.ToString("yyy-MM-dd_HH-mm-ssZ"));

                                //Update status file
                                UpdateScanStatus(folderPath, ScanStatus.ForceStopped, null);
                            }

                            break;
                        }
                    }

                    //Clean up the temp file
                    StopScan(mainScanDirPath);

                    //Update status file with success
                    if (successfulScan)
                    {
                        //Check if process terminated with errors
                        if (_executingProcess.ExitCode != 0)
                        {
                            UpdateScanStatus(folderPath, ScanStatus.Failed, null);
                            _tracer.Trace("Scan {0} has terminated with exit code {1}. More info found in {2}", scanId, _executingProcess.ExitCode, logFilePath);
                        }
                        else
                        {
                            UpdateScanStatus(folderPath, ScanStatus.Success, null);
                            _tracer.Trace("Scan {0} is Successful", scanId);
                        }
                    }
                }, "Performing continuous scan", TimeSpan.Zero);

                _scanLock.SetLockMsg("");
            });

            return(successfulScan);
        }
コード例 #2
0
ファイル: ScanManager.cs プロジェクト: Hazhzeng/KuduLite
        public async Task <ScanRequestResult> StartScan(String timeout, String mainScanDirPath, String id, String host, Boolean checkModified)
        {
            using (_tracer.Step("Start scan in the background"))
            {
                String  folderPath          = Path.Combine(mainScanDirPath, Constants.ScanFolderName + id);
                String  filePath            = Path.Combine(folderPath, Constants.ScanStatusFile);
                Boolean hasFileModifcations = true;

                if (_scanLock.IsHeld)
                {
                    return(ScanRequestResult.ScanAlreadyInProgress);
                }

                //Create unique scan folder and scan status file
                _scanLock.LockOperation(() =>
                {
                    //This means user wants to start a scan without checking for file changes after previous scan
                    //Delete the manifest file containing last updated timestamps of files
                    //This will force a scan to start irrespective of changes made to files
                    if (!checkModified)
                    {
                        String manifestPath = Path.Combine(mainScanDirPath, Constants.ScanManifest);
                        if (FileSystemHelpers.FileExists(manifestPath))
                        {
                            FileSystemHelpers.DeleteFileSafe(manifestPath);
                        }
                    }

                    //Check if files are modified
                    if (CheckModifications(mainScanDirPath))
                    {
                        //Create unique scan directory for current scan
                        FileSystemHelpers.CreateDirectory(folderPath);
                        _tracer.Trace("Unique scan directory created for scan {0}", id);

                        //Create scan status file inside folder
                        FileSystemHelpers.CreateFile(filePath).Close();

                        //Create temp file to check if scan is still running
                        string tempScanFilePath = GetTempScanFilePath(mainScanDirPath);
                        tempScanFilePath        = Path.Combine(mainScanDirPath, Constants.TempScanFile);
                        FileSystemHelpers.CreateFile(tempScanFilePath).Close();

                        UpdateScanStatus(folderPath, ScanStatus.Starting, id);
                    }
                    else
                    {
                        hasFileModifcations = false;
                    }
                }, "Creating unique scan folder", TimeSpan.Zero);

                if (!hasFileModifcations)
                {
                    return(ScanRequestResult.NoFileModifications);
                }

                //Start Backgorund Scan
                using (var timeoutCancellationTokenSource = new CancellationTokenSource())
                {
                    var successfullyScanned = PerformBackgroundScan(_tracer, _scanLock, folderPath, timeoutCancellationTokenSource.Token, id, mainScanDirPath);

                    //Wait till scan task completes or the timeout goes off
                    if (await Task.WhenAny(successfullyScanned, Task.Delay(Int32.Parse(timeout), timeoutCancellationTokenSource.Token)) == successfullyScanned)
                    {
                        //If scan task completes before timeout
                        //Delete excess scan folders, just keep the maximum number allowed
                        await DeletePastScans(mainScanDirPath, _tracer);

                        //Create new Manifest file containing the modified timestamps
                        String manifestPath = Path.Combine(mainScanDirPath, Constants.ScanManifest);
                        if (FileSystemHelpers.FileExists(manifestPath))
                        {
                            FileSystemHelpers.DeleteFileSafe(manifestPath);
                        }
                        JObject manifestObj = new JObject();

                        //Write to the manifest with new timestamps of the modified file
                        ModifyManifestFile(manifestObj, Constants.ScanDir);
                        File.WriteAllText(manifestPath, JsonConvert.SerializeObject(manifestObj));

                        //Path to common log file for azure monitor
                        String aggrLogPath = Path.Combine(mainScanDirPath, Constants.AggregrateScanResults);

                        //This checks if result scan log is formed
                        //If yes, it will append necessary logs to the aggregrate log file
                        //Current appended logs will be "Scanned files","Infected files", and details of infected files
                        String currLogPath = Path.Combine(folderPath, Constants.ScanLogFile);
                        if (FileSystemHelpers.FileExists(currLogPath))
                        {
                            StreamReader file = new StreamReader(currLogPath);
                            string       line;
                            while ((line = file.ReadLine()) != null)
                            {
                                if (line.Contains("FOUND") || line.Contains("Infected files") || line.Contains("Scanned files"))
                                {
                                    //logType "Infected" means this log line represents details of infected files
                                    String logType = "Infected";
                                    if (line.Contains("Infected files") || line.Contains("Scanned files"))
                                    {
                                        //logType "Info" means this log line represents total number of scanned or infected files
                                        logType = "Info";
                                    }
                                    FileSystemHelpers.AppendAllTextToFile(aggrLogPath, DateTime.UtcNow.ToString(@"M/d/yyyy hh:mm:ss tt") + "," + id + "," + logType + "," + host + "," + line + '\n');
                                }
                            }
                        }

                        return(successfullyScanned.Result
                        ? ScanRequestResult.RunningAynschronously
                        : ScanRequestResult.AsyncScanFailed);
                    }
                    else
                    {
                        //Timeout went off before scan task completion
                        //Cancel scan task
                        timeoutCancellationTokenSource.Cancel();

                        //Scan process will be cancelled
                        //wait till scan status file is appropriately updated
                        await successfullyScanned;

                        //Delete excess scan folders, just keep the maximum number allowed
                        await DeletePastScans(mainScanDirPath, _tracer);

                        return(ScanRequestResult.AsyncScanFailed);
                    }
                }
            }
        }