Example #1
0
 public IEnumerable <PackageVerifierIssue> Validate(PackageAnalysisContext context)
 {
     if (!SemanticVersion.TryParse(context.Metadata.Version.ToString(), out var _))
     {
         yield return(PackageIssueFactory.NotSemanticVersion(context.Metadata.Version));
     }
 }
        public IEnumerable <PackageVerifierIssue> Validate(PackageAnalysisContext context)
        {
            var repoMetadata = context.PackageReader.NuspecReader.GetRepositoryMetadata();

            if (repoMetadata == null)
            {
                yield return(PackageIssueFactory.PackageRepositoryMetadataMissing());
            }
            else
            {
                if (string.IsNullOrEmpty(repoMetadata.Url))
                {
                    yield return(PackageIssueFactory.PackageRepositoryUrl());
                }

                if (string.IsNullOrEmpty(repoMetadata.Type))
                {
                    yield return(PackageIssueFactory.PackageRepositoryType());
                }

                if (string.IsNullOrEmpty(repoMetadata.Commit))
                {
                    yield return(PackageIssueFactory.PackageRepositoryCommit());
                }
            }
        }
Example #3
0
        public IEnumerable <PackageVerifierIssue> Validate(PackageAnalysisContext context)
        {
            if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                throw new InvalidOperationException("Package sign verification is only supported on Windows machines");
            }

            var args = new[]
            {
                "verify",
                "-NonInteractive",
                "-All",
                context.PackageFileInfo.FullName,
            };

            var psi = new ProcessStartInfo
            {
                FileName  = _nuGetExePath,
                Arguments = ArgumentEscaper.EscapeAndConcatenate(args),
                RedirectStandardOutput = true,
            };

            var process = Process.Start(psi);

            process.WaitForExit(60 * 1000);

            if (process.ExitCode != 0)
            {
                var issueText = process.StandardOutput.ReadToEnd();
                yield return(PackageIssueFactory.PackageSignVerificationFailed(context.Metadata.Id, issueText));
            }
        }
 public IEnumerable <PackageVerifierIssue> Validate(PackageAnalysisContext context)
 {
     if (!string.Equals(context.Metadata.Copyright, ExpectedCopyright, StringComparison.Ordinal))
     {
         yield return(PackageIssueFactory.CopyrightIsIncorrect(context.Metadata.Id, ExpectedCopyright, context.Metadata.Copyright));
     }
 }
Example #5
0
        public IEnumerable <PackageVerifierIssue> Validate(PackageAnalysisContext context)
        {
            if (context.Metadata.PackageTypes.Any(p => p == PackageType.DotnetCliTool))
            {
                yield break;
            }

            if (!context.PackageReader.IsSatellitePackage())
            {
                var allXmlFiles =
                    from item in context.PackageReader.GetLibItems()
                    from file in item.Items
                    select file into path
                    where path.EndsWith(".xml", StringComparison.OrdinalIgnoreCase)
                    select path;

                foreach (var current in context.PackageReader.GetLibItems())
                {
                    foreach (var item in current.Items)
                    {
                        var assemblyPath = item;
                        // TODO: Does this need to check for just managed code?
                        if (assemblyPath.EndsWith(".dll", StringComparison.OrdinalIgnoreCase))
                        {
                            var docFilePath = Path.ChangeExtension(assemblyPath, ".xml");
                            if (!allXmlFiles.Contains(docFilePath, StringComparer.OrdinalIgnoreCase))
                            {
                                yield return(PackageIssueFactory.AssemblyHasNoDocFile(assemblyPath));
                            }
                        }
                    }
                }
            }
        }
Example #6
0
 public IEnumerable <PackageVerifierIssue> Validate(PackageAnalysisContext context)
 {
     foreach (var rule in _rules)
     {
         foreach (var issue in rule.Validate(context))
         {
             yield return(issue);
         }
     }
 }
Example #7
0
 public IEnumerable <PackageVerifierIssue> Validate(PackageAnalysisContext context)
 {
     AssemblyAttributesDataHelper.SetAssemblyAttributesData(context);
     foreach (var assemblyData in context.AssemblyData)
     {
         if (!HasDescriptionAttribute(assemblyData.Value.AssemblyAttributes))
         {
             yield return(PackageIssueFactory.AssemblyMissingDescriptionAttribute(assemblyData.Key));
         }
     }
 }
Example #8
0
        public IEnumerable <PackageVerifierIssue> Validate(PackageAnalysisContext context)
        {
            if (context.Metadata.PackageTypes.Any(p => p == Constants.DotNetTool))
            {
                // Skip for dotnet global tool packages which contain assemblies from other teams and projects
                yield break;
            }

            AssemblyAttributesDataHelper.SetAssemblyAttributesData(context);
            foreach (var assemblyData in context.AssemblyData)
            {
                var assemblyInformationalVersionAttribute = assemblyData.Value.AssemblyAttributes.SingleOrDefault(a =>
                                                                                                                  a.AttributeType.FullName.Equals(
                                                                                                                      typeof(AssemblyInformationalVersionAttribute).FullName,
                                                                                                                      StringComparison.Ordinal));

                var infoVersion = assemblyInformationalVersionAttribute?.ConstructorArguments[0].Value?.ToString();

                if (!NuGetVersion.TryParse(infoVersion, out var assemblyInformationalNuGetVersion) ||
                    !VersionEquals(context.Metadata.Version, assemblyInformationalNuGetVersion))
                {
                    yield return(PackageIssueFactory.AssemblyInformationalVersionDoesNotMatchPackageVersion(
                                     assemblyData.Key,
                                     infoVersion,
                                     context.Metadata.Version,
                                     context.Metadata.Id));
                }

                var assemblyFileVersionAttribute = assemblyData.Value.AssemblyAttributes.SingleOrDefault(a =>
                                                                                                         a.AttributeType.FullName.Equals(
                                                                                                             typeof(AssemblyFileVersionAttribute).FullName,
                                                                                                             StringComparison.Ordinal));

                var assemblyFileNuGetVersion = new NuGetVersion(assemblyFileVersionAttribute.ConstructorArguments[0].Value.ToString());
                if (!VersionEquals(context.Metadata.Version, assemblyFileNuGetVersion))
                {
                    yield return(PackageIssueFactory.AssemblyFileVersionDoesNotMatchPackageVersion(
                                     assemblyData.Key,
                                     assemblyFileNuGetVersion,
                                     context.Metadata.Version,
                                     context.Metadata.Id));
                }

                var assemblyVersion = assemblyData.Value.AssemblyName.Version;
                if (!context.Metadata.Version.Version.Equals(assemblyVersion))
                {
                    yield return(PackageIssueFactory.AssemblyVersionDoesNotMatchPackageVersion(
                                     assemblyData.Key,
                                     assemblyVersion,
                                     context.Metadata.Version.Version,
                                     context.Metadata.Id));
                }
            }
        }
Example #9
0
        public IEnumerable <PackageVerifierIssue> Validate(PackageAnalysisContext context)
        {
            if (!context.Metadata.PackageTypes.Any(p => p == Constants.DotNetTool))
            {
                yield break;
            }

            var packageFiles = context.PackageReader.GetFiles();
            var manifests    = packageFiles?.Where(f => Path.GetFileName(f).Equals(ToolManifestFileName, StringComparison.Ordinal)) ?? Enumerable.Empty <string>();

            if (packageFiles == null || manifests.Count() == 0)
            {
                yield return(PackageIssueFactory.DotNetToolMustHaveManifest(Constants.DotNetTool.Name, ToolManifestFileName));

                yield break;
            }

            foreach (var manifestPath in manifests)
            {
                var manifestDir = Path.GetDirectoryName(manifestPath).Replace('\\', '/');

                var manifestStream = context.PackageReader.GetStream(manifestPath);
                var manifest       = XDocument.Load(manifestStream);

                AssemblyAttributesDataHelper.SetAssemblyAttributesData(context);

                var commands = manifest.Descendants("Command");
                foreach (var command in commands)
                {
                    var name = command.Attribute("Name");
                    if (string.IsNullOrEmpty(name?.Value))
                    {
                        yield return(PackageIssueFactory.DotNetToolMalformedManifest(manifestPath, "Missing Name"));

                        continue;
                    }

                    var entryPoint = command.Attribute("EntryPoint");
                    if (entryPoint?.Value == null)
                    {
                        yield return(PackageIssueFactory.DotNetToolMalformedManifest(manifestPath, "Missing EntryPoint"));

                        continue;
                    }

                    var entryPointPath = manifestDir + '/' + entryPoint.Value;
                    if (!packageFiles.Any(a => a.Equals(entryPointPath, StringComparison.Ordinal)))
                    {
                        yield return(PackageIssueFactory.DotNetToolMissingEntryPoint(manifestPath, entryPoint.Value));
                    }
                }
            }
        }
 public IEnumerable <PackageVerifierIssue> Validate(PackageAnalysisContext context)
 {
     AssemblyAttributesDataHelper.SetAssemblyAttributesData(context);
     foreach (var assemblyData in context.AssemblyData)
     {
         var fileName         = Path.GetFileNameWithoutExtension(assemblyData.Key);
         var isSourcesPackage = fileName.EndsWith(".Sources", StringComparison.OrdinalIgnoreCase);
         if (!isSourcesPackage && !HasCommitHashInMetadataAttribute(assemblyData.Value.AssemblyAttributes))
         {
             yield return(PackageIssueFactory.AssemblyMissingHashAttribute(assemblyData.Key));
         }
     }
 }
        public static void SetAssemblyAttributesData(PackageAnalysisContext context)
        {
            if (context.AssemblyData.Any())
            {
                return;
            }

            foreach (var currentFile in context.PackageReader.GetFiles())
            {
                var extension = Path.GetExtension(currentFile);
                if (extension.Equals(".dll", StringComparison.OrdinalIgnoreCase) ||
                    extension.Equals(".exe", StringComparison.OrdinalIgnoreCase))
                {
                    string assemblyPath;
                    do
                    {
                        assemblyPath = Path.ChangeExtension(
                            Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()), extension);
                    } while (File.Exists(assemblyPath));

                    try
                    {
                        using (var packageFileStream = context.PackageReader.GetStream(currentFile))
                            using (var fileStream = new FileStream(assemblyPath, FileMode.Create))
                            {
                                packageFileStream.CopyTo(fileStream);
                            }

                        if (AssemblyHelpers.IsAssemblyManaged(assemblyPath))
                        {
                            using (var assembly = AssemblyDefinition.ReadAssembly(assemblyPath))
                            {
                                var asmAttrs = assembly.CustomAttributes;
                                context.AssemblyData.Add(currentFile, new AssemblyAttributesData
                                {
                                    AssemblyName       = assembly.Name,
                                    AssemblyAttributes = asmAttrs,
                                });
                            }
                        }
                    }
                    finally
                    {
                        if (File.Exists(assemblyPath))
                        {
                            File.Delete(assemblyPath);
                        }
                    }
                }
            }
        }
 public IEnumerable <PackageVerifierIssue> Validate(PackageAnalysisContext context)
 {
     foreach (var current in context.PackageReader.GetFiles())
     {
         var extension = Path.GetExtension(current);
         if (PowerShellExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase))
         {
             if (!VerifySigned(context.PackageReader, current))
             {
                 yield return(PackageIssueFactory.PowerShellScriptNotSigned(current));
             }
         }
     }
 }
Example #13
0
        public IEnumerable <PackageVerifierIssue> Validate(PackageAnalysisContext context)
        {
            var discoveredTypes = context.Metadata.PackageTypes.Select(t => t.Name);
            var expectedTypes   = context.Options?.PackageTypes ?? Enumerable.Empty <string>();

            foreach (var missing in expectedTypes.Except(discoveredTypes))
            {
                yield return(PackageIssueFactory.PackageTypeMissing(missing));
            }

            foreach (var unexpected in discoveredTypes.Except(expectedTypes))
            {
                yield return(PackageIssueFactory.PackageTypeUnexpected(unexpected));
            }
        }
 public IEnumerable <PackageVerifierIssue> Validate(PackageAnalysisContext context)
 {
     if (string.IsNullOrEmpty(context.Metadata.Description))
     {
         yield return(PackageIssueFactory.RequiredDescription());
     }
     if (string.IsNullOrEmpty(context.Metadata.Tags))
     {
         yield return(PackageIssueFactory.RequiredTags());
     }
     if (string.IsNullOrEmpty(context.Metadata.Id))
     {
         yield return(PackageIssueFactory.RequiredId());
     }
 }
        public IEnumerable <PackageVerifierIssue> Validate(PackageAnalysisContext context)
        {
            AssemblyAttributesDataHelper.SetAssemblyAttributesData(context);
            foreach (var assemblyData in context.AssemblyData)
            {
                if (!HasAttrWithArg(assemblyData.Value.AssemblyAttributes, typeof(AssemblyFileVersionAttribute).FullName))
                {
                    yield return(PackageIssueFactory.AssemblyMissingFileVersionAttribute(assemblyData.Key));
                }

                if (!HasAttrWithArg(assemblyData.Value.AssemblyAttributes, typeof(AssemblyInformationalVersionAttribute).FullName))
                {
                    yield return(PackageIssueFactory.AssemblyMissingInformationalVersionAttribute(assemblyData.Key));
                }
            }
        }
Example #16
0
        public IEnumerable <PackageVerifierIssue> Validate(PackageAnalysisContext context)
        {
            if (context.Metadata.IsDotNetToolPackage())
            {
                yield break;
            }

            AssemblyAttributesDataHelper.SetAssemblyAttributesData(context);
            foreach (var assemblyData in context.AssemblyData)
            {
                if (!HasNeutralResourcesLanguageAttribute(assemblyData.Value.AssemblyAttributes))
                {
                    yield return(PackageIssueFactory.AssemblyMissingNeutralResourcesLanguageAttribute(assemblyData.Key));
                }
            }
        }
Example #17
0
        public IEnumerable <PackageVerifierIssue> Validate(PackageAnalysisContext context)
        {
            if (ExternallyOwnedPackageIds.Contains(context.Metadata.Id, StringComparer.OrdinalIgnoreCase))
            {
                yield return(PackageIssueFactory.IdIsNotOwned(context.Metadata.Id));
            }

            if (OwnedPackageIds.Contains(context.Metadata.Id, StringComparer.OrdinalIgnoreCase))
            {
                yield break;
            }

            if (OwnedPrefixes.Any(prefix => context.Metadata.Id.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)))
            {
                yield break;
            }
        }
Example #18
0
        public IEnumerable <PackageVerifierIssue> Validate(PackageAnalysisContext context)
        {
            foreach (var dependencyGroup in context.Metadata.DependencyGroups)
            {
                foreach (var packageDependency in dependencyGroup.Packages)
                {
                    if (packageDependency.VersionRange.HasUpperBound)
                    {
                        yield return(PackageIssueFactory.DependencyVersionHasUpperBound(context.Metadata.Id, packageDependency.Id, dependencyGroup.TargetFramework));
                    }

                    if (!packageDependency.VersionRange.HasLowerBound)
                    {
                        yield return(PackageIssueFactory.DependencyVersionDoesNotHaveLowerBound(context.Metadata.Id, packageDependency.Id, dependencyGroup.TargetFramework));
                    }
                }
            }
        }
Example #19
0
 public IEnumerable <PackageVerifierIssue> Validate(PackageAnalysisContext context)
 {
     if (context.PackageReader.IsSatellitePackage())
     {
         if (context.Metadata.Summary.Contains("{"))
         {
             yield return(PackageIssueFactory.Satellite_PackageSummaryNotLocalized());
         }
         if (context.Metadata.Title.Contains("{"))
         {
             yield return(PackageIssueFactory.Satellite_PackageTitleNotLocalized());
         }
         if (context.Metadata.Description.Contains("{"))
         {
             yield return(PackageIssueFactory.Satellite_PackageDescriptionNotLocalized());
         }
     }
 }
Example #20
0
        public IEnumerable <PackageVerifierIssue> Validate(PackageAnalysisContext context)
        {
            var extractPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());

            try
            {
                UnzipPackage(context.PackageFileInfo, extractPath);
                foreach (var current in context.PackageReader.GetFiles())
                {
                    //string packagePath = package.FileSystem.Root + "\\" + Id + "." + Version + ".nupkg"
                    var extension = Path.GetExtension(current);

                    // TODO: Need to add more extensions?
                    if (extension.Equals(".dll", StringComparison.OrdinalIgnoreCase) ||
                        extension.Equals(".exe", StringComparison.OrdinalIgnoreCase))
                    {
                        var pathOfFileToScan = Path.Combine(extractPath, current);
                        var realAssemblyPath = pathOfFileToScan;
                        if (!File.Exists(realAssemblyPath))
                        {
                            realAssemblyPath = pathOfFileToScan.Replace("+", "%2B").Replace("#", "%23");
                            if (!File.Exists(realAssemblyPath))
                            {
                                context.Logger.LogError(
                                    "The assembly '{0}' in this package can't be found (a bug in this tool, most likely).",
                                    current);

                                continue;
                            }
                        }

                        var isAuthenticodeSigned = WinTrust.IsAuthenticodeSigned(realAssemblyPath);
                        if (!isAuthenticodeSigned)
                        {
                            yield return(PackageIssueFactory.PEFileNotAuthenticodeSigned(current));
                        }
                    }
                }
            }
            finally
            {
                CleanUpFolder(extractPath, context.Logger);
            }
        }
Example #21
0
        public IEnumerable <PackageVerifierIssue> Validate(PackageAnalysisContext context)
        {
            if (context.Metadata.Authors == null || !context.Metadata.Authors.Any())
            {
                yield return(PackageIssueFactory.RequiredAuthor());
            }

            if (context.Metadata.Authors.Count() > 1)
            {
                yield return(PackageIssueFactory.SingleAuthorOnly(context.Metadata.Id));
            }

            var author = context.Metadata.Authors.First();

            if (!string.Equals(author, _expectedAuthor, StringComparison.Ordinal))
            {
                yield return(PackageIssueFactory.AuthorIsIncorrect(context.Metadata.Id, _expectedAuthor, author));
            }
        }
        public IEnumerable <PackageVerifierIssue> Validate(PackageAnalysisContext context)
        {
            var dependencyFrameworks = new HashSet <NuGetFramework>(
                context.Metadata.DependencyGroups.Select(g => g.TargetFramework));

            var buildItems = context
                             .PackageReader
                             .GetBuildItems()
                             .Where(f => f.Items.Any(i => IsCandidateMSBuildItem(i, context.Metadata.Id)));

            foreach (var buildItem in buildItems)
            {
                if (!dependencyFrameworks.Contains(buildItem.TargetFramework))
                {
                    yield return(PackageIssueFactory
                                 .BuildItemsDoNotMatchFrameworks(context.Metadata.Id, buildItem.TargetFramework));
                }
            }
        }
Example #23
0
        public IEnumerable <PackageVerifierIssue> Validate(PackageAnalysisContext context)
        {
            if (context.Metadata.PackageTypes.All(p => p != PackageType.DotnetCliTool))
            {
                yield break;
            }

            var libItems = context.PackageReader
                           .GetLibItems()
                           .FirstOrDefault(f => f.TargetFramework.Framework == FrameworkConstants.FrameworkIdentifiers.NetCoreApp);

            if (libItems == null)
            {
                yield return(PackageIssueFactory.DotNetCliToolMustTargetNetCoreApp());

                yield break;
            }

            var assembly = libItems.Items.Where(f =>
                                                Path.GetFileName(f).StartsWith("dotnet-") &&
                                                Path.GetExtension(f) == ".dll");

            if (!assembly.Any())
            {
                yield return(PackageIssueFactory.DotNetCliToolMissingDotnetAssembly());
            }

            foreach (var tool in assembly)
            {
                var expected = Path.GetFileNameWithoutExtension(tool) + ".runtimeconfig.json";
                if (libItems.Items.All(f => Path.GetFileName(f) != expected))
                {
                    yield return(PackageIssueFactory.DotNetCliToolMissingRuntimeConfig());
                }
            }

            if (context.PackageReader.GetFiles().All(f => f != "prefercliruntime"))
            {
                yield return(PackageIssueFactory.DotNetCliToolMissingPrefercliRuntime());
            }
        }
Example #24
0
        public IEnumerable <PackageVerifierIssue> Validate(PackageAnalysisContext context)
        {
            if (context.SignRequest == null)
            {
                context.Logger.Log(LogLevel.Info, "Skipping signing rule request verification for " + context.PackageFileInfo.FullName);
                yield break;
            }

            foreach (var file in context.PackageReader.GetFiles())
            {
                if (!SignRequestItem.IsFileTypeSignable(file))
                {
                    continue;
                }

                if (!context.SignRequest.Children.Any(f => string.Equals(f.Path, file)))
                {
                    yield return(PackageIssueFactory.SignRequestMissingPackageFile(context.Metadata.Id, file));
                }
            }
        }
 public IEnumerable <PackageVerifierIssue> Validate(PackageAnalysisContext context)
 {
     if (string.IsNullOrEmpty(context.Metadata.Copyright))
     {
         yield return(PackageIssueFactory.RequiredCopyright());
     }
     if (context.Metadata.LicenseUrl == null)
     {
         yield return(PackageIssueFactory.RequiredLicenseUrl());
     }
     if (context.Metadata.IconUrl == null)
     {
         yield return(PackageIssueFactory.RequiredIconUrl());
     }
     if (context.Metadata.ProjectUrl == null)
     {
         yield return(PackageIssueFactory.RequiredProjectUrl());
     }
     if (!context.Metadata.RequireLicenseAcceptance)
     {
         yield return(PackageIssueFactory.RequiredRequireLicenseAcceptanceTrue());
     }
 }
Example #26
0
        public IEnumerable <PackageVerifierIssue> Validate(PackageAnalysisContext context)
        {
            if (context.Metadata.Version.IsPrerelease)
            {
                yield break;
            }

            foreach (var dependencyGroup in context.Metadata.DependencyGroups)
            {
                foreach (var packageDependency in dependencyGroup.Packages)
                {
                    var minVersion = packageDependency.VersionRange.MinVersion;
                    if (minVersion != null && minVersion.IsPrerelease)
                    {
                        yield return(PackageIssueFactory.DependencyVersionIsPrereleaseForRTMPackage(
                                         context.Metadata.Id,
                                         context.Metadata.Version,
                                         packageDependency.Id,
                                         packageDependency.VersionRange.MinVersion,
                                         dependencyGroup.TargetFramework));
                    }
                }
            }
        }
        public IEnumerable <PackageVerifierIssue> Validate(PackageAnalysisContext context)
        {
            if (context.Metadata.IsDotNetToolPackage())
            {
                yield break;
            }

            foreach (var currentFile in context.PackageReader.GetFiles())
            {
                var extension = Path.GetExtension(currentFile);
                if (extension.Equals(".dll", StringComparison.OrdinalIgnoreCase) ||
                    extension.Equals(".exe", StringComparison.OrdinalIgnoreCase))
                {
                    string assemblyPath;
                    do
                    {
                        assemblyPath = Path.ChangeExtension(
                            Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()), extension);
                    } while (File.Exists(assemblyPath));

                    var isManagedCode            = false;
                    var isStrongNameSigned       = false;
                    var hasCorrectPublicKeyToken = false;
                    var hresult = 0;

                    try
                    {
                        using (var packageFileStream = context.PackageReader.GetStream(currentFile))
                            using (var fileStream = new FileStream(assemblyPath, FileMode.Create))
                            {
                                packageFileStream.CopyTo(fileStream);
                            }

                        if (AssemblyHelpers.IsAssemblyManaged(assemblyPath))
                        {
                            isManagedCode = true;
                            using (var assembly = AssemblyDefinition.ReadAssembly(assemblyPath))
                            {
                                if (assembly.Modules.Any())
                                {
                                    isStrongNameSigned = assembly.Modules.All(
                                        module => module.Attributes.HasFlag(ModuleAttributes.StrongNameSigned));
                                }
                                else
                                {
                                    throw new InvalidOperationException("The managed assembly does not contain any modules.");
                                }

                                var tokenHexString = BitConverter.ToString(assembly.Name.PublicKeyToken).Replace("-", "");
                                if (_publicKeyToken.Equals(tokenHexString, StringComparison.OrdinalIgnoreCase))
                                {
                                    hasCorrectPublicKeyToken = true;
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        context.Logger.LogError(
                            "Error while verifying strong name signature for {0}: {1}", currentFile, ex.Message);
                    }
                    finally
                    {
                        if (File.Exists(assemblyPath))
                        {
                            File.Delete(assemblyPath);
                        }
                    }

                    if (isManagedCode && !isStrongNameSigned)
                    {
                        yield return(PackageIssueFactory.AssemblyNotStrongNameSigned(currentFile, hresult));
                    }

                    if (isManagedCode && !hasCorrectPublicKeyToken)
                    {
                        yield return(PackageIssueFactory.AssemblyHasWrongPublicKeyToken(currentFile, _publicKeyToken));
                    }
                }
            }
        }
        // TODO: Revert to using Mono.Cecil when https://github.com/jbevain/cecil/issues/306 is fixed.
        public IEnumerable <PackageVerifierIssue> Validate(PackageAnalysisContext context)
        {
            var issues = new List <PackageVerifierIssue>();

            foreach (var currentFile in context.PackageReader.GetFiles())
            {
                var extension = Path.GetExtension(currentFile);
                if (!extension.Equals(".dll", StringComparison.OrdinalIgnoreCase) &&
                    !extension.Equals(".exe", StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }

                using (var packageFileStream = context.PackageReader.GetStream(currentFile))
                    using (var stream = new MemoryStream())
                    {
                        // packageFileStream is not a seekable stream. So wrap it in a memory stream for PEReader to consume.
                        packageFileStream.CopyTo(stream);
                        stream.Position = 0;
                        PEReader       peReader = null;
                        MetadataReader reader;
                        try
                        {
                            peReader = new PEReader(stream);
                            reader   = peReader.GetMetadataReader();
                        }
                        catch
                        {
                            // This assembly is not managed.
                            peReader?.Dispose();
                            continue;
                        }

                        using (peReader)
                        {
                            foreach (var handle in reader.CustomAttributes)
                            {
                                var    customAttribute = reader.GetCustomAttribute(handle);
                                string typeName;
                                if (customAttribute.Constructor.Kind == HandleKind.MemberReference)
                                {
                                    var ctor = reader.GetMemberReference((MemberReferenceHandle)customAttribute.Constructor);
                                    var type = reader.GetTypeReference((TypeReferenceHandle)ctor.Parent);
                                    typeName = reader.GetString(type.Name);
                                }
                                else if (customAttribute.Constructor.Kind == HandleKind.MethodDefinition)
                                {
                                    var method = reader.GetMethodDefinition((MethodDefinitionHandle)customAttribute.Constructor);
                                    var type   = reader.GetTypeDefinition(method.GetDeclaringType());
                                    typeName = reader.GetString(type.Name);
                                }
                                else
                                {
                                    throw new InvalidOperationException($"Unknown CustomAttribute constructor type '{customAttribute.Constructor.Kind}");
                                }

                                if (string.Equals(typeof(DebuggableAttribute).Name, typeName, StringComparison.Ordinal))
                                {
                                    var attribute = customAttribute.DecodeValue(NullProvider.Instance);

                                    var debuggingMode = (DebuggableAttribute.DebuggingModes)attribute.FixedArguments.Single().Value;
                                    if (debuggingMode.HasFlag(DebuggableAttribute.DebuggingModes.Default) ||
                                        debuggingMode.HasFlag(DebuggableAttribute.DebuggingModes.DisableOptimizations))
                                    {
                                        issues.Add(PackageIssueFactory.AssemblyHasIncorrectBuildConfiguration(currentFile));
                                    }
                                    ;

                                    break;
                                }
                            }
                        }
                    }
            }

            return(issues);
        }