Skip to content

Commit

Permalink
Copy trust store to /tmp to work with readonly fs
Browse files Browse the repository at this point in the history
Co-authored-by: Sumit Kulhadia <sumit.kulhadia@sap.com>
  • Loading branch information
c0d1ngm0nk3y and kulhadia committed May 11, 2023
1 parent 2ddb2d9 commit e6fb742
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 5 deletions.
46 changes: 43 additions & 3 deletions helper/openssl_certificate_loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,28 +19,68 @@ package helper
import (
"fmt"
"os"
"path/filepath"

"github.com/paketo-buildpacks/libpak/bard"
"github.com/paketo-buildpacks/libpak/sherpa"
"golang.org/x/sys/unix"

"github.com/paketo-buildpacks/libjvm"
)

var TmpTrustStore = filepath.Join(os.TempDir(), "truststore")

type OpenSSLCertificateLoader struct {
CertificateLoader libjvm.CertificateLoader
Logger bard.Logger
}

func (o OpenSSLCertificateLoader) prepareTempTrustStore(trustStore, tempTrustStore string) (map[string]string, error) {
o.Logger.Infof("Using readonly truststore: %s", tempTrustStore)

trustStoreFile, err := os.Open(trustStore)
if err != nil {
return nil, fmt.Errorf("unable to open trust store %s\n%w", trustStore, err)
}
defer trustStoreFile.Close()

err = sherpa.CopyFile(trustStoreFile, tempTrustStore)
if err != nil {
return nil, fmt.Errorf("unable to copy dir (%s, %s)\n%w", trustStore, tempTrustStore, err)
}

opts := sherpa.AppendToEnvVar("JAVA_TOOL_OPTIONS", " ", fmt.Sprintf("-Djavax.net.ssl.trustStore=%s", tempTrustStore))
o.Logger.Debugf("changed JAVA_TOOL_OPTIONS: '%s'", opts)

return map[string]string{"JAVA_TOOL_OPTIONS": opts}, nil
}

func (o OpenSSLCertificateLoader) Execute() (map[string]string, error) {
k, ok := os.LookupEnv("BPI_JVM_CACERTS")
trustStore, ok := os.LookupEnv("BPI_JVM_CACERTS")
if !ok {
return nil, fmt.Errorf("$BPI_JVM_CACERTS must be set")
}

trustStoreWriteable := true
if unix.Access(trustStore, unix.W_OK) != nil {
trustStoreWriteable = false
}

var opts map[string]string
if !trustStoreWriteable {
tmpOpts, err := o.prepareTempTrustStore(trustStore, TmpTrustStore)
if err == nil {
trustStore = TmpTrustStore
opts = tmpOpts
}
}

o.CertificateLoader.Logger = o.Logger.InfoWriter()

if err := o.CertificateLoader.Load(k, "changeit"); err != nil {
if err := o.CertificateLoader.Load(trustStore, "changeit"); err != nil {
return nil, fmt.Errorf("unable to load certificates\n%w", err)
}

return nil, nil
return opts, nil

}
32 changes: 30 additions & 2 deletions helper/openssl_certificate_loader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package helper_test

import (
"fmt"
"io"
"io/ioutil"
"os"
Expand Down Expand Up @@ -79,6 +80,7 @@ func testOpenSSLCertificateLoader(t *testing.T, context spec.G, it spec.S) {

it.After(func() {
Expect(os.Unsetenv("BPI_JVM_CACERTS")).To(Succeed())
_ = os.Remove(helper.TmpTrustStore)
})

it("loads additional certificates", func() {
Expand All @@ -100,12 +102,37 @@ func testOpenSSLCertificateLoader(t *testing.T, context spec.G, it spec.S) {
return
}

it("does not return error when keystore is read-only", func() {
it("does use temp keystore if keystore is read-only", func() {
Expect(os.Chmod(path, 0555)).To(Succeed())

o := helper.OpenSSLCertificateLoader{CertificateLoader: cl, Logger: bard.NewLogger(ioutil.Discard)}

Expect(o.Execute()).To(BeNil())
env, err := o.Execute()
Expect(err).NotTo(HaveOccurred())

in, err := os.Open(helper.TmpTrustStore)
Expect(err).NotTo(HaveOccurred())
defer in.Close()

ks := keystore.New()
err = ks.Load(in, []byte("changeit"))
Expect(err).NotTo(HaveOccurred())
Expect(ks.Aliases()).To(HaveLen(1))

Expect(env).To(HaveKeyWithValue("JAVA_TOOL_OPTIONS", fmt.Sprintf("-Djavax.net.ssl.trustStore=%s", helper.TmpTrustStore)))
})

it("does not return error when keystore and /tmp/truststore are read-only", func() {
Expect(os.Chmod(path, 0555)).To(Succeed())
_, err := os.OpenFile(helper.TmpTrustStore, os.O_CREATE, 0)
Expect(err).NotTo(HaveOccurred())
Expect(os.Chmod(helper.TmpTrustStore, 0555)).To(Succeed())

o := helper.OpenSSLCertificateLoader{CertificateLoader: cl, Logger: bard.NewLogger(os.Stdout)}

env, err := o.Execute()
Expect(env).To(BeNil())
Expect(err).NotTo(HaveOccurred())

in, err := os.Open(path)
Expect(err).NotTo(HaveOccurred())
Expand All @@ -116,6 +143,7 @@ func testOpenSSLCertificateLoader(t *testing.T, context spec.G, it spec.S) {
Expect(err).NotTo(HaveOccurred())
Expect(ks.Aliases()).To(HaveLen(1))
})

})

}

0 comments on commit e6fb742

Please sign in to comment.