/// <summary> /// 获取项目全称 /// </summary> /// <param name="userInfo">用户</param> /// <param name="id">主键</param> /// <returns>项目全称</returns> public string GetProjectFullName(BaseUserInfo userInfo, string id) { // 写入调试信息 #if (DEBUG) int milliStart = BaseBusinessLogic.StartDebug(userInfo, MethodBase.GetCurrentMethod()); #endif string returnValue = string.Empty; IDbHelper dbHelper = DbHelperFactory.GetHelper(); try { dbHelper.Open(UserCenterDbConnection); BaseProjectManager projectManager = new BaseProjectManager(dbHelper, userInfo); returnValue = projectManager.GetFullName(id); BaseLogManager.Instance.Add(dbHelper, userInfo, MethodBase.GetCurrentMethod()); } catch (Exception ex) { BaseExceptionManager.LogException(dbHelper, userInfo, ex); throw ex; } finally { dbHelper.Close(); } // 写入调试信息 #if (DEBUG) BaseBusinessLogic.EndDebug(MethodBase.GetCurrentMethod(), milliStart); #endif return(returnValue); }
public async Task TestVersionSort(string preSortS, string postSortS) { string[]? preSort = preSortS.Split(new[] { ',' }); string[]? postSort = postSortS.Split(new[] { ',' }); System.Collections.Generic.IEnumerable <string>?result = BaseProjectManager.SortVersions(preSort); Assert.IsTrue(result.SequenceEqual(postSort), $"Result {string.Join(',', result)} != {string.Join(',', postSort)}"); }
public async Task FindSource(PackageURL purl) { var purlNoVersion = new PackageURL(purl.Type, purl.Namespace, purl.Name, null, purl.Qualifiers, purl.Subpath); Logger.Debug("Searching for source code for {0}", purlNoVersion.ToString()); // Use reflection to find the correct downloader class var projectManagerClass = typeof(BaseProjectManager).Assembly.GetTypes() .Where(type => type.IsSubclassOf(typeof(BaseProjectManager))) .Where(type => type.Name.Equals($"{purl.Type}ProjectManager", StringComparison.InvariantCultureIgnoreCase)) .FirstOrDefault(); if (projectManagerClass != null) { var ctor = projectManagerClass.GetConstructor(Array.Empty <Type>()); var projectManager = (BaseProjectManager)(ctor.Invoke(Array.Empty <object>())); var content = await projectManager.GetMetadata(purlNoVersion); foreach (var githubPurl in BaseProjectManager.ExtractGitHubPackageURLs(content)) { var githubUrl = $"https://github.com/{githubPurl.Namespace}/{githubPurl.Name}"; Logger.Info("Found: {0} ({1})", githubPurl.ToString(), githubUrl); } } else { throw new ArgumentException("Invalid Package URL type: {0}", purlNoVersion.Type); } }
public async Task TestVersionSort(string preSortS, string postSortS) { var preSort = preSortS.Split(new[] { ',' }); var postSort = postSortS.Split(new[] { ',' }); var result = BaseProjectManager.SortVersions(preSort); Assert.IsTrue(result.SequenceEqual(postSort), $"Result {string.Join(',', result)} != {string.Join(',', postSort)}"); }
/// <summary> /// Formulates the help text for each derived tool /// </summary> /// <typeparam name="T"> </typeparam> /// <param name="result"> </param> /// <param name="errs"> </param> protected void DisplayHelp <T>(ParserResult <T> result, IEnumerable <Error> errs) { HelpText helpText = HelpText.AutoBuild(result, h => { h.AddDashesToOption = true; h.AutoVersion = true; h.AdditionalNewLineAfterOption = false; h.MaximumDisplayWidth = Console.WindowWidth; h.AddPostOptionsLines(BaseProjectManager.GetCommonSupportedHelpTextLines()); return(HelpText.DefaultParsingErrorsHandler(result, h)); }); Console.Error.Write(helpText); }
/// <summary> /// Displays usage information for the program. /// </summary> private static void ShowUsage() { Console.Error.WriteLine($@" {TOOL_NAME} {VERSION} Usage: {TOOL_NAME} [options] package-url... positional arguments: package-url PackgeURL specifier to analyze (required, repeats OK) {BaseProjectManager.GetCommonSupportedHelpText()} optional arguments: --help show this help message and exit --version show version of this tool "); }
/// <summary> /// Displays usage information for the program. /// </summary> private static void ShowUsage() { Console.Error.WriteLine($@" {TOOL_NAME} {VERSION} Usage: {TOOL_NAME} [options] package-url... positional arguments: package-url package url to analyze (required, multiple allowed) {BaseProjectManager.GetCommonSupportedHelpText()} optional arguments: --help show this help message and exit --version show version number "); }
/// <summary> /// Displays usage information for the program. /// </summary> private static void ShowUsage() { Console.Error.WriteLine($@" {TOOL_NAME} {VERSION} Usage: {TOOL_NAME} [options] package-url... positional arguments: package-url PackgeURL specifier to download (required, repeats OK) {BaseProjectManager.GetCommonSupportedHelpText()} optional arguments: --custom-rule-directory DIR load rules from directory DIR --disable-default-rules do not load default, built-in rules. --help show this help message and exit --version show version of this tool "); }
public async Task <HealthMetrics> CheckHealth(PackageURL purl) { // Use reflection to find the correct package management class var projectManagerClass = typeof(BaseProjectManager).Assembly.GetTypes() .Where(type => type.IsSubclassOf(typeof(BaseProjectManager))) .Where(type => type.Name.Equals($"{purl.Type}ProjectManager", StringComparison.InvariantCultureIgnoreCase)) .FirstOrDefault(); if (projectManagerClass != default) { var ctor = projectManagerClass.GetConstructor(Array.Empty <Type>()); var projectManager = (BaseProjectManager)(ctor.Invoke(Array.Empty <object>())); var content = await projectManager.GetMetadata(purl); if (!string.IsNullOrWhiteSpace(content)) { foreach (var githubPurl in BaseProjectManager.ExtractGitHubPackageURLs(content)) { try { var healthAlgorithm = new GitHubHealthAlgorithm(githubPurl); var health = await healthAlgorithm.GetHealth(); return(health); } catch (Exception ex) { Logger.Warn(ex, "Unable to calculate health for {0}: {1}", githubPurl, ex.Message); } } } else { Logger.Warn("No metadata found for {0}", purl.ToString()); } } else { throw new ArgumentException("Invalid Package URL type: {0}", purl.Type); } return(default);
public async Task <IEnumerable <PackageURL> > FindSource(PackageURL purl) { var purlNoVersion = new PackageURL(purl.Type, purl.Namespace, purl.Name, null, purl.Qualifiers, purl.Subpath); Logger.Debug("Searching for source code for {0}", purlNoVersion.ToString()); // Use reflection to find the correct downloader class var projectManagerClass = typeof(BaseProjectManager).Assembly.GetTypes() .Where(type => type.IsSubclassOf(typeof(BaseProjectManager))) .Where(type => type.Name.Equals($"{purl.Type}ProjectManager", StringComparison.InvariantCultureIgnoreCase)) .FirstOrDefault(); var sourceList = new List <PackageURL>(); if (projectManagerClass != default) { var ctor = projectManagerClass.GetConstructor(Array.Empty <Type>()); var projectManager = (BaseProjectManager)(ctor.Invoke(Array.Empty <object>())); var content = await projectManager.GetMetadata(purlNoVersion); if (!string.IsNullOrWhiteSpace(content)) { foreach (var githubPurl in BaseProjectManager.ExtractGitHubPackageURLs(content)) { sourceList.Add(githubPurl); Logger.Debug("Identified GitHub Source: {0})", githubPurl.ToString()); } } else { Logger.Warn("No metadata found for {0}", purlNoVersion.ToString()); } } else { throw new ArgumentException("Invalid Package URL type: {0}", purlNoVersion.Type); } return(sourceList); }
/// <summary> /// Displays usage information for the program. /// </summary> private static void ShowUsage() { Console.Error.WriteLine($@" {TOOL_NAME} {VERSION} Usage: {TOOL_NAME} [options] package-url... positional arguments: package-url PackgeURL specifier to download (required, repeats OK), or directory. {BaseProjectManager.GetCommonSupportedHelpText()} optional arguments: --verbose increase output verbosity --custom-rule-directory DIR load rules from directory DIR --disable-default-rules do not load default, built-in rules. --download-directory the directory to download the package to --use-cache do not download the package if it is already present in the destination directory --format selct the output format (text|sarifv1|sarifv2). (default is text) --output-file send the command output to a file instead of stdout --help show this help message and exit --version show version of this tool "); }
/// <summary> /// Main entrypoint for the download program. /// </summary> /// <param name="args">parameters passed in from the user</param> static async Task Main(string[] args) { var detectCryptographyTool = new DetectCryptographyTool(); Logger.Info($"Microsoft OSS Gadget - {TOOL_NAME} {VERSION}"); detectCryptographyTool.ParseOptions(args); if (((IList <string>)detectCryptographyTool.Options["target"]).Count > 0) { foreach (var target in (IList <string>)detectCryptographyTool.Options["target"]) { var sb = new StringBuilder(); try { List <IssueRecord> results = null; if (target.StartsWith("pkg:", StringComparison.InvariantCulture)) { var purl = new PackageURL(target); results = await detectCryptographyTool.AnalyzePackage(purl); } else if (Directory.Exists(target)) { results = await detectCryptographyTool.AnalyzeDirectory(target); } else if (File.Exists(target)) { string targetDirectoryName = null; while (targetDirectoryName == null || Directory.Exists(targetDirectoryName)) { targetDirectoryName = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); } var projectManager = new BaseProjectManager() { TopLevelExtractionDirectory = targetDirectoryName }; #pragma warning disable SCS0018 // Path traversal: injection possible in {1} argument passed to '{0}' var path = await projectManager.ExtractArchive("temp", File.ReadAllBytes(target)); #pragma warning restore SCS0018 // Path traversal: injection possible in {1} argument passed to '{0}' results = await detectCryptographyTool.AnalyzeDirectory(path); // Clean up after ourselves try { if (targetDirectoryName != null) { Directory.Delete(targetDirectoryName, true); } } catch (Exception ex) { Logger.Warn("Unable to delete {0}: {1}", targetDirectoryName, ex.Message); } } if (!results.Any()) { sb.AppendLine($"[ ] {target} - This software package does NOT appear to implement cryptography."); } else { var shortTags = results.SelectMany(r => r.Issue.Rule.Tags) .Distinct() .Where(t => t.StartsWith("Cryptography.Implementation.")) .Select(t => t.Replace("Cryptography.Implementation.", "")); var otherTags = results.SelectMany(r => r.Issue.Rule.Tags) .Distinct() .Where(t => !t.StartsWith("Cryptography.Implementation.")); if (shortTags.Count() > 0) { sb.AppendLine($"[X] {target} - This software package appears to implement {string.Join(", ", shortTags)}."); } if (otherTags.Contains("Cryptography.GenericImplementation.HighDensityOperators")) { sb.AppendLine($"[X] {target} - This software package has a high-density of cryptographic operators."); } else { sb.AppendLine($"[ ] {target} - This software package does NOT have a high-density of cryptographic operators."); } if (otherTags.Contains("Cryptography.GenericImplementation.CryptographicWords")) { sb.AppendLine($"[X] {target} - This software package contains words that suggest cryptography."); } else { sb.AppendLine($"[ ] {target} - This software package does NOT contains words that suggest cryptography."); } if ((bool)detectCryptographyTool.Options["verbose"]) { var items = results.GroupBy(k => k.Issue.Rule.Name).OrderByDescending(k => k.Count()); foreach (var item in items) { sb.AppendLine(); sb.AppendLine($"There were {item.Count()} finding(s) of type [{item.Key}]."); foreach (var result in results) { if (result.Issue.Rule.Name == item.Key) { sb.AppendLine($" {result.Filename}:"); if (result.Issue.Rule.Id == "_CRYPTO_DENSITY") { // No excerpt for cryptogrpahic density // TODO: We stuffed the density in the unused 'Description' field. This is code smell. sb.AppendLine($" | The maximum cryptographic density is {result.Issue.Rule.Description}."); } else { // Show the excerpt foreach (var line in result.TextSample.Split(new char[] { '\n', '\r' })) { if (!string.IsNullOrWhiteSpace(line)) { sb.AppendLine($" | {line.Trim()}"); } } } sb.AppendLine(); } } } } if (Logger.IsDebugEnabled) { foreach (var result in results) { Logger.Debug($"Result: {result.Filename} {result.Issue.Rule.Name} {result.TextSample}"); } } } Console.WriteLine(sb.ToString()); } catch (Exception ex) { Logger.Warn(ex, "Error processing {0}: {1}", target, ex.Message); Logger.Warn(ex.StackTrace); } } } else { Logger.Warn("No target provided; nothing to analyze."); DetectCryptographyTool.ShowUsage(); Environment.Exit(1); } }
/// <summary> /// 获取项目全称 /// </summary> /// <param name="userInfo">用户</param> /// <param name="id">主键</param> /// <returns>项目全称</returns> public string GetProjectFullName(BaseUserInfo userInfo, string id) { // 写入调试信息 #if (DEBUG) int milliStart = BaseBusinessLogic.StartDebug(userInfo, MethodBase.GetCurrentMethod()); #endif string returnValue = string.Empty; IDbHelper dbHelper = DbHelperFactory.GetHelper(); try { dbHelper.Open(UserCenterDbConnection); BaseProjectManager projectManager = new BaseProjectManager(dbHelper, userInfo); returnValue = projectManager.GetFullName(id); BaseLogManager.Instance.Add(dbHelper, userInfo, MethodBase.GetCurrentMethod()); } catch (Exception ex) { BaseExceptionManager.LogException(dbHelper, userInfo, ex); throw ex; } finally { dbHelper.Close(); } // 写入调试信息 #if (DEBUG) BaseBusinessLogic.EndDebug(MethodBase.GetCurrentMethod(), milliStart); #endif return returnValue; }