/// <summary> /// Starts a scan. If the projectId property of the ProjectSettings is set, this is will scan for an existing project. /// However, if a project name is given, this will create a new project and scan for this newly created project. Once a /// scan is started, you should use the runId returned to periodically check the status and get the results. /// </summary> /// <param name="projectSettings">Project Settings</param> /// <param name="sourceCodeSettings">Source Code Settings</param> /// <param name="isIncremental">Whether or not this is an incremental scan. (default = false)</param> /// <param name="isPrivate">Whetther or not this is a private scan, which should not be shared with others in your team. (default = false)</param> /// <param name="cronString">An appropriate CRON style string for the schdule time. See https://checkmarx.atlassian.net/wiki/spaces/KC/pages/26542199/Running+Scheduled+Scans for more information (only useed in scheduled scans)</param> /// <param name="utcEpochEndTime">Those long type parameters are used to determine a repetitive (scheduled) scan start and end time. The default values are 0 (zero) in order to indicate that it should start now (though initiate a scan by the cron expression schedule) and never end / last forever. (only used in scheduled scans).</param> /// <param name="utcEpochStartTime">Those long type parameters are used to determine a repetitive (scheduled) scan start and end time. The default values are 0 (zero) in order to indicate that it should start now (though initiate a scan by the cron expression schedule) and never end / last forever. (only used in scheduled scans).</param> /// <returns>string runId; NULL for failures.</returns> /// <see cref="GetScanStatus(string)"/> /// <example> /// using(CxWebService service = new CxWebService()) /// { /// if(service.Login(username, password)) /// { /// long projectID = 35; /// /// CxSDKWebService.ProjectConfiguration configuration = service.GetProjectConfiguration(projectID); /// CxSDKWebService.ProjectSettings pSettings = configuration.ProjectSettings; /// /// CxSDKWebService.SourceCodeSettings scSettings = new CxSDKWebService.SourceCodeSettings(); /// scSettings.SourceOrigin = CxSDKWebService.SourceLocationType.Local; /// scSettings.PackagedCode = new CxSDKWebService.LocalCodeContainer(); /// scSettings.PackagedCode.FileName = @"C:\Temp\MyProjectSources.zip"; /// scSettings.PackagedCode.ZippedFile = File.ReadAllBytes(scSettings.PackagedCode.FileName); /// /// //Start an incremental scan which will only focus on changes in the sources since the last scan. /// string runId = service.Scan(pSettings, scSettings, true); /// while(true) /// { /// CxSDKWebService.CxWSResponseScanStatus status = service.GetScanStatus(runId); /// switch(status.CurrentStatus) /// { /// //TODO... /// Thread.Sleep(300); /// } /// } /// } /// } /// </example> public string Scan( CxSDKWebService.ProjectSettings projectSettings, CxSDKWebService.SourceCodeSettings sourceCodeSettings, bool isIncremental = false, bool isPrivate = false, string cronString = "", long utcEpochStartTime = 0L, long utcEpochEndTime = 0L) { if (_sessionId == null) { throw new AuthenticationException(); } CxSDKWebService.CliScanArgs scanArgs = new CxSDKWebService.CliScanArgs(); scanArgs.PrjSettings = projectSettings; scanArgs.SrcCodeSettings = sourceCodeSettings; scanArgs.IsIncremental = isIncremental; scanArgs.IsPrivateScan = isPrivate; string runId = null; try { log.Debug(String.Format("Starting {0}scan for {1}", (cronString.Length > 0) ? "scheduled " : "", (projectSettings.projectID > 0) ? projectSettings.projectID + "" : projectSettings.ProjectName)); CxSDKWebService.CxWSResponseRunID response = (cronString.Length > 0) ? CallCheckmarxApi(() => SoapClient.ScanWithSchedulingWithCron(_sessionId, scanArgs, cronString, utcEpochStartTime, utcEpochEndTime)) : CallCheckmarxApi(() => SoapClient.Scan(_sessionId, scanArgs)); log.Debug(String.Format("Received run ID: {0}", response.RunId)); runId = response.RunId; } catch (ResponseException e) { log.Error(String.Format("Error, unable to start scan: {0}", e.Message), e); } catch (CommunicationException e) { log.Error(String.Format("Unable to communicate to SOAP API at endpoint {0}: {1} {2}", _endpoint.DnsSafeHost, e.GetType().Name, e.Message), e); } return(runId); }
static void Main(string[] args) { if (args.Length == 0) { Help(); } Configuration config = Configuration.GetInstance(args); SetupLogging((config.IsDebug) ? Level.Debug : Level.Info, config.LogFile); string[] requiredKeys = { "CxUser", "CxPass", "CxServer" }; foreach (string key in requiredKeys) { if (!config.Keys.Contains(key)) { Help(String.Format("The option '-{0}' is required.", key)); } } string username = config.GetValueWithCheck("CxUser"); SecureString password = StringUtils.GetSecureString(config.GetValueWithCheck("CxPass")); config["CxPass"] = null; string cxServer = config.GetValueWithCheck("CxServer"); if (config.Command == Commands.scan) { string zipFile = (config.Keys.Contains("Zip") ? config.GetValueWithCheck("Zip") : ""); string locationPath = (zipFile.Length == 0) ? config.GetValueWithCheck("LocationPath") : ""; bool isIncremental = (config.Keys.Contains("IsIncremental") ? config.GetValueWithCheck("IsIncremental") : false); bool isPrivate = (config.Keys.Contains("IsPrivate") ? config.GetValueWithCheck("IsPrivate") : false); string cronString = (config.Keys.Contains("CronString") ? config.GetValueWithCheck("CronString") : ""); int projectId = (config.Keys.Contains("ProjectId") ? Int32.Parse(config.GetValueWithCheck("ProjectId")) : -1); string projectName = (projectId == -1) ? config.GetValueWithCheck("ProjectName") : ""; long presetId = (projectName.Length > 0) ? Int32.Parse(config.GetValueWithCheck("PresetId")) : -1; string teamName = (projectName.Length > 0) ? config.GetValueWithCheck("Team") : "CxServer"; if (!teamName.StartsWith("CxServer")) { Help(@"Error: Team name must start with 'CxServer' (e.g. CxServer\SP\Humana SE\Pharmacy)."); } long configurationId = (projectName.Length > 0) ? long.Parse(config.GetValueWithCheck("ConfigurationId")) : 0; long utcEpochStartTime = (config.Keys.Contains("UtcEpochStartTime") ? long.Parse(config.GetValueWithCheck("UtcEpochStartTime")) : 0); long utcEpochEndTime = (config.Keys.Contains("UtcEpochEndTime") ? long.Parse(config.GetValueWithCheck("UtcEpochEndTime")) : 0); using (CxWebService service = new CxWebService(config.UseSSL)) { if (service.Login(username, password)) { CxSDKWebService.ProjectSettings projectSettings = new CxSDKWebService.ProjectSettings(); if (projectId > -1) { CxSDKWebService.ProjectConfiguration configuration = service.GetProjectConfiguration(projectId); projectSettings = configuration.ProjectSettings; } else { projectSettings.ProjectName = teamName + "\\" + projectName; projectSettings.PresetID = presetId; projectSettings.Owner = username; projectSettings.ScanConfigurationID = configurationId; } CxSDKWebService.SourceCodeSettings sourceCodeSettings = new CxSDKWebService.SourceCodeSettings(); sourceCodeSettings.SourceOrigin = CxSDKWebService.SourceLocationType.Local; if (zipFile.Length > 0) { sourceCodeSettings.PackagedCode = new CxSDKWebService.LocalCodeContainer(); sourceCodeSettings.PackagedCode.FileName = Path.GetFileName(zipFile); sourceCodeSettings.PackagedCode.ZippedFile = File.ReadAllBytes(zipFile); } else { CxSDKWebService.ScanPath path = new CxSDKWebService.ScanPath(); path.IncludeSubTree = true; path.Path = locationPath; sourceCodeSettings.PathList = new CxSDKWebService.ScanPath[] { path }; } //TODO - Support Source Control Settings Console.Write("Scanning {0}, please wait...\r", (zipFile.Length > 0) ? zipFile : locationPath); string runId = service.Scan(projectSettings, sourceCodeSettings, isIncremental, isPrivate, cronString, utcEpochStartTime, utcEpochEndTime); bool running = true; while (running) { CxSDKWebService.CxWSResponseScanStatus status = service.GetScanStatus(runId); switch (status.CurrentStatus) { case CxSDKWebService.CurrentStatusEnum.Canceled: case CxSDKWebService.CurrentStatusEnum.Deleted: Console.WriteLine("Scanning {0}, please wait...cancelled or deleted! {1}", (zipFile.Length > 0) ? zipFile : locationPath, status.ErrorMessage); running = false; break; case CxSDKWebService.CurrentStatusEnum.Failed: Console.WriteLine("Scanning {0}, please wait...failed: {1}", (zipFile.Length > 0) ? zipFile : locationPath, status.ErrorMessage); running = false; break; case CxSDKWebService.CurrentStatusEnum.Finished: Console.WriteLine("Scanning {0}, please wait...done: {1}", (zipFile.Length > 0) ? zipFile : locationPath, CxUtils.FromCxDateTime(status.TimeFinished)); var summary = service.GetScanSummary(status.ScanId); Console.WriteLine("{0}loc, {1} high, {2} medium, {3} low, {4} info vulnerabilities.", summary.LOC, summary.High, summary.Medium, summary.Low, summary.Info); running = false; break; case CxSDKWebService.CurrentStatusEnum.Unknown: case CxSDKWebService.CurrentStatusEnum.Queued: case CxSDKWebService.CurrentStatusEnum.Unzipping: case CxSDKWebService.CurrentStatusEnum.WaitingToProcess: case CxSDKWebService.CurrentStatusEnum.Working: Console.Write("Scanning {4}, please wait..." + Environment.NewLine + " [{0}] {2} ({1}% current / {3}% total)\r", status.CurrentStage, status.CurrentStagePercent, status.CurrentStatus, status.TotalPercent, (zipFile.Length > 0) ? zipFile : locationPath); break; } if (running) { Thread.Sleep(100); } } } } } else if (config.Command == Commands.list) { bool projects = config.Keys.Contains("Projects"); bool scans = config.Keys.Contains("Scans"); bool presets = config.Keys.Contains("Presets"); bool configurations = config.Keys.Contains("Configurations"); bool users = config.Keys.Contains("Users"); using (CxWebService service = new CxWebService(config.UseSSL)) { if (service.Login(username, password)) { if (projects) { foreach (var project in service.GetProjectsToDisplay()) { Console.WriteLine("[{0}] {1} was last scanned on {2} ({3} total scans)", project.projectID, project.ProjectName, CxUtils.FromCxDateTime(project.LastScanDate), project.TotalScans); } } else if (scans) { foreach (var scan in service.GetProjectScannedDisplayData()) { Console.WriteLine("[{0}] {1} scanned at {6}: {2} high, {3} medium, {4} low, {5} info", scan.LastScanID, scan.ProjectName, scan.HighVulnerabilities, scan.MediumVulnerabilities, scan.LowVulnerabilities, scan.InfoVulnerabilities, DateTime.FromFileTimeUtc(scan.LastScanDate)); } } else if (presets) { foreach (var preset in service.GetPresets()) { Console.WriteLine("[{0}] {1}", preset.ID, preset.PresetName); } } else if (configurations) { foreach (var c in service.GetConfigurationSetList()) { Console.WriteLine("[{0}] {1}", c.ID, c.ConfigSetName); } } else if (users) { foreach (var user in service.GetAllUsers()) { Console.WriteLine("[{0}] {4} {1} {2} {3}", user.ID, String.Format("{0}, {1}", user.LastName, user.FirstName), user.Email, user.LastLoginDate, user.UserName); } } else { Help("Error: -Users, -Presets, -Projects, -Configurations, or -Scans option is required."); } } else { Help("Error: User/Pass was invalid. Please try again."); } } } else if (config.Command == Commands.report) { CxSDKWebService.CxWSReportRequest reportRequest = new CxSDKWebService.CxWSReportRequest(); reportRequest.ScanID = long.Parse(config.GetValueWithCheck("ScanId")); reportRequest.Type = CxSDKWebService.CxWSReportType.PDF; if (config.Keys.Contains("Format")) { string format = config.GetValueWithCheck("Format"); if (format.Equals("pdf", StringComparison.CurrentCultureIgnoreCase)) { reportRequest.Type = CxSDKWebService.CxWSReportType.PDF; } else if (format.Equals("csv", StringComparison.CurrentCultureIgnoreCase)) { reportRequest.Type = CxSDKWebService.CxWSReportType.CSV; } else if (format.Equals("rtf", StringComparison.CurrentCultureIgnoreCase)) { reportRequest.Type = CxSDKWebService.CxWSReportType.RTF; } else if (format.Equals("xml", StringComparison.CurrentCultureIgnoreCase)) { reportRequest.Type = CxSDKWebService.CxWSReportType.XML; } } using (CxWebService service = new CxWebService(config.UseSSL)) { if (service.Login(username, password)) { Console.Write(String.Format("Generating report for scan ID {0} in {1} format, please wait...", reportRequest.ScanID, reportRequest.Type.ToString().ToUpper())); long reportId = service.CreateScanReport(reportRequest); while (true) { CxSDKWebService.CxWSReportStatusResponse statusResponse = service.GetScanReportStatus(reportId); if (statusResponse.IsFailed) { Console.WriteLine("failed: {0}", statusResponse.ErrorMessage); break; } else if (statusResponse.IsReady) { Console.WriteLine("done."); Console.Write("Downloading report, please wait..."); string fileName = config.Keys.Contains("Out") ? config.GetValueWithCheck("Out") : Guid.NewGuid().ToString() + "." + reportRequest.Type.ToString().ToLower(); byte[] data = service.GetScanReport(reportId); File.WriteAllBytes(fileName, data); Console.WriteLine("done: {0}", fileName); break; } } } } } else if (config.Command == Commands.register) { string name = config.GetValueWithCheck("Name"); string uri = config.GetValueWithCheck("Url"); int minLoc = (config.Keys.Contains("MinLOC") ? config.GetValueWithCheck("MinLOC") : -1); int maxLoc = (config.Keys.Contains("MaxLOC") ? config.GetValueWithCheck("MaxLOC") : -1); bool blocked = (config.Keys.Contains("IsBlocked") ? config.GetValueWithCheck("IsBlocked") : false); CxRestService service = new CxRestService(new Uri(cxServer)); bool loggedIn = service.Login(username, password).GetAwaiter().GetResult(); if (!loggedIn) { Help("Error: User/Pass was invalid. Please try again."); } Console.Write("Registering scan engine '{0}' ({1}), please wait...", name, uri); int engineId = service.RegisterEngine(name, uri, minLoc, maxLoc, blocked).GetAwaiter().GetResult(); if (engineId != -1) { Console.WriteLine("complete: {0}", engineId); } else { Console.WriteLine("failed."); } } else if (config.Command == Commands.unregister) { int engineId = config.GetValueWithCheck("EngineId"); bool blockOnly = config.Keys.Contains("BlockOnly"); CxRestService service = new CxRestService(new Uri(cxServer)); bool loggedIn = service.Login(username, password).GetAwaiter().GetResult(); if (!loggedIn) { Help("Error: User/Pass was invalid. Please try again."); } Console.Write("Unregistering/Updating scan engine {0}, please wait...", engineId); bool allDone = false; if (blockOnly) { allDone = service.UpdateEngine(engineId, "", "", -1, -1, blockOnly).GetAwaiter().GetResult(); } else { allDone = service.UnregisterEngine(engineId).GetAwaiter().GetResult(); } if (allDone) { Console.WriteLine("done."); } else { Console.Error.WriteLine("failed."); } } }