From 5c1ae6021447cc8236a8dbd345098dc7260d388a Mon Sep 17 00:00:00 2001 From: Brent Date: Fri, 16 Jan 2026 21:56:27 -0500 Subject: [PATCH 1/2] Added SUSE/OpenSUSE support. --- README.md | 1 + src/linux-dev-certs/CertificateManager.cs | 8 ++++++++ src/linux-dev-certs/NssCertificateDatabase.cs | 4 ++++ src/linux-dev-certs/OSFlavor.cs | 1 + src/linux-dev-certs/SystemCertificateStore.cs | 18 +++++++++++++++++- 5 files changed, 31 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 95c8c4d..73fe71b 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ If you get an error saying _Could not execute because the specified command or f - Arch Linux - Gentoo - Slackware +- OpenSUSE Leap and SUSE Linux Enterprise Server (SLES). Tumbleweed and SLED untested but expected to work. Limitations: diff --git a/src/linux-dev-certs/CertificateManager.cs b/src/linux-dev-certs/CertificateManager.cs index 0416b22..acca031 100644 --- a/src/linux-dev-certs/CertificateManager.cs +++ b/src/linux-dev-certs/CertificateManager.cs @@ -142,6 +142,10 @@ private bool CheckDependencies(HashSet dependencies, bool installMis { command = ["slackpkg", "install", ..packagesToInstall]; } + else if (OSFlavor.IsSUSELike) + { + command = ["zypper", "install", ..packagesToInstall]; + } else { command = []; @@ -180,6 +184,10 @@ private bool CheckDependencies(HashSet dependencies, bool installMis { Console.Error.WriteLine($" slackpkg install {string.Join(", ", packagesToInstall)}"); } + else if (OSFlavor.IsSUSELike) + { + Console.Error.WriteLine($" zypper install {string.Join(", ", packagesToInstall)}"); + } else { Console.ForegroundColor = color; diff --git a/src/linux-dev-certs/NssCertificateDatabase.cs b/src/linux-dev-certs/NssCertificateDatabase.cs index 9ac5830..4184d3c 100644 --- a/src/linux-dev-certs/NssCertificateDatabase.cs +++ b/src/linux-dev-certs/NssCertificateDatabase.cs @@ -69,6 +69,10 @@ private string GetPackageForCertUtils() { return "mozilla-nss"; } + else if(OSFlavor.IsSUSELike) + { + return "mozilla-nss-tools"; + } else { OSFlavor.ThrowNotSupported(); diff --git a/src/linux-dev-certs/OSFlavor.cs b/src/linux-dev-certs/OSFlavor.cs index dd8c706..4ba9ba0 100644 --- a/src/linux-dev-certs/OSFlavor.cs +++ b/src/linux-dev-certs/OSFlavor.cs @@ -8,6 +8,7 @@ static class OSFlavor public static bool IsArchLike => MatchesId("arch"); public static bool IsGentooLike => MatchesId("gentoo"); public static bool IsSlackLike => MatchesId("slackware"); + public static bool IsSUSELike => MatchesId("suse"); private static string? _id; private static string[]? _idLike; diff --git a/src/linux-dev-certs/SystemCertificateStore.cs b/src/linux-dev-certs/SystemCertificateStore.cs index d5e6e34..35471a4 100644 --- a/src/linux-dev-certs/SystemCertificateStore.cs +++ b/src/linux-dev-certs/SystemCertificateStore.cs @@ -10,6 +10,7 @@ sealed class SystemCertificateStore : ICertificateStore private const string DebianFamilyCaSourceDirectory = "/usr/local/share/ca-certificates"; private const string ArchFamilyCaSourceDirectory = "/etc/ca-certificates/trust-source/anchors/"; private const string SlackFamilyCaSourceDirectory = "/usr/share/ca-certificates/mozilla/"; + private const string SUSEFamilyCaSourceDirectory = "/usr/share/pki/trust/anchors/"; public string Name => "System Certificates"; public bool TryInstallCertificate(string name, X509Certificate2 certificate) @@ -40,6 +41,17 @@ public bool TryInstallCertificate(string name, X509Certificate2 certificate) certFilePath = $"{SlackFamilyCaSourceDirectory}/{name}.crt"; trustCommand = ["update-ca-certificates"]; } + else if (OSFlavor.IsSUSELike) + { + certFilePath = $"{SUSEFamilyCaSourceDirectory}/{name}.crt"; + + // Absolute since OpenSUSE/SLES do not include /usr/sbin in default PATH even for wheel users + trustCommand = ["/usr/sbin/update-ca-certificates"]; + + // OpenSUSE and SLES both also provide /usr/bin/trust in the base installation, but + // running this would miss any customization in /{etc,usr/lib}/ca-certificates/update.d + // trustCommand = ["trust", "extract-compat"]; + } else { OSFlavor.ThrowNotSupported(); @@ -64,6 +76,10 @@ public void AddDependencies(HashSet dependencies) { dependencies.Add(new Dependency("update-ca-certificates", "ca-certificates")); } + else if (OSFlavor.IsSUSELike) + { + dependencies.Add(new Dependency("/usr/sbin/update-ca-certificates", "ca-certificates")); + } else if (OSFlavor.IsArchLike) { dependencies.Add(new Dependency("trust", "p11-kit")); @@ -75,5 +91,5 @@ public void AddDependencies(HashSet dependencies) } public bool IsSupported - => OSFlavor.IsFedoraLike || OSFlavor.IsDebianLike || OSFlavor.IsArchLike || OSFlavor.IsSlackLike; + => OSFlavor.IsFedoraLike || OSFlavor.IsDebianLike || OSFlavor.IsArchLike || OSFlavor.IsSlackLike || OSFlavor.IsSUSELike; } \ No newline at end of file From 572cacd71b5d4276322b83a70718ee74ce226e3d Mon Sep 17 00:00:00 2001 From: Tom Deseyn Date: Mon, 19 Jan 2026 16:00:25 +0100 Subject: [PATCH 2/2] Apply suggestions from code review --- README.md | 2 +- src/linux-dev-certs/SystemCertificateStore.cs | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/README.md b/README.md index 73fe71b..e06266b 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ If you get an error saying _Could not execute because the specified command or f - Arch Linux - Gentoo - Slackware -- OpenSUSE Leap and SUSE Linux Enterprise Server (SLES). Tumbleweed and SLED untested but expected to work. +- SUSE Linux Enterprise Server (SLES) and derived (OpenSUSE Leap, SLED, ...) Limitations: diff --git a/src/linux-dev-certs/SystemCertificateStore.cs b/src/linux-dev-certs/SystemCertificateStore.cs index 35471a4..ff3c01c 100644 --- a/src/linux-dev-certs/SystemCertificateStore.cs +++ b/src/linux-dev-certs/SystemCertificateStore.cs @@ -44,13 +44,7 @@ public bool TryInstallCertificate(string name, X509Certificate2 certificate) else if (OSFlavor.IsSUSELike) { certFilePath = $"{SUSEFamilyCaSourceDirectory}/{name}.crt"; - - // Absolute since OpenSUSE/SLES do not include /usr/sbin in default PATH even for wheel users trustCommand = ["/usr/sbin/update-ca-certificates"]; - - // OpenSUSE and SLES both also provide /usr/bin/trust in the base installation, but - // running this would miss any customization in /{etc,usr/lib}/ca-certificates/update.d - // trustCommand = ["trust", "extract-compat"]; } else {