From fe0b2ea0da9c4c58dad69710a2eca08215398aa5 Mon Sep 17 00:00:00 2001 From: Tyler Creller Date: Tue, 27 Feb 2024 14:08:02 -0500 Subject: [PATCH] Migrate keychain to use non-CGO libraries --- .github/workflows/check-pull-request.yaml | 14 +- authentication/handler_test.go | 3 + authentication/securestore/keychain_test.go | 71 ++++++++++ authentication/securestore/main.go | 101 +++++++++++--- authentication/securestore/pass_test.go | 131 ++++++++++++++++++ authentication/securestore/wincred_test.go | 71 ++++++++++ authentication/testdata/test-gpg.key | 82 +++++++++++ .../testdata/test-ownertrust-gpg.txt | 3 + authentication/transport_wrapper_test.go | 3 + configuration/main_test.go | 3 + examples/go.mod | 3 + examples/go.sum | 6 + go.mod | 4 + go.sum | 6 + h2c_test.go | 3 + unix_sockets_test.go | 3 + 16 files changed, 487 insertions(+), 20 deletions(-) create mode 100644 authentication/securestore/keychain_test.go create mode 100644 authentication/securestore/pass_test.go create mode 100644 authentication/securestore/wincred_test.go create mode 100644 authentication/testdata/test-gpg.key create mode 100644 authentication/testdata/test-ownertrust-gpg.txt diff --git a/.github/workflows/check-pull-request.yaml b/.github/workflows/check-pull-request.yaml index 3c6f5b88..4bcc410d 100644 --- a/.github/workflows/check-pull-request.yaml +++ b/.github/workflows/check-pull-request.yaml @@ -25,15 +25,27 @@ jobs: test: name: Test - runs-on: ubuntu-latest strategy: matrix: go: - "1.21" + platform: + - ubuntu-latest + - macos-latest + - windows-latest + runs-on: ${{ matrix.platform }} steps: - name: Checkout the source uses: actions/checkout@v2 + - name: Install Keyrings (macOS-only) + if: ${{ contains(fromJSON('["macos-latest"]'), matrix.platform) }} + run: brew install pass gnupg + + - name: Install Keyrings (linux) + if: ${{ contains(fromJSON('["ubuntu-latest"]'), matrix.platform) }} + run: sudo apt-get install pass + - name: Setup Go uses: actions/setup-go@v2 with: diff --git a/authentication/handler_test.go b/authentication/handler_test.go index bf46e2e6..f3bd5e93 100644 --- a/authentication/handler_test.go +++ b/authentication/handler_test.go @@ -1,3 +1,6 @@ +//go:build linux +// +build linux + /* Copyright (c) 2019 Red Hat, Inc. diff --git a/authentication/securestore/keychain_test.go b/authentication/securestore/keychain_test.go new file mode 100644 index 00000000..35dc9907 --- /dev/null +++ b/authentication/securestore/keychain_test.go @@ -0,0 +1,71 @@ +//go:build darwin +// +build darwin + +/* +Copyright (c) 2024 Red Hat, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package securestore + +import ( + "time" + + . "github.com/onsi/ginkgo/v2" // nolint + . "github.com/onsi/gomega" // nolint + + . "github.com/openshift-online/ocm-sdk-go/testing" // nolint +) + +var _ = Describe("Keychain", func() { + const backend = "keychain" + + BeforeEach(func() { + err := RemoveConfigFromKeyring(backend) + Expect(err).To(BeNil()) + }) + + When("Listing Keyrings", func() { + It("Lists keychain as a valid keyring", func() { + backends := AvailableBackends() + Expect(backends).To(ContainElement(backend)) + }) + }) + + When("Using Keychain", func() { + It("Stores/Removes via Keychain", func() { + // Create the token + accessToken := MakeTokenString("Bearer", 15*time.Minute) + + // Run insert + err := UpsertConfigToKeyring(backend, []byte(accessToken)) + + Expect(err).To(BeNil()) + + // Check the content of the keyring + result, err := GetConfigFromKeyring(backend) + Expect(result).To(Equal([]byte(accessToken))) + Expect(err).To(BeNil()) + + // Remove the configuration from the keyring + err = RemoveConfigFromKeyring(backend) + Expect(err).To(BeNil()) + + // Ensure the keyring is empty + result, err = GetConfigFromKeyring(backend) + Expect(result).To(Equal([]byte(""))) + Expect(err).To(BeNil()) + }) + }) +}) diff --git a/authentication/securestore/main.go b/authentication/securestore/main.go index 4c2943b8..73b51c37 100644 --- a/authentication/securestore/main.go +++ b/authentication/securestore/main.go @@ -3,11 +3,14 @@ package securestore import ( "bytes" "compress/gzip" + "errors" "fmt" "io" + "runtime" "strings" "github.com/99designs/keyring" + gokeyring "github.com/zalando/go-keyring" ) const ( @@ -46,8 +49,6 @@ func getKeyringConfig(backend string) keyring.Config { } // IsBackendAvailable provides validation that the desired backend is available on the current OS. -// -// Note: CGO_ENABLED=1 is required for darwin builds (enables OSX Keychain) func IsBackendAvailable(backend string) (isAvailable bool) { if backend == "" { return false @@ -64,11 +65,14 @@ func IsBackendAvailable(backend string) (isAvailable bool) { } // AvailableBackends provides a slice of all available backend keys on the current OS. -// -// Note: CGO_ENABLED=1 is required for darwin builds (enables OSX Keychain) func AvailableBackends() []string { b := []string{} + if isDarwin() { + // Assume Keychain is always available on Darwin. It will not return from keyring.AvailableBackends() + b = append(b, "keychain") + } + // Intersection between available backends from OS and allowed backends for _, avail := range keyring.AvailableBackends() { for _, allowed := range AllowedBackends { @@ -82,13 +86,15 @@ func AvailableBackends() []string { } // UpsertConfigToKeyring will upsert the provided credentials to the desired OS secure store. -// -// Note: CGO_ENABLED=1 is required for darwin builds (enables OSX Keychain) func UpsertConfigToKeyring(backend string, creds []byte) error { if err := ValidateBackend(backend); err != nil { return err } + if isDarwin() && isKeychain(backend) { + return keychainUpsert(creds) + } + ring, err := keyring.Open(getKeyringConfig(backend)) if err != nil { return err @@ -116,13 +122,15 @@ func UpsertConfigToKeyring(backend string, creds []byte) error { } // RemoveConfigFromKeyring will remove the credentials from the first priority OS secure store. -// -// Note: CGO_ENABLED=1 is required for OSX Keychain and darwin builds func RemoveConfigFromKeyring(backend string) error { if err := ValidateBackend(backend); err != nil { return err } + if isDarwin() && isKeychain(backend) { + return keychainRemove() + } + ring, err := keyring.Open(getKeyringConfig(backend)) if err != nil { return err @@ -130,27 +138,25 @@ func RemoveConfigFromKeyring(backend string) error { err = ring.Remove(ItemKey) if err != nil { - if err == keyring.ErrKeyNotFound { + if errors.Is(err, keyring.ErrKeyNotFound) { // Ignore not found errors, key is already removed return nil } - - if strings.Contains(err.Error(), "Keychain Error. (-25244)") { - return fmt.Errorf("%s\nThis application may not have permission to delete from the Keychain. Please check the permissions in the Keychain and try again", err.Error()) - } } return err } // GetConfigFromKeyring will retrieve the credentials from the first priority OS secure store. -// -// Note: CGO_ENABLED=1 is required for darwin builds (enables OSX Keychain) func GetConfigFromKeyring(backend string) ([]byte, error) { if err := ValidateBackend(backend); err != nil { return nil, err } + if isDarwin() && isKeychain(backend) { + return keychainGet() + } + credentials := []byte("") ring, err := keyring.Open(getKeyringConfig(backend)) @@ -159,9 +165,9 @@ func GetConfigFromKeyring(backend string) ([]byte, error) { } i, err := ring.Get(ItemKey) - if err != nil && err != keyring.ErrKeyNotFound { + if err != nil && !errors.Is(err, keyring.ErrKeyNotFound) { return credentials, err - } else if err == keyring.ErrKeyNotFound { + } else if errors.Is(err, keyring.ErrKeyNotFound) { // Not found, continue } else { credentials = i.Data @@ -182,8 +188,6 @@ func GetConfigFromKeyring(backend string) ([]byte, error) { } // Validates that the requested backend is valid and available, returns an error if not. -// -// Note: CGO_ENABLED=1 is required for darwin builds (enables OSX Keychain) func ValidateBackend(backend string) error { if backend == "" { return ErrKeyringInvalid @@ -207,6 +211,55 @@ func ValidateBackend(backend string) error { return nil } +func keychainGet() ([]byte, error) { + credentials, err := gokeyring.Get(ItemKey, ItemKey) + if err != nil && !errors.Is(err, gokeyring.ErrNotFound) { + return []byte(credentials), err + } else if errors.Is(err, gokeyring.ErrNotFound) { + return []byte(""), nil + } + + if len(credentials) == 0 { + // No creds to decompress, return early + return []byte(""), nil + } + + creds, err := decompressConfig([]byte(credentials)) + if err != nil { + return nil, err + } + return creds, nil +} + +func keychainUpsert(creds []byte) error { + compressed, err := compressConfig(creds) + if err != nil { + return err + } + + err = gokeyring.Set(ItemKey, ItemKey, string(compressed)) + if err != nil { + return err + } + + return nil +} + +func keychainRemove() error { + err := gokeyring.Delete(ItemKey, ItemKey) + if err != nil { + if errors.Is(err, gokeyring.ErrNotFound) { + // Ignore not found errors, key is already removed + return nil + } + if strings.Contains(err.Error(), "Keychain Error. (-25244)") { + return fmt.Errorf("%s\nThis application may not have permission to delete from the Keychain. Please check the permissions in the Keychain and try again", err.Error()) + } + } + + return err +} + // Compresses credential bytes to help ensure all OS secure stores can store the data. // Windows Credential Manager has a 2500 byte limit. func compressConfig(creds []byte) ([]byte, error) { @@ -241,3 +294,13 @@ func decompressConfig(creds []byte) ([]byte, error) { return output, err } + +// isDarwin returns true if the current OS runtime is "darwin" +func isDarwin() bool { + return runtime.GOOS == "darwin" +} + +// isKeychain returns true if the backend is "keychain" +func isKeychain(backend string) bool { + return backend == "keychain" +} diff --git a/authentication/securestore/pass_test.go b/authentication/securestore/pass_test.go new file mode 100644 index 00000000..a9f40e47 --- /dev/null +++ b/authentication/securestore/pass_test.go @@ -0,0 +1,131 @@ +//go:build !windows +// +build !windows + +/* +Copyright (c) 2024 Red Hat, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package securestore + +import ( + "fmt" + "os" + "os/exec" + "path/filepath" + "time" + + . "github.com/onsi/ginkgo/v2" // nolint + . "github.com/onsi/gomega" // nolint + + . "github.com/openshift-online/ocm-sdk-go/testing" // nolint +) + +// This test requires `pass` to be installed. +// macOS: `brew install pass` +// linux: `sudo apt-get install pass` or `sudo yum install pass` + +const keyring_dir = "keyring-pass-test-*" + +func runCmd(cmds ...string) { + cmd := exec.Command(cmds[0], cmds[1:]...) //nolint:gosec + out, err := cmd.CombinedOutput() + if err != nil { + fmt.Println(cmd) + fmt.Println(string(out)) + Fail(err.Error()) + } +} + +var _ = Describe("Pass Keyring", Ordered, func() { + const backend = "pass" + + BeforeAll(func() { + pwd, err := os.Getwd() + if err != nil { + Fail(err.Error()) + } + pwdParent := filepath.Dir(pwd) + + // the default temp directory can't be used because gpg-agent complains with "socket name too long" + tmpdir, err := os.MkdirTemp("/tmp", keyring_dir) + if err != nil { + Fail(err.Error()) + + } + tmpdirPass, err := os.MkdirTemp("/tmp", ".password-store-*") + if err != nil { + Fail(err.Error()) + } + + // Initialise a blank GPG homedir; import & trust the test key + gnupghome := filepath.Join(tmpdir, ".gnupg") + err = os.Mkdir(gnupghome, os.FileMode(int(0700))) + if err != nil { + Fail(err.Error()) + } + os.Setenv("GNUPGHOME", gnupghome) + os.Setenv("PASSWORD_STORE_DIR", tmpdirPass) + os.Unsetenv("GPG_AGENT_INFO") + os.Unsetenv("GPG_TTY") + + runCmd("gpg", "--batch", "--import", filepath.Join(pwdParent, "testdata", "test-gpg.key")) + runCmd("gpg", "--batch", "--import-ownertrust", filepath.Join(pwdParent, "testdata", "test-ownertrust-gpg.txt")) + runCmd("pass", "init", "ocm-devel@redhat.com") + + DeferCleanup(func() { + os.Unsetenv("GNUPGHOME") + os.Unsetenv("PASSWORD_STORE_DIR") + os.RemoveAll(filepath.Join("/tmp", keyring_dir)) + }) + }) + + BeforeEach(func() { + err := RemoveConfigFromKeyring(backend) + Expect(err).To(BeNil()) + }) + + When("Listing Keyrings", func() { + It("Lists pass as a valid keyring", func() { + backends := AvailableBackends() + Expect(backends).To(ContainElement(backend)) + }) + }) + + When("Using Pass", func() { + It("Stores/Removes configuration in Pass", func() { + // Create the token + accessToken := MakeTokenString("Bearer", 15*time.Minute) + + // Run insert + err := UpsertConfigToKeyring(backend, []byte(accessToken)) + + Expect(err).To(BeNil()) + + // Check the content of the keyring + result, err := GetConfigFromKeyring(backend) + Expect(result).To(Equal([]byte(accessToken))) + Expect(err).To(BeNil()) + + // Remove the configuration from the keyring + err = RemoveConfigFromKeyring(backend) + Expect(err).To(BeNil()) + + // Ensure the keyring is empty + result, err = GetConfigFromKeyring(backend) + Expect(result).To(Equal([]byte(""))) + Expect(err).To(BeNil()) + }) + }) +}) diff --git a/authentication/securestore/wincred_test.go b/authentication/securestore/wincred_test.go new file mode 100644 index 00000000..29833675 --- /dev/null +++ b/authentication/securestore/wincred_test.go @@ -0,0 +1,71 @@ +//go:build windows +// +build windows + +/* +Copyright (c) 2024 Red Hat, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package securestore + +import ( + "time" + + . "github.com/onsi/ginkgo/v2" // nolint + . "github.com/onsi/gomega" // nolint + + . "github.com/openshift-online/ocm-sdk-go/testing" // nolint +) + +var _ = Describe("Wincred Keyring", func() { + const backend = "wincred" + + BeforeEach(func() { + err := RemoveConfigFromKeyring(backend) + Expect(err).To(BeNil()) + }) + + When("Listing Keyrings", func() { + It("Lists wincred as a valid keyring", func() { + backends := AvailableBackends() + Expect(backends).To(ContainElement(backend)) + }) + }) + + When("Using wincred", func() { + It("Stores/Removes via wincred", func() { + // Create the token + accessToken := MakeTokenString("Bearer", 15*time.Minute) + + // Run insert + err := UpsertConfigToKeyring(backend, []byte(accessToken)) + + Expect(err).To(BeNil()) + + // Check the content of the keyring + result, err := GetConfigFromKeyring(backend) + Expect(result).To(Equal([]byte(accessToken))) + Expect(err).To(BeNil()) + + // Remove the configuration from the keyring + err = RemoveConfigFromKeyring(backend) + Expect(err).To(BeNil()) + + // Ensure the keyring is empty + result, err = GetConfigFromKeyring(backend) + Expect(result).To(Equal([]byte(""))) + Expect(err).To(BeNil()) + }) + }) +}) diff --git a/authentication/testdata/test-gpg.key b/authentication/testdata/test-gpg.key new file mode 100644 index 00000000..087cf635 --- /dev/null +++ b/authentication/testdata/test-gpg.key @@ -0,0 +1,82 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- + +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 +mTmgGQ== +=I8cN +-----END PGP PRIVATE KEY BLOCK----- \ No newline at end of file diff --git a/authentication/testdata/test-ownertrust-gpg.txt b/authentication/testdata/test-ownertrust-gpg.txt new file mode 100644 index 00000000..1a26a32d --- /dev/null +++ b/authentication/testdata/test-ownertrust-gpg.txt @@ -0,0 +1,3 @@ +# List of assigned trustvalues, created Tue Feb 20 11:49:38 2024 EST +# (Use "gpg --import-ownertrust" to restore them) +D0F5D0EC5CF01F1EEE2389619BA9864A24FB1FA0:6: diff --git a/authentication/transport_wrapper_test.go b/authentication/transport_wrapper_test.go index 8cc605cd..ef770107 100644 --- a/authentication/transport_wrapper_test.go +++ b/authentication/transport_wrapper_test.go @@ -1,3 +1,6 @@ +//go:build linux +// +build linux + /* Copyright (c) 2019 Red Hat, Inc. diff --git a/configuration/main_test.go b/configuration/main_test.go index c37e6119..4f404352 100644 --- a/configuration/main_test.go +++ b/configuration/main_test.go @@ -1,3 +1,6 @@ +//go:build !windows +// +build !windows + /* Copyright (c) 2020 Red Hat, Inc. diff --git a/examples/go.mod b/examples/go.mod index cb09e42f..d6451837 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -16,6 +16,7 @@ require ( require ( github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.2 // indirect + github.com/alessio/shellescape v1.4.1 // indirect github.com/aymerick/douceur v0.2.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cenkalti/backoff/v4 v4.1.3 // indirect @@ -24,6 +25,7 @@ require ( github.com/dvsekhvalnov/jose2go v1.5.0 // indirect github.com/go-logr/logr v1.2.0 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect + github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v4 v4.4.1 // indirect github.com/golang/glog v1.0.0 // indirect @@ -43,6 +45,7 @@ require ( github.com/prometheus/common v0.32.1 // indirect github.com/prometheus/procfs v0.7.3 // indirect github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect + github.com/zalando/go-keyring v0.2.3 // indirect golang.org/x/net v0.19.0 // indirect golang.org/x/oauth2 v0.15.0 // indirect golang.org/x/sys v0.15.0 // indirect diff --git a/examples/go.sum b/examples/go.sum index 29a5375d..3807e846 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -45,6 +45,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVKJUX0= +github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= @@ -106,6 +108,8 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= +github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= +github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= @@ -316,6 +320,8 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/zalando/go-keyring v0.2.3 h1:v9CUu9phlABObO4LPWycf+zwMG7nlbb3t/B5wa97yms= +github.com/zalando/go-keyring v0.2.3/go.mod h1:HL4k+OXQfJUWaMnqyuSOc0drfGPX2b51Du6K+MRgZMk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= diff --git a/go.mod b/go.mod index 941ec47f..c79b1769 100644 --- a/go.mod +++ b/go.mod @@ -25,14 +25,18 @@ require ( gopkg.in/yaml.v3 v3.0.1 ) +require github.com/zalando/go-keyring v0.2.3 + require ( github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect + github.com/alessio/shellescape v1.4.1 // indirect github.com/aymerick/douceur v0.2.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/danieljoos/wincred v1.2.0 // indirect github.com/dvsekhvalnov/jose2go v1.5.0 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect + github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/gorilla/css v1.0.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect diff --git a/go.sum b/go.sum index ef215f85..d63be537 100644 --- a/go.sum +++ b/go.sum @@ -44,6 +44,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVKJUX0= +github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -91,6 +93,8 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= +github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= +github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -325,6 +329,8 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/zalando/go-keyring v0.2.3 h1:v9CUu9phlABObO4LPWycf+zwMG7nlbb3t/B5wa97yms= +github.com/zalando/go-keyring v0.2.3/go.mod h1:HL4k+OXQfJUWaMnqyuSOc0drfGPX2b51Du6K+MRgZMk= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= diff --git a/h2c_test.go b/h2c_test.go index ee120ead..4e5d7009 100644 --- a/h2c_test.go +++ b/h2c_test.go @@ -1,3 +1,6 @@ +//go:build !windows +// +build !windows + /* Copyright (c) 2021 Red Hat, Inc. diff --git a/unix_sockets_test.go b/unix_sockets_test.go index 6d0e7523..b1174104 100644 --- a/unix_sockets_test.go +++ b/unix_sockets_test.go @@ -1,3 +1,6 @@ +//go:build !windows +// +build !windows + /* Copyright (c) 2019 Red Hat, Inc.