diff --git a/pkg/rhsm/secrets.go b/pkg/rhsm/secrets.go index 5542618c1f..fa8730ce09 100644 --- a/pkg/rhsm/secrets.go +++ b/pkg/rhsm/secrets.go @@ -42,6 +42,25 @@ type ConsumerSecrets struct { ConsumerCert string } +// defaultCACert picks the CA certificate to use when a repo does not set +// sslcacert explicitly. On Satellite-registered hosts content is served through +// the Satellite content proxy whose TLS certificate is signed by the Katello CA; +// the default redhat-uep.pem only holds the Red Hat CDN CA and cannot validate +// it. When katello-server-ca.pem is present (installed by Satellite +// registration) it contains the CA chain needed for the content proxy, so prefer +// it; otherwise fall back to redhat-uep.pem. A repo's explicit sslcacert still +// takes precedence over this default (see GetSecretsForBaseurl). +// katelloCACert is a variable so tests can point it at a temp file; production +// code never reassigns it. +var katelloCACert = "/etc/rhsm/ca/katello-server-ca.pem" + +func defaultCACert() string { + if _, err := os.Stat(katelloCACert); err == nil { + return katelloCACert + } + return "/etc/rhsm/ca/redhat-uep.pem" +} + func getRHSMSecrets() (*RHSMSecrets, error) { // search /etc first to allow container users to override the entitlements globs := []string{ @@ -58,7 +77,7 @@ func getRHSMSecrets() (*RHSMSecrets, error) { cert := strings.TrimSuffix(key, "-key.pem") + ".pem" if _, err := os.Stat(cert); err == nil { return &RHSMSecrets{ - SSLCACert: "/etc/rhsm/ca/redhat-uep.pem", + SSLCACert: defaultCACert(), SSLClientKey: key, SSLClientCert: cert, }, nil diff --git a/pkg/rhsm/secrets_test.go b/pkg/rhsm/secrets_test.go index 3be7f7a345..3f6ca0b3d8 100644 --- a/pkg/rhsm/secrets_test.go +++ b/pkg/rhsm/secrets_test.go @@ -1,6 +1,8 @@ package rhsm import ( + "os" + "path/filepath" "testing" "github.com/stretchr/testify/assert" @@ -132,6 +134,23 @@ func TestGetSecretsForBaseurlFallback(t *testing.T) { assert.Equal(t, "/etc/pki/entitlement/fallback-key.pem", secrets.SSLClientKey) } +// defaultCACert prefers the Katello CA when it exists (Satellite-registered +// host) and otherwise falls back to redhat-uep.pem. +func TestDefaultCACert(t *testing.T) { + orig := katelloCACert + t.Cleanup(func() { katelloCACert = orig }) + + // Katello CA absent: fall back to the Red Hat CDN CA. + katelloCACert = filepath.Join(t.TempDir(), "does-not-exist.pem") + assert.Equal(t, "/etc/rhsm/ca/redhat-uep.pem", defaultCACert()) + + // Katello CA present: prefer it. + present := filepath.Join(t.TempDir(), "katello-server-ca.pem") + require.NoError(t, os.WriteFile(present, []byte("ca"), 0600)) + katelloCACert = present + assert.Equal(t, present, defaultCACert()) +} + // mirrors the cases in osbuild's test_util_rhsm.py::TestUrlMatching. func TestBaseurlToRegex(t *testing.T) { for _, tc := range []struct {