Restructure solution layout by module

This commit is contained in:
master
2025-10-28 15:10:40 +02:00
parent 95daa159c4
commit d870da18ce
4103 changed files with 192899 additions and 187024 deletions

View File

@@ -0,0 +1,106 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using StellaOps.Scanner.Analyzers.OS;
using StellaOps.Scanner.Analyzers.OS.Abstractions;
using StellaOps.Scanner.Analyzers.OS.Analyzers;
using StellaOps.Scanner.Analyzers.OS.Helpers;
namespace StellaOps.Scanner.Analyzers.OS.Apk;
internal sealed class ApkPackageAnalyzer : OsPackageAnalyzerBase
{
private static readonly IReadOnlyList<OSPackageRecord> EmptyPackages =
new ReadOnlyCollection<OSPackageRecord>(System.Array.Empty<OSPackageRecord>());
private readonly ApkDatabaseParser _parser = new();
public ApkPackageAnalyzer(ILogger<ApkPackageAnalyzer> logger)
: base(logger)
{
}
public override string AnalyzerId => "apk";
protected override ValueTask<IReadOnlyList<OSPackageRecord>> ExecuteCoreAsync(OSPackageAnalyzerContext context, CancellationToken cancellationToken)
{
var installedPath = Path.Combine(context.RootPath, "lib", "apk", "db", "installed");
if (!File.Exists(installedPath))
{
Logger.LogInformation("Apk installed database not found at {Path}; skipping analyzer.", installedPath);
return ValueTask.FromResult<IReadOnlyList<OSPackageRecord>>(EmptyPackages);
}
using var stream = File.OpenRead(installedPath);
var entries = _parser.Parse(stream, cancellationToken);
var records = new List<OSPackageRecord>(entries.Count);
foreach (var entry in entries)
{
if (string.IsNullOrWhiteSpace(entry.Name) ||
string.IsNullOrWhiteSpace(entry.Version) ||
string.IsNullOrWhiteSpace(entry.Architecture))
{
continue;
}
var versionParts = PackageVersionParser.ParseApkVersion(entry.Version);
var purl = PackageUrlBuilder.BuildAlpine(entry.Name, entry.Version, entry.Architecture);
var vendorMetadata = new Dictionary<string, string?>(StringComparer.Ordinal)
{
["origin"] = entry.Origin,
["description"] = entry.Description,
["homepage"] = entry.Url,
["maintainer"] = entry.Maintainer,
["checksum"] = entry.Checksum,
["buildTime"] = entry.BuildTime,
};
foreach (var pair in entry.Metadata)
{
vendorMetadata[$"apk:{pair.Key}"] = pair.Value;
}
var files = new List<OSPackageFileEvidence>(entry.Files.Count);
foreach (var file in entry.Files)
{
files.Add(new OSPackageFileEvidence(
file.Path,
layerDigest: null,
sha256: file.Digest,
sizeBytes: null,
isConfigFile: file.IsConfig));
}
var cveHints = CveHintExtractor.Extract(
string.Join(' ', entry.Depends),
string.Join(' ', entry.Provides));
var record = new OSPackageRecord(
AnalyzerId,
purl,
entry.Name,
versionParts.BaseVersion,
entry.Architecture,
PackageEvidenceSource.ApkDatabase,
epoch: null,
release: versionParts.Release,
sourcePackage: entry.Origin,
license: entry.License,
cveHints: cveHints,
provides: entry.Provides,
depends: entry.Depends,
files: files,
vendorMetadata: vendorMetadata);
records.Add(record);
}
records.Sort();
return ValueTask.FromResult<IReadOnlyList<OSPackageRecord>>(records);
}
}