public IEnumerable<PackageVerifierIssue> Validate(IPackageRepository packageRepo, IPackage package, IPackageVerifierLogger logger)
        {
            foreach (IPackageFile currentFile in package.GetFiles())
            {
                string extension = Path.GetExtension(currentFile.Path);
                if (extension.Equals(".dll", StringComparison.OrdinalIgnoreCase) ||
                    extension.Equals(".exe", StringComparison.OrdinalIgnoreCase))
                {
                    string assemblyPath = Path.ChangeExtension(Path.Combine(Path.GetTempPath(), Path.GetTempFileName()), extension);
                    var isManagedCode = false;
                    var isStrongNameSigned = false;
                    int hresult = 0;
                    try
                    {
                        using (Stream packageFileStream = currentFile.GetStream())
                        {
                            var _assemblyBytes = new byte[packageFileStream.Length];
                            packageFileStream.Read(_assemblyBytes, 0, _assemblyBytes.Length);

                            using (var fileStream = new FileStream(assemblyPath, FileMode.Create))
                            {
                                packageFileStream.Seek(0, SeekOrigin.Begin);
                                packageFileStream.CopyTo(fileStream);
                                fileStream.Flush(true);
                            }

                            if (AssemblyHelpers.IsAssemblyManaged(assemblyPath))
                            {
                                isManagedCode = true;
                                var clrStrongName = (IClrStrongName)RuntimeEnvironment.GetRuntimeInterfaceAsObject(new Guid("B79B0ACD-F5CD-409b-B5A5-A16244610B92"), new Guid("9FD93CCF-3280-4391-B3A9-96E1CDE77C8D"));
                                bool verificationForced;
                                hresult = clrStrongName.StrongNameSignatureVerificationEx(assemblyPath, true, out verificationForced);
                                if (hresult == 0)
                                {
                                    isStrongNameSigned = true;
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        logger.LogError("Error while verifying strong name signature for {0}: {1}", currentFile.Path, ex.Message);
                    }
                    finally
                    {
                        if (File.Exists(assemblyPath))
                        {
                            File.Delete(assemblyPath);
                        }
                    }
                    if (isManagedCode && !isStrongNameSigned)
                    {
                        yield return PackageIssueFactory.AssemblyNotStrongNameSigned(currentFile.Path, hresult);
                    }
                }
            }
            yield break;
        }
        public IEnumerable <PackageVerifierIssue> Validate(IPackageRepository packageRepo, IPackage package, IPackageVerifierLogger logger)
        {
            foreach (IPackageFile currentFile in package.GetFiles())
            {
                string extension = Path.GetExtension(currentFile.Path);
                if (extension.Equals(".dll", StringComparison.OrdinalIgnoreCase) ||
                    extension.Equals(".exe", StringComparison.OrdinalIgnoreCase))
                {
                    string assemblyPath       = Path.ChangeExtension(Path.Combine(Path.GetTempPath(), Path.GetTempFileName()), extension);
                    var    isManagedCode      = false;
                    var    isStrongNameSigned = false;
                    int    hresult            = 0;
                    try
                    {
                        using (Stream packageFileStream = currentFile.GetStream())
                        {
                            var _assemblyBytes = new byte[packageFileStream.Length];
                            packageFileStream.Read(_assemblyBytes, 0, _assemblyBytes.Length);

                            using (var fileStream = new FileStream(assemblyPath, FileMode.Create))
                            {
                                packageFileStream.Seek(0, SeekOrigin.Begin);
                                packageFileStream.CopyTo(fileStream);
                                fileStream.Flush(true);
                            }

                            if (AssemblyHelpers.IsAssemblyManaged(assemblyPath))
                            {
                                isManagedCode = true;
                                var  clrStrongName = (IClrStrongName)RuntimeEnvironment.GetRuntimeInterfaceAsObject(new Guid("B79B0ACD-F5CD-409b-B5A5-A16244610B92"), new Guid("9FD93CCF-3280-4391-B3A9-96E1CDE77C8D"));
                                bool verificationForced;
                                hresult = clrStrongName.StrongNameSignatureVerificationEx(assemblyPath, true, out verificationForced);
                                if (hresult == 0)
                                {
                                    isStrongNameSigned = true;
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        logger.LogError("Error while verifying strong name signature for {0}: {1}", currentFile.Path, ex.Message);
                    }
                    finally
                    {
                        if (File.Exists(assemblyPath))
                        {
                            File.Delete(assemblyPath);
                        }
                    }
                    if (isManagedCode && !isStrongNameSigned)
                    {
                        yield return(PackageIssueFactory.AssemblyNotStrongNameSigned(currentFile.Path, hresult));
                    }
                }
            }
            yield break;
        }
Exemple #3
0
        public IEnumerable <PackageVerifierIssue> Validate(IPackageRepository packageRepo, IPackage package, IPackageVerifierLogger logger)
        {
            string packagePath     = packageRepo.Source + "\\" + package.Id + "." + package.Version.ToString() + ".nupkg";
            string nupkgWithoutExt = Path.Combine(Path.GetDirectoryName(packagePath), Path.GetFileNameWithoutExtension(packagePath));

            try
            {
                UnzipPackage(nupkgWithoutExt);

                foreach (IPackageFile current in package.GetFiles())
                {
                    //string packagePath = package.FileSystem.Root + "\\" + Id + "." + Version + ".nupkg"
                    string extension = Path.GetExtension(current.Path);

                    // TODO: Need to add more extensions?
                    if (extension.Equals(".dll", StringComparison.OrdinalIgnoreCase) ||
                        extension.Equals(".exe", StringComparison.OrdinalIgnoreCase))
                    {
                        string pathOfFileToScan = Path.Combine(nupkgWithoutExt, current.Path);
                        var    realAssemblyPath = pathOfFileToScan;
                        if (!File.Exists(realAssemblyPath))
                        {
                            realAssemblyPath = pathOfFileToScan.Replace("+", "%2B").Replace("#", "%23");
                            if (!File.Exists(realAssemblyPath))
                            {
                                logger.LogError("The assembly '{0}' in this package can't be found (a bug in this tool, most likely).", current.Path);
                                continue;
                            }
                        }
                        bool isAuthenticodeSigned = WinTrust.IsAuthenticodeSigned(realAssemblyPath);
                        if (!isAuthenticodeSigned)
                        {
                            yield return(PackageIssueFactory.PEFileNotAuthenticodeSigned(current.Path));
                        }
                    }
                }
            }
            finally
            {
                CleanUpFolder(nupkgWithoutExt, logger);
            }

            yield break;
        }
        public IEnumerable<PackageVerifierIssue> Validate(IPackageRepository packageRepo, IPackage package, IPackageVerifierLogger logger)
        {
            string packagePath = packageRepo.Source + "\\" + package.Id + "." + package.Version.ToString() + ".nupkg";
            string nupkgWithoutExt = Path.Combine(Path.GetDirectoryName(packagePath), Path.GetFileNameWithoutExtension(packagePath));
            try
            {
                UnzipPackage(nupkgWithoutExt);

                foreach (IPackageFile current in package.GetFiles())
                {
                    //string packagePath = package.FileSystem.Root + "\\" + Id + "." + Version + ".nupkg"
                    string extension = Path.GetExtension(current.Path);

                    // TODO: Need to add more extensions?
                    if (extension.Equals(".dll", StringComparison.OrdinalIgnoreCase) ||
                        extension.Equals(".exe", StringComparison.OrdinalIgnoreCase))
                    {
                        string pathOfFileToScan = Path.Combine(nupkgWithoutExt, current.Path);
                        var realAssemblyPath = pathOfFileToScan;
                        if (!File.Exists(realAssemblyPath))
                        {
                            realAssemblyPath = pathOfFileToScan.Replace("+", "%2B").Replace("#", "%23");
                            if (!File.Exists(realAssemblyPath))
                            {
                                logger.LogError("The assembly '{0}' in this package can't be found (a bug in this tool, most likely).", current.Path);
                                continue;
                            }
                        }
                        bool isAuthenticodeSigned = WinTrust.IsAuthenticodeSigned(realAssemblyPath);
                        if (!isAuthenticodeSigned)
                        {
                            yield return PackageIssueFactory.PEFileNotAuthenticodeSigned(current.Path);
                        }
                    }
                }
            }
            finally
            {
                CleanUpFolder(nupkgWithoutExt, logger);
            }

            yield break;
        }
        private static int Execute(
            IDictionary <string, PackageSet> packageSets,
            IEnumerable <FileInfo> nupkgs,
            List <string> excludedRuleNames,
            IPackageVerifierLogger logger,
            IgnoreAssistanceMode ignoreAssistanceMode)
        {
            var allRules = typeof(Program).Assembly.GetTypes()
                           .Where(t =>
                                  typeof(IPackageVerifierRule).IsAssignableFrom(t) && !t.IsAbstract)
                           .ToDictionary(
                t => t.Name,
                t =>
            {
                var rule = (IPackageVerifierRule)Activator.CreateInstance(t);
                if (rule is CompositeRule compositeRule)
                {
                    return(compositeRule.GetRules());
                }
                else
                {
                    return(new[] { rule });
                }
            });

            var packages = nupkgs.ToDictionary(file =>
            {
                var reader = new PackageArchiveReader(file.FullName);
                return((IPackageMetadata) new PackageBuilder(reader.GetNuspec(), basePath: null));
            });

            var processedPackages = new HashSet <IPackageMetadata>();

            var totalErrors   = 0;
            var totalWarnings = 0;

            var ignoreAssistanceData = new Dictionary <string, PackageVerifierOptions>(
                StringComparer.OrdinalIgnoreCase);

            PackageSet defaultPackageSet = null;
            IEnumerable <IPackageVerifierRule> defaultRuleSet        = null;
            IEnumerable <IssueIgnore>          defaultIssuesToIgnore = null;

            foreach (var packageSet in packageSets)
            {
                logger.LogInfo(
                    "Processing package set '{0}' with {1} package(s)",
                    packageSet.Key,
                    packageSet.Value.Packages?.Count ?? 0);

                var packageSetRuleInfo = packageSet.Value.Rules;

                var packageSetRules = packageSetRuleInfo.SelectMany(
                    ruleId => allRules.SingleOrDefault(
                        rule => string.Equals(rule.Key, ruleId, StringComparison.OrdinalIgnoreCase)).Value)
                                      .Where(rule => !excludedRuleNames.Contains(rule.GetType().Name));

                if (string.Equals(packageSet.Key, "Default", StringComparison.OrdinalIgnoreCase))
                {
                    defaultPackageSet     = packageSet.Value;
                    defaultRuleSet        = packageSetRules;
                    defaultIssuesToIgnore = GetIgnoresFromFile(packageSet.Value.Packages);
                    continue;
                }

                var analyzer = new PackageAnalyzer();
                foreach (var ruleInstance in packageSetRules)
                {
                    analyzer.Rules.Add(ruleInstance);
                }

                var issuesToIgnore = GetIgnoresFromFile(packageSet.Value.Packages);

                var issueProcessor = new IssueProcessor(issuesToIgnore);

                if (packageSet.Value.Packages != null)
                {
                    foreach (var packageInfo in packageSet.Value.Packages)
                    {
                        var packageId = packageInfo.Key;

                        var packagesWithId = packages.Where(p => p.Key.Id.Equals(packageId));
                        if (!packagesWithId.Any())
                        {
                            logger.LogError("Couldn't find package '{0}' in the repo", packageId);
                            totalErrors++;
                            continue;
                        }

                        foreach (var packagePair in packagesWithId)
                        {
                            var package = packagePair.Key;
                            logger.LogInfo("Analyzing {0} ({1})", package.Id, package.Version);

                            List <PackageVerifierIssue> issues;
                            using (var context = new PackageAnalysisContext
                            {
                                PackageFileInfo = packagePair.Value,
                                Metadata = package,
                                Logger = logger,
                                Options = packageInfo.Value,
                            })
                            {
                                issues = analyzer.AnalyzePackage(context).ToList();
                            }

                            var packageErrorsAndWarnings = ProcessPackageIssues(
                                ignoreAssistanceMode,
                                logger,
                                issueProcessor,
                                ignoreAssistanceData,
                                package,
                                issues);

                            totalErrors   += packageErrorsAndWarnings.Item1;
                            totalWarnings += packageErrorsAndWarnings.Item2;

                            processedPackages.Add(package);
                        }
                    }
                }

                foreach (var issue in issueProcessor.RemainingIssuesToIgnore)
                {
                    // TODO: Don't show this for rules that we don't run.
                    logger.LogWarning(
                        "Unnecessary exclusion in {0}{3}Issue: {1}{3}Instance: {2}{3}",
                        issue.PackageId,
                        issue.IssueId,
                        issue.Instance,
                        Environment.NewLine);
                }
            }

            var unlistedPackages = packages.Keys.Except(processedPackages);

            if (unlistedPackages.Any())
            {
                // For unlisted packages we run the rules from 'Default' package set if present
                // or we run all rules (because we have no idea what exactly to run)
                var analyzer             = new PackageAnalyzer();
                var unlistedPackageRules = defaultRuleSet ??
                                           allRules.Values.SelectMany(f => f).Where(r => !excludedRuleNames.Contains(r.GetType().Name));

                foreach (var ruleInstance in unlistedPackageRules)
                {
                    analyzer.Rules.Add(ruleInstance);
                }

                var issueProcessor = new IssueProcessor(issuesToIgnore: defaultIssuesToIgnore);

                foreach (var unlistedPackage in unlistedPackages)
                {
                    logger.LogInfo("Analyzing {0} ({1})", unlistedPackage.Id, unlistedPackage.Version);

                    List <PackageVerifierIssue> issues;
                    PackageVerifierOptions      packageOptions = null;
                    defaultPackageSet?.Packages?.TryGetValue(unlistedPackage.Id, out packageOptions);

                    using (var context = new PackageAnalysisContext
                    {
                        PackageFileInfo = packages[unlistedPackage],
                        Metadata = unlistedPackage,
                        Logger = logger,
                        Options = packageOptions,
                    })
                    {
                        issues = analyzer.AnalyzePackage(context).ToList();
                    }

                    var packageErrorsAndWarnings = ProcessPackageIssues(
                        ignoreAssistanceMode,
                        logger,
                        issueProcessor,
                        ignoreAssistanceData,
                        unlistedPackage,
                        issues);

                    totalErrors   += packageErrorsAndWarnings.Item1;
                    totalWarnings += packageErrorsAndWarnings.Item2;
                }

                foreach (var issue in issueProcessor.RemainingIssuesToIgnore)
                {
                    // TODO: Don't show this for rules that we don't run.
                    logger.LogWarning(
                        "Unnecessary exclusion in {0}{3}Issue: {1}{3}Instance: {2}{3}",
                        issue.PackageId,
                        issue.IssueId,
                        issue.Instance,
                        Environment.NewLine);
                }
            }

            if (ignoreAssistanceMode != IgnoreAssistanceMode.None && ignoreAssistanceData.Any())
            {
                Console.WriteLine("Showing JSON for ignore content:");
                Console.WriteLine(JsonConvert.SerializeObject(ignoreAssistanceData,
                                                              Formatting.Indented,
                                                              new JsonSerializerSettings
                {
                    NullValueHandling = NullValueHandling.Ignore
                }));
                Console.WriteLine();
            }

            var errorLevel = LogLevel.Normal;

            if (totalWarnings > 0)
            {
                errorLevel = LogLevel.Warning;
            }
            if (totalErrors > 0)
            {
                errorLevel = LogLevel.Error;
            }
            logger.Log(
                errorLevel,
                "SUMMARY: {0} error(s) and {1} warning(s) found",
                totalErrors, totalWarnings);



            return((totalErrors + totalWarnings > 0) ? ReturnErrorsOrWarnings : ReturnOk);
        }