Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BP_OPENSSL_ACTIVATE_LEGACY_PROVIDER: load legacy ssl provider via env var #921

Merged
merged 1 commit into from
Feb 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions fixtures/source_apps/simple_legacy_openssl/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
This app was generated with the .NET Core CLI v6:
```
dotnet new mvc -o source_6.0
```
This app is used to test the functionality to load the legacy openssl provider
when using cflinuxfs4

The app is tested with the addition of the `BP_OPENSSL_ACTIVATE_LEGACY_PROVIDER` environment
variable set to `true`

See ssl-related integration test in `src/dotnetcore/integration/default_test.go`
3 changes: 0 additions & 3 deletions fixtures/source_apps/simple_legacy_openssl/buildpack.yml

This file was deleted.

3 changes: 2 additions & 1 deletion src/dotnetcore/integration/default_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,11 +213,12 @@ func testDefault(t *testing.T, context spec.G, it spec.S) {
})
})

context("with use_legacy_openssl specified in buildpack.yml", func() {
context("with BP_USE_LEGACY_OPENSSL set to `true`", func() {
it.Before(func() {
// this feature is not available on cflinuxfs3, because the stack already supports the legacy ssl provider
SkipOnCflinuxfs3(t)
app = cutlass.New(filepath.Join(settings.FixturesPath, "source_apps", "simple_legacy_openssl"))
app.SetEnv("BP_OPENSSL_ACTIVATE_LEGACY_PROVIDER", "true")
})

it("activates openssl legacy provider and builds/runs successfully", func() {
Expand Down
25 changes: 12 additions & 13 deletions src/dotnetcore/supply/supply.go
Original file line number Diff line number Diff line change
Expand Up @@ -401,18 +401,26 @@ func (s *Supplier) InstallDotnetSdk() error {
return s.installRuntimeIfNeeded()
}

// Users can load the legacy SSL provider via:
// - the BP_OPENSSL_ACTIVATE_LEGACY_PROVIDER=true environment variable
// - provide an openssl.cnf file in the application directory
func (s *Supplier) LoadLegacySSLProvider() error {
loadLegacySSLProvider, err := s.parseBuildpackYamlOpenssl()
if err != nil {
return err
var loadLegacySSLProvider bool
var err error

if legacySSLEnvVar, ok := os.LookupEnv("BP_OPENSSL_ACTIVATE_LEGACY_PROVIDER"); ok {
loadLegacySSLProvider, err = strconv.ParseBool(legacySSLEnvVar)
if err != nil {
return err
}
}

if loadLegacySSLProvider {
if os.Getenv("CF_STACK") == "cflinuxfs3" {
s.Log.Warning("Legacy SSL support requested, this feature is not available on cflinuxfs3")
return nil
}
// If a user sets the buidpack.yml to include legacy provider AND
// If a user requests the legacy provider AND
// includes their own openssl.cnf, just use the provided openssl.cnf
opensslCnfFile := filepath.Join(s.Stager.BuildDir(), "openssl.cnf")
exists, err := libbuildpack.FileExists(opensslCnfFile)
Expand Down Expand Up @@ -527,7 +535,6 @@ type buildpackYaml struct {
DotnetCore struct {
Version string `yaml:"sdk"`
} `yaml:"dotnet-core"`
UseLegacyOpenssl bool `yaml:"use_legacy_openssl"`
}

func (s *Supplier) parseBuildpackYamlVersion() (string, error) {
Expand All @@ -538,14 +545,6 @@ func (s *Supplier) parseBuildpackYamlVersion() (string, error) {
return content.DotnetCore.Version, nil
}

func (s *Supplier) parseBuildpackYamlOpenssl() (bool, error) {
content, err := s.parseBuildpackYamlFile()
if err != nil {
return false, err
}
return content.UseLegacyOpenssl, nil
}

func (s *Supplier) parseBuildpackYamlFile() (buildpackYaml, error) {
obj := buildpackYaml{}
if found, err := libbuildpack.FileExists(filepath.Join(s.Stager.BuildDir(), "buildpack.yml")); err != nil || !found {
Expand Down
62 changes: 18 additions & 44 deletions src/dotnetcore/supply/supply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,89 +217,63 @@ var _ = Describe("Supply", func() {
})

Describe("LoadLegacySSLProvider", func() {
Context("with buildpack.yml", func() {
Context("contains use_legacy_openssl: true", func() {
Context("BP_OPENSSL_ACTIVATE_LEGACY_PROVIDER is set", func() {
Context("set to true", func() {
BeforeEach(func() {
Expect(os.WriteFile(filepath.Join(buildDir, "buildpack.yml"), []byte("dotnet-core:\n sdk: 6.7.8\nuse_legacy_openssl: true\n"), 0644)).To(Succeed())
Expect(os.Setenv("BP_OPENSSL_ACTIVATE_LEGACY_PROVIDER", "true")).To(Succeed())
})
AfterEach(func() {
Expect(os.Remove(filepath.Join(buildDir, "buildpack.yml"))).To(Succeed())
Expect(os.Unsetenv("BP_OPENSSL_ACTIVATE_LEGACY_PROVIDER")).To(Succeed())
})
It("Loads legacy SSL provider", func() {
Expect(supplier.LoadLegacySSLProvider()).To(Succeed())
Expect(filepath.Join(buildDir, "openssl.cnf")).To(BeARegularFile())
Expect(buffer.String()).To(ContainSubstring("Loading legacy SSL provider"))
})
})
Context("contains use_legacy_openssl: false", func() {
BeforeEach(func() {
Expect(os.WriteFile(filepath.Join(buildDir, "buildpack.yml"), []byte("dotnet-core:\n sdk: 6.7.8\nuse_legacy_openssl: false\n"), 0644)).To(Succeed())
})
AfterEach(func() {
Expect(os.Remove(filepath.Join(buildDir, "buildpack.yml"))).To(Succeed())
})
It("does not load legacy SSL provider", func() {
Expect(supplier.LoadLegacySSLProvider()).To(Succeed())
Expect(filepath.Join(buildDir, "openssl.cnf")).NotTo(BeARegularFile())
})
})

Context("does not contain use_legacy_openssl at all", func() {
Context("set to false", func() {
BeforeEach(func() {
Expect(os.WriteFile(filepath.Join(buildDir, "buildpack.yml"), []byte("dotnet-core:\n sdk: 6.7.8\n"), 0644)).To(Succeed())
Expect(os.Setenv("BP_OPENSSL_ACTIVATE_LEGACY_PROVIDER", "false")).To(Succeed())
})
AfterEach(func() {
Expect(os.Remove(filepath.Join(buildDir, "buildpack.yml"))).To(Succeed())
Expect(os.Unsetenv("BP_OPENSSL_ACTIVATE_LEGACY_PROVIDER")).To(Succeed())
})
It("does not load legacy SSL provider", func() {
Expect(supplier.LoadLegacySSLProvider()).To(Succeed())
Expect(filepath.Join(buildDir, "openssl.cnf")).NotTo(BeARegularFile())
Expect(buffer.String()).NotTo(ContainSubstring("Loading legacy SSL provider"))
})
})

Context("openssl.cnf file already exists in app", func() {
Context("both environment variable and openssl.cnf are present", func() {
BeforeEach(func() {
Expect(os.WriteFile(filepath.Join(buildDir, "buildpack.yml"), []byte("dotnet-core:\n sdk: 6.7.8\nuse_legacy_openssl: true\n"), 0644)).To(Succeed())
Expect(os.WriteFile(filepath.Join(buildDir, "openssl.cnf"), []byte("some-data"), 0644)).To(Succeed())
Expect(os.Setenv("BP_OPENSSL_ACTIVATE_LEGACY_PROVIDER", "true")).To(Succeed())
Expect(os.WriteFile(filepath.Join(buildDir, "openssl.cnf"), []byte(""), 0644)).To(Succeed())
})
AfterEach(func() {
Expect(os.Remove(filepath.Join(buildDir, "buildpack.yml"))).To(Succeed())
Expect(os.Unsetenv("BP_OPENSSL_ACTIVATE_LEGACY_PROVIDER")).To(Succeed())
Expect(os.Remove(filepath.Join(buildDir, "openssl.cnf"))).To(Succeed())
})
It("uses the openssl.cnf file that already exists", func() {
It("the openssl.cnf file takes precedence", func() {
Expect(supplier.LoadLegacySSLProvider()).To(Succeed())
Expect(filepath.Join(buildDir, "openssl.cnf")).To(BeARegularFile())
Expect(buffer.String()).To(ContainSubstring("Loading legacy SSL provider"))
Expect(buffer.String()).To(ContainSubstring("Application already contains openssl.cnf file"))
})
})
Context("on cflinuxfs3", func() {
Context("contains use_legacy_openssl: true", func() {
BeforeEach(func() {
Expect(os.WriteFile(filepath.Join(buildDir, "buildpack.yml"), []byte("dotnet-core:\n sdk: 6.7.8\nuse_legacy_openssl: true\n"), 0644)).To(Succeed())
Expect(os.Setenv("CF_STACK", "cflinuxfs3")).To(Succeed())
})
AfterEach(func() {
Expect(os.Remove(filepath.Join(buildDir, "buildpack.yml"))).To(Succeed())
Expect(os.Unsetenv("CF_STACK")).To(Succeed())
})
It("doesn not load legacy SSL provider", func() {
Expect(supplier.LoadLegacySSLProvider()).To(Succeed())
Expect(buffer.String()).To(ContainSubstring("Legacy SSL support requested, this feature is not available on cflinuxfs3"))
})
})
})
})

Context("error cases", func() {
Context("cannot parse buildpack.yaml", func() {
Context("cannot parse the BP_OPENSSL_ACTIVATE_LEGACY_PROVIDER boolean", func() {
BeforeEach(func() {
Expect(os.WriteFile(filepath.Join(buildDir, "buildpack.yml"), []byte("bad yaml"), 0644)).To(Succeed())
Expect(os.Setenv("BP_OPENSSL_ACTIVATE_LEGACY_PROVIDER", "bad boolean")).To(Succeed())
})
AfterEach(func() {
Expect(os.Remove(filepath.Join(buildDir, "buildpack.yml"))).To(Succeed())
Expect(os.Unsetenv("BP_OPENSSL_ACTIVATE_LEGACY_PROVIDER")).To(Succeed())
})
It("returns an error", func() {
Expect(supplier.LoadLegacySSLProvider()).To(MatchError(ContainSubstring("cannot unmarshal")))
Expect(supplier.LoadLegacySSLProvider()).To(MatchError(ContainSubstring(`parsing "bad boolean": invalid syntax`)))
Expect(filepath.Join(buildDir, "openssl.cnf")).NotTo(BeARegularFile())
})
})
Expand Down
Loading