diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..e299b1950 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,24 @@ +; https://editorconfig.org/ +root = true + +[*] +insert_final_newline = true +charset = utf-8 +trim_trailing_whitespace = true +indent_style = space +indent_size = 2 + +[{Makefile,go.mod,go.sum,*.go,.gitmodules}] +indent_style = tab +indent_size = 4 + +[*.md] +indent_size = 4 +trim_trailing_whitespace = false +eclint_indent_style = unset + +[*.html] +insert_final_newline = false + +[Dockerfile] +indent_size = 4 diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index c33a1a7c2..e81167f3b 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -10,7 +10,10 @@ jobs: build: name: Build - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macOS-latest] steps: - name: Set up Go 1.x @@ -22,4 +25,10 @@ jobs: uses: actions/checkout@v2 - name: Test - run: make ci \ No newline at end of file + run: go test -v ./... + + - name: golangci-lint + uses: golangci/golangci-lint-action@v2 + with: + # Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version. + version: v1.32 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..8e2afd89b --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,28 @@ +name: release + +on: + push: + tags: + - '*' + +jobs: + release: + name: release + runs-on: macOS-latest + steps: + + - name: Set up Go 1.x + uses: actions/setup-go@v2 + with: + go-version: 1.15.x + + - name: Check out code into the Go module directory + uses: actions/checkout@v2 + + - name: GoReleaser + uses: goreleaser/goreleaser-action@v2 + with: + version: latest + args: release --rm-dist + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 15c4962e3..186524f9f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ .DS_Store .credentials -/dist +/dist* /build /packages /release diff --git a/.golangci.yaml b/.golangci.yaml new file mode 100644 index 000000000..8cd3c6a64 --- /dev/null +++ b/.golangci.yaml @@ -0,0 +1,14 @@ +linters: + disable-all: true + enable: + - goimports + - deadcode + - errcheck + - gosimple + - govet + - ineffassign + - staticcheck + - structcheck + - typecheck + - unused + - varcheck diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 000000000..416840296 --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,29 @@ +--- +project_name: saml2aws + +builds: +- main: ./cmd/saml2aws/main.go + binary: saml2aws + flags: + - -trimpath + - -v + ldflags: + - -s -w -X main.Version={{.Version}} + goos: + - windows + - darwin + - linux + goarch: + - amd64 + - arm64 + - arm +archives: + - format: tar.gz + wrap_in_directory: false + format_overrides: + - goos: windows + format: zip + # remove README and LICENSE + files: + - LICENSE.md + - README.md diff --git a/Makefile b/Makefile index 49a48e15e..2af6bc523 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,8 @@ ARCH=$(shell uname -m) VERSION=2.28.0 ITERATION := 1 +GOLANGCI_VERSION = 1.32.0 + SOURCE_FILES?=$$(go list ./... | grep -v /vendor/) TEST_PATTERN?=. TEST_OPTIONS?= @@ -11,72 +13,43 @@ BIN_DIR := $(CURDIR)/bin ci: prepare test -prepare: prepare.metalinter - GOBIN=$(BIN_DIR) go install github.com/buildkite/github-release - GOBIN=$(BIN_DIR) go install github.com/mitchellh/gox - GOBIN=$(BIN_DIR) go install github.com/axw/gocov/gocov - GOBIN=$(BIN_DIR) go install golang.org/x/tools/cmd/cover +$(BIN_DIR)/golangci-lint: $(BIN_DIR)/golangci-lint-${GOLANGCI_VERSION} + @ln -sf golangci-lint-${GOLANGCI_VERSION} $(BIN_DIR)/golangci-lint +$(BIN_DIR)/golangci-lint-${GOLANGCI_VERSION}: + @curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | BINARY=golangci-lint bash -s -- v${GOLANGCI_VERSION} + @mv $(BIN_DIR)/golangci-lint $@ -# Gometalinter is deprecated and broken dependency so let's use with GO111MODULE=off -prepare.metalinter: - GO111MODULE=off go get -u github.com/alecthomas/gometalinter - GO111MODULE=off gometalinter --fast --install +$(BIN_DIR)/goreleaser: + @go get -u github.com/goreleaser/goreleaser + @env GOBIN=$(BIN_DIR) GO111MODULE=on go install github.com/goreleaser/goreleaser mod: @go mod download @go mod tidy -compile: mod - @rm -rf build/ - @$(BIN_DIR)/gox -ldflags "-X main.Version=$(VERSION)" \ - -osarch="darwin/amd64" \ - -osarch="linux/i386" \ - -osarch="linux/amd64" \ - -osarch="windows/amd64" \ - -osarch="windows/i386" \ - -output "build/{{.Dir}}_$(VERSION)_{{.OS}}_{{.Arch}}/$(NAME)" \ - ${SOURCE_FILES} +lint: $(BIN_DIR)/golangci-lint + @echo "--- lint all the things" + @$(BIN_DIR)/golangci-lint run ./... +.PHONY: lint -# Run all the linters -lint: - @gometalinter --vendor ./... +lint-fix: $(BIN_DIR)/golangci-lint + @echo "--- lint all the things" + @$(BIN_DIR)/golangci-lint run --fix ./... +.PHONY: lint-fix -# gofmt and goimports all go files -fmt: - find . -name '*.go' -not -wholename './vendor/*' | while read -r file; do gofmt -w -s "$$file"; goimports -w "$$file"; done +fmt: lint-fix install: go install ./cmd/saml2aws -dist: - $(eval FILES := $(shell ls build)) - @rm -rf dist && mkdir dist - @for f in $(FILES); do \ - (cd $(shell pwd)/build/$$f && tar -cvzf ../../dist/$$f.tar.gz *); \ - (cd $(shell pwd)/dist && shasum -a 512 $$f.tar.gz > $$f.sha512); \ - echo $$f; \ - done - -release: - @$(BIN_DIR)/github-release "v$(VERSION)" dist/* --commit "$(git rev-parse HEAD)" --github-repository versent/$(NAME) - -test: - @$(BIN_DIR)/gocov test $(SOURCE_FILES) | $(BIN_DIR)/gocov report +release-snapshot: $(BIN_DIR)/goreleaser + $(BIN_DIR)/goreleaser --snapshot --rm-dist clean: @rm -fr ./build -packages: - rm -rf package && mkdir package - rm -rf stage && mkdir -p stage/usr/bin - cp build/saml2aws_*_linux_amd64/saml2aws stage/usr/bin - fpm --name $(NAME) -a x86_64 -t rpm -s dir --version $(VERSION) --iteration $(ITERATION) -C stage -p package/$(NAME)-$(VERSION)_$(ITERATION).rpm usr - fpm --name $(NAME) -a x86_64 -t deb -s dir --version $(VERSION) --iteration $(ITERATION) -C stage -p package/$(NAME)-$(VERSION)_$(ITERATION).deb usr - shasum -a 512 package/$(NAME)-$(VERSION)_$(ITERATION).rpm > package/$(NAME)-$(VERSION)_$(ITERATION).rpm.sha512 - shasum -a 512 package/$(NAME)-$(VERSION)_$(ITERATION).deb > package/$(NAME)-$(VERSION)_$(ITERATION).deb.sha512 - generate-mocks: mockery -dir pkg/prompter --all mockery -dir pkg/provider/okta -name U2FDevice -.PHONY: default prepare.metalinter prepare mod compile lint fmt dist release test clean generate-mocks +.PHONY: default prepare mod compile fmt dist release test clean generate-mocks diff --git a/README.md b/README.md index 9cdbc1467..ba4cadcce 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,6 @@ Aside from Okta, most of the providers in this project are using screen scraping If you're on OSX you can install saml2aws using homebrew! ``` -brew tap versent/homebrew-taps brew install saml2aws saml2aws --version ``` @@ -550,6 +549,12 @@ Then to test the software just run. make test ``` +Before raising a PR please run the linter. + +``` +make lint-fix +``` + ## Environment vars The exec sub command will export the following environment variables. @@ -620,7 +625,7 @@ An example of the aws configuration (`~/.aws/config`): ``` [profile mybucket] region = us-west-1 -credential_process = saml2aws login --skip-prompt --quiet --credential-process --role +credential_process = saml2aws login --skip-prompt --quiet --credential-process --role --profile mybucket ``` When using the aws cli with the `mybucket` profile, the authentication process will be run and the aws will then be executed based on the returned credentials. diff --git a/cmd/saml2aws/commands/console.go b/cmd/saml2aws/commands/console.go index 8c981c422..cf11bf0d3 100644 --- a/cmd/saml2aws/commands/console.go +++ b/cmd/saml2aws/commands/console.go @@ -83,7 +83,7 @@ func loadOrLogin(account *cfg.IDPAccount, sharedCreds *awsconfig.CredentialsProv return loginRefreshCredentials(sharedCreds, execFlags.LoginExecFlags) } - if awsCreds.Expires.Sub(time.Now()) < 0 { + if time.Until(awsCreds.Expires) < 0 { log.Println("expired credentials triggering login") return loginRefreshCredentials(sharedCreds, execFlags.LoginExecFlags) } diff --git a/cmd/saml2aws/commands/exec.go b/cmd/saml2aws/commands/exec.go index 4e65c7969..b289ca443 100644 --- a/cmd/saml2aws/commands/exec.go +++ b/cmd/saml2aws/commands/exec.go @@ -47,7 +47,7 @@ func Exec(execFlags *flags.LoginExecFlags, cmdline []string) error { return errors.Wrap(err, "error loading credentials") } - if awsCreds.Expires.Sub(time.Now()) < 0 { + if time.Until(awsCreds.Expires) < 0 { return errors.New("error aws credentials have expired") } diff --git a/cmd/saml2aws/commands/login.go b/cmd/saml2aws/commands/login.go index 2dc39119e..be6c58cd9 100644 --- a/cmd/saml2aws/commands/login.go +++ b/cmd/saml2aws/commands/login.go @@ -46,12 +46,15 @@ func Login(loginFlags *flags.LoginExecFlags) error { if !sharedCreds.Expired() && !loginFlags.Force { logger.Debug("credentials are not expired skipping") - previous_creds, err := sharedCreds.Load() + previousCreds, err := sharedCreds.Load() if err != nil { log.Println("Unable to load cached credentials") } if loginFlags.CredentialProcess { - PrintCredentialProcess(previous_creds) + err = PrintCredentialProcess(previousCreds) + if err != nil { + return err + } } return nil } @@ -110,7 +113,10 @@ func Login(loginFlags *flags.LoginExecFlags) error { // print credential process if needed if loginFlags.CredentialProcess { - PrintCredentialProcess(awsCreds) + err = PrintCredentialProcess(awsCreds) + if err != nil { + return err + } } return saveCredentials(awsCreds, sharedCreds) } @@ -348,13 +354,12 @@ func CredentialsToCredentialProcess(awsCreds *awsconfig.AWSCredentials) (string, } -// PrintCredentialProcess -// Prints a Json output that is compatible with the AWS credential_process +// PrintCredentialProcess Prints a Json output that is compatible with the AWS credential_process // https://github.com/awslabs/awsprocesscreds func PrintCredentialProcess(awsCreds *awsconfig.AWSCredentials) error { - json_output, err := CredentialsToCredentialProcess(awsCreds) + jsonData, err := CredentialsToCredentialProcess(awsCreds) if err == nil { - fmt.Println(json_output) + fmt.Println(jsonData) } return err } diff --git a/cmd/saml2aws/commands/script.go b/cmd/saml2aws/commands/script.go index 35372c207..7592c1e99 100644 --- a/cmd/saml2aws/commands/script.go +++ b/cmd/saml2aws/commands/script.go @@ -61,7 +61,7 @@ func Script(execFlags *flags.LoginExecFlags, shell string) error { return errors.Wrap(err, "error loading credentials") } - if awsCreds.Expires.Sub(time.Now()) < 0 { + if time.Until(awsCreds.Expires) < 0 { return errors.New("error aws credentials have expired") } diff --git a/go.mod b/go.mod index cf189d39f..ceb72ebb8 100644 --- a/go.mod +++ b/go.mod @@ -3,37 +3,43 @@ module github.com/versent/saml2aws/v2 go 1.15 require ( - github.com/99designs/keyring v0.0.0-20190110203331-82da6802f65f + github.com/99designs/keyring v1.1.6 github.com/AlecAivazis/survey/v2 v2.2.2 github.com/Azure/go-ntlmssp v0.0.0-20180416175057-4b934ac9dad3 github.com/PuerkitoBio/goquery v1.5.1 github.com/alecthomas/kingpin v2.2.6+incompatible - github.com/alecthomas/units v0.0.0-20190910110746-680d30ca3117 // indirect - github.com/aulanov/go.dbus v0.0.0-20150729231527-25c3068a42a0 // indirect + github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect + github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect github.com/avast/retry-go v2.6.0+incompatible - github.com/aws/aws-sdk-go v1.35.24 + github.com/aws/aws-sdk-go v1.37.11 github.com/beevik/etree v1.0.1 - github.com/danieljoos/wincred v1.0.1 - github.com/dvsekhvalnov/jose2go v0.0.0-20170216131308-f21a8cedbbae // indirect + github.com/danieljoos/wincred v1.1.0 + github.com/dvsekhvalnov/jose2go v1.5.0 // indirect github.com/godbus/dbus v4.1.0+incompatible // indirect - github.com/google/uuid v1.1.1 - github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect - github.com/keybase/go-keychain v0.0.0-20201121013009-976c83ec27a6 + github.com/google/uuid v1.2.0 + github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d + github.com/kr/text v0.2.0 // indirect + github.com/magefile/mage v1.11.0 // indirect github.com/marshallbrekka/go-u2fhost v0.0.0-20210111072507-3ccdec8c8105 + github.com/mattn/go-colorable v0.1.8 // indirect github.com/mitchellh/go-homedir v1.1.0 github.com/pkg/errors v0.9.1 - github.com/sirupsen/logrus v1.6.0 + github.com/sirupsen/logrus v1.7.1 github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 - github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 // indirect - github.com/stretchr/objx v0.2.0 // indirect - github.com/stretchr/testify v1.5.1 + github.com/smartystreets/assertions v1.0.0 // indirect + github.com/smartystreets/goconvey v1.6.4 // indirect + github.com/stretchr/objx v0.3.0 // indirect + github.com/stretchr/testify v1.7.0 github.com/tidwall/gjson v1.1.1 github.com/tidwall/match v1.0.0 // indirect - golang.org/x/net v0.0.0-20200202094626-16171245cfb2 - golang.org/x/sys v0.0.0-20190919044723-0c1ff786ef13 // indirect - golang.org/x/text v0.3.2 // indirect - gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect - gopkg.in/ini.v1 v1.57.0 + golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad // indirect + golang.org/x/net v0.0.0-20210119194325-5f4716e94777 + golang.org/x/sys v0.0.0-20210216163648-f7da38b97c65 // indirect + golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf // indirect + golang.org/x/text v0.3.5 // indirect + gopkg.in/ini.v1 v1.62.0 + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect ) -replace github.com/keybase/go-keychain => github.com/wolfeidau/go-keychain v0.0.0-20210215232950-1e19148f864f +// replace github.com/keybase/go-keychain => github.com/wolfeidau/go-keychain v0.0.0-20210215232950-1e19148f864f diff --git a/go.sum b/go.sum index 73512a6f4..623972376 100644 --- a/go.sum +++ b/go.sum @@ -1,10 +1,11 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -github.com/99designs/keyring v0.0.0-20190110203331-82da6802f65f h1:WXiWWJrYCaOaYimBAXlRdRJ7qOisrYyMLYnCvvhHVms= -github.com/99designs/keyring v0.0.0-20190110203331-82da6802f65f/go.mod h1:aKt8W/yd91/xHY6ixZAJZ2vYbhr3pP8DcrvuGSGNPJk= +github.com/99designs/keyring v1.1.6 h1:kVDC2uCgVwecxCk+9zoCt2uEL6dt+dfVzMvGgnVcIuM= +github.com/99designs/keyring v1.1.6/go.mod h1:16e0ds7LGQQcT59QqkTg72Hh5ShM51Byv5PEmW6uoRU= github.com/AlecAivazis/survey/v2 v2.2.2 h1:1I4qBrNsHQE+91tQCqVlfrKe9DEL65949d1oKZWVELY= github.com/AlecAivazis/survey/v2 v2.2.2/go.mod h1:9FJRdMdDm8rnT+zHVbvQT2RTSTLq0Ttd6q3Vl2fahjk= github.com/Azure/go-ntlmssp v0.0.0-20180416175057-4b934ac9dad3 h1:r8SecdrDTMoF5DXQWYTAGv3Py8EnuxEOah49lc4E29o= github.com/Azure/go-ntlmssp v0.0.0-20180416175057-4b934ac9dad3/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8 h1:xzYJEypr/85nBpB11F9br+3HUrpgb+fcm5iADzXXYEw= github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc= @@ -15,18 +16,18 @@ github.com/alecthomas/kingpin v2.2.6+incompatible h1:5svnBTFgJjZvGKyYBtMB0+m5wvr github.com/alecthomas/kingpin v2.2.6+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190910110746-680d30ca3117 h1:aUo+WrWZtRRfc6WITdEKzEczFRlEpfW15NhNeLRc17U= -github.com/alecthomas/units v0.0.0-20190910110746-680d30ca3117/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/andybalholm/cascadia v1.1.0 h1:BuuO6sSfQNFRu1LppgbD25Hr2vLYW25JvxHs5zzsLTo= github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/aulanov/go.dbus v0.0.0-20150729231527-25c3068a42a0 h1:EEDvbomAQ+MFWqJ9FM6RXyJTkc4lckyWsbc5CGQkG1Y= -github.com/aulanov/go.dbus v0.0.0-20150729231527-25c3068a42a0/go.mod h1:VHvUx+4lTCaJ8zUnEXF4cWEc9c8lnDt4PGLwlZ+3yaM= github.com/avast/retry-go v2.6.0+incompatible h1:FelcMrm7Bxacr1/RM8+/eqkDkmVN7tjlsy51dOzB3LI= github.com/avast/retry-go v2.6.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= -github.com/aws/aws-sdk-go v1.35.24 h1:U3GNTg8+7xSM6OAJ8zksiSM4bRqxBWmVwwehvOSNG3A= -github.com/aws/aws-sdk-go v1.35.24/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k= +github.com/aws/aws-sdk-go v1.37.11 h1:W1gUQxt6jmiUsk2jkTVAlYsd3Sg8bNL2VDcWjrXmD+0= +github.com/aws/aws-sdk-go v1.37.11/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/bearsh/hid v1.3.0 h1:GLNa8hvEzJxzQEEpheDUr2SivvH7iwTrJrDhFKutfX8= github.com/bearsh/hid v1.3.0/go.mod h1:KbQByg8WfPr92v7aaKAHTtZUEVG7e2XRpcF8+TopQv8= github.com/beevik/etree v1.0.1 h1:lWzdj5v/Pj1X360EV7bUudox5SRipy4qZLjY0rhb0ck= @@ -34,6 +35,7 @@ github.com/beevik/etree v1.0.1/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -41,21 +43,27 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/danieljoos/wincred v1.0.1 h1:fcRTaj17zzROVqni2FiToKUVg3MmJ4NtMSGCySPIr/g= -github.com/danieljoos/wincred v1.0.1/go.mod h1:SnuYRW9lp1oJrZX/dXJqr0cPK5gYXqx3EJbmjhLdK9U= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/danieljoos/wincred v1.0.2 h1:zf4bhty2iLuwgjgpraD2E9UbvO+fe54XXGJbOwe23fU= +github.com/danieljoos/wincred v1.0.2/go.mod h1:SnuYRW9lp1oJrZX/dXJqr0cPK5gYXqx3EJbmjhLdK9U= +github.com/danieljoos/wincred v1.1.0 h1:3RNcEpBg4IhIChZdFRSdlQt1QjCp1sMAPIrOnm7Yf8g= +github.com/danieljoos/wincred v1.1.0/go.mod h1:XYlo+eRTsVA9aHGp7NGjFkPla4m+DCL7hqDjlFjiygg= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dvsekhvalnov/jose2go v0.0.0-20170216131308-f21a8cedbbae h1:UTOyRlLeWJrZx+ynml6q6qzZ1uDkJe/0Z5CMZRbEIJg= -github.com/dvsekhvalnov/jose2go v0.0.0-20170216131308-f21a8cedbbae/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM= +github.com/dvsekhvalnov/jose2go v0.0.0-20200901110807-248326c1351b h1:HBah4D48ypg3J7Np4N+HY/ZR76fx3HEUGxDU6Uk39oQ= +github.com/dvsekhvalnov/jose2go v0.0.0-20200901110807-248326c1351b/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM= +github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQxaLAeM= +github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus v4.1.0+incompatible h1:WqqLRTsQic3apZUK9qC5sGNfXthmPXzUZ7nQPrNITa4= github.com/godbus/dbus v4.1.0+incompatible/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -67,8 +75,8 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= @@ -77,9 +85,11 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174 h1:WlZsjVhE8Af9IcZDGgJGQpNflI3+MJSBhsgT5PCtzBQ= github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= @@ -91,8 +101,10 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= -github.com/keybase/go.dbus v0.0.0-20200324223359-a94be52c0b03/go.mod h1:a8clEhrrGV/d76/f9r2I41BwANMihfZYV9C223vaxqE= +github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d h1:Z+RDyXzjKE0i2sTjZ/b1uxiGtPhFy34Ou/Tk0qwN0kM= +github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d/go.mod h1:JJNrCn9otv/2QP4D7SMJBgaleKpOf66PnW6F5WGNRIc= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= @@ -105,20 +117,34 @@ github.com/kr/pty v1.1.4 h1:5Myjjh3JY/NaAi4IsUbHADytDyl1VE1Y9PXDlL+P/VQ= github.com/kr/pty v1.1.4/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/magefile/mage v1.10.0 h1:3HiXzCUY12kh9bIuyXShaVe529fJfyqoVM42o/uom2g= +github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= +github.com/magefile/mage v1.11.0 h1:C/55Ywp9BpgVVclD3lRnSYCwXTYxmSppIgLeDYlNuls= +github.com/magefile/mage v1.11.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/marshallbrekka/go-u2fhost v0.0.0-20210111072507-3ccdec8c8105 h1:Si3VAYdC1ZtA58UsDXxlkbpF5EMWxoCJP9gn1cYQ+vc= github.com/marshallbrekka/go-u2fhost v0.0.0-20210111072507-3ccdec8c8105/go.mod h1:VyqGj5jbZtzHO11cS7rkDh/owr/rNCEM98IhQwWvmXg= github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= +github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -141,12 +167,16 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.1 h1:rsizeFmZP+GYwyb4V6t6qpG7ZNWzA2bvgW/yC2xHCcg= +github.com/sirupsen/logrus v1.7.1/go.mod h1:4GuYW9TZmE769R5STWrRakJc4UqQ3+QQ95fyz7ENv1A= github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8= -github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/smartystreets/assertions v1.0.0 h1:UVQPSSmc3qtTi+zPPkCXvZX9VvW/xT/NsRvKfwY81a8= +github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= @@ -159,20 +189,22 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.3.0 h1:NGXK3lHquSN08v5vWalVI/L8XU9hdzE/G6xsrze47As= +github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/tidwall/gjson v1.1.1 h1:XSn7wxSH2Us55nigCfI8WrNfe2gihrwOSJU39w7Ot2w= github.com/tidwall/gjson v1.1.1/go.mod h1:c/nTNbUr0E0OrXEhq1pwa8iEgc2DOt4ZZqAt1HtCkPA= github.com/tidwall/match v1.0.0 h1:Ym1EcFkp+UQ4ptxfWlW+iMdq5cPH5nEuGzdf/Pb7VmI= github.com/tidwall/match v1.0.0/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/wolfeidau/go-keychain v0.0.0-20210215232950-1e19148f864f h1:GcPUj8RkdhxTeykVFO/+gzlYMrHBCOOl7A9VRiWhT3M= -github.com/wolfeidau/go-keychain v0.0.0-20210215232950-1e19148f864f/go.mod h1:N83iQ9rnnzi2KZuTu+0xBcD1JNWn1jSN140ggAF7HeE= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= @@ -181,9 +213,12 @@ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5 h1:8dUaAV7K4uHsF56JQWkprecIQKdPHtR9jCHF5nB8uzc= golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59 h1:3zb4D3T4G8jdExgVU/95+vQXfpEPiMdCaZgmGVxjNHM= -golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -195,6 +230,9 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777 h1:003p0dJM77cxMSyCPFphvZf/Y5/NXf5fzg6ufd1/Oew= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -208,11 +246,23 @@ golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190530182044-ad28b68e88f1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190919044723-0c1ff786ef13 h1:/zi0zzlPHWXYXrO1LjNRByFu8sdGgCkj2JLDdBIB84k= -golang.org/x/sys v0.0.0-20190919044723-0c1ff786ef13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210216163648-f7da38b97c65 h1:pTMjDVnP5eVRRlWO76rEWJ8JoC6Lf1CmyjPZXRiy2Sw= +golang.org/x/sys v0.0.0-20210216163648-f7da38b97c65/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221 h1:/ZHdbVpdR/jk3g30/d4yUL0JU9kksj8+F/bnQUVLGDM= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf h1:MZ2shdL+ZM/XzY3ZGOnh4Nlpnxz5GSOhOmtHo3iPU6M= +golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -226,14 +276,19 @@ google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ij gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/ini.v1 v1.57.0 h1:9unxIsFcTt4I55uWluz+UmL95q4kdJ0buvQ1ZIqVQww= -gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U= +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= +gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/helper/osxkeychain/keychain.go b/helper/osxkeychain/keychain.go new file mode 100644 index 000000000..6101875d4 --- /dev/null +++ b/helper/osxkeychain/keychain.go @@ -0,0 +1,84 @@ +// +build darwin + +package osxkeychain + +/* +#cgo LDFLAGS: -framework CoreFoundation -framework Security + +#include +#include +*/ +import "C" +import "github.com/keybase/go-keychain" + +// Protocols used to covert protocol to kSecAttrProtocol +var Protocols = map[string]string{ + "https": CFStringToString(C.CFStringRef(C.kSecAttrProtocolHTTPS)), + "http": CFStringToString(C.CFStringRef(C.kSecAttrProtocolHTTP)), + "smtp": CFStringToString(C.CFStringRef(C.kSecAttrProtocolSMTP)), + "pop3": CFStringToString(C.CFStringRef(C.kSecAttrProtocolPOP3)), + "pop3s": CFStringToString(C.CFStringRef(C.kSecAttrProtocolPOP3S)), + "socks": CFStringToString(C.CFStringRef(C.kSecAttrProtocolSOCKS)), + "imap": CFStringToString(C.CFStringRef(C.kSecAttrProtocolIMAP)), + "imaps": CFStringToString(C.CFStringRef(C.kSecAttrProtocolIMAPS)), + "ldap": CFStringToString(C.CFStringRef(C.kSecAttrProtocolLDAP)), + "ldaps": CFStringToString(C.CFStringRef(C.kSecAttrProtocolLDAPS)), + "ssh": CFStringToString(C.CFStringRef(C.kSecAttrProtocolSSH)), + "ftp": CFStringToString(C.CFStringRef(C.kSecAttrProtocolFTP)), + "ftps": CFStringToString(C.CFStringRef(C.kSecAttrProtocolFTPS)), +} + +var ( + // ServerKey is for kSecAttrServer + ServerKey = attrKey(C.CFTypeRef(C.kSecAttrServer)) + // ProtocolKey is for kSecAttrProtocol + ProtocolKey = attrKey(C.CFTypeRef(C.kSecAttrProtocol)) + // PortKey is for kSecAttrPort + PortKey = attrKey(C.CFTypeRef(C.kSecAttrPort)) + // PathKey is for kSecAttrPath + PathKey = attrKey(C.CFTypeRef(C.kSecAttrPath)) +) + +// SetPath sets the Path attribute +func SetPath(k keychain.Item, s string) { + k.SetString(PathKey, s) +} + +// SetPort sets the Port attribute +func SetPort(k keychain.Item, s string) { + k.SetString(PortKey, s) +} + +// SetProtocol sets the Protocol attribute +func SetProtocol(k keychain.Item, s string) { + k.SetString(ProtocolKey, Protocols[s]) +} + +// SetServer sets the server attribute +func SetServer(k keychain.Item, s string) { + k.SetString(ServerKey, s) +} + +func attrKey(ref C.CFTypeRef) string { + return CFStringToString(C.CFStringRef(ref)) +} + +// CFStringToString converts a CFStringRef to a string. +func CFStringToString(s C.CFStringRef) string { + p := C.CFStringGetCStringPtr(s, C.kCFStringEncodingUTF8) + if p != nil { + return C.GoString(p) + } + length := C.CFStringGetLength(s) + if length == 0 { + return "" + } + maxBufLen := C.CFStringGetMaximumSizeForEncoding(length, C.kCFStringEncodingUTF8) + if maxBufLen == 0 { + return "" + } + buf := make([]byte, maxBufLen) + var usedBufLen C.CFIndex + _ = C.CFStringGetBytes(s, C.CFRange{0, length}, C.kCFStringEncodingUTF8, C.UInt8(0), C.false, (*C.UInt8)(&buf[0]), maxBufLen, &usedBufLen) + return string(buf[:usedBufLen]) +} diff --git a/helper/osxkeychain/osxkeychain.go b/helper/osxkeychain/osxkeychain.go index 1c31e2843..7fbff79ca 100644 --- a/helper/osxkeychain/osxkeychain.go +++ b/helper/osxkeychain/osxkeychain.go @@ -13,10 +13,6 @@ import ( var logger = logrus.WithField("helper", "osxkeychain") -// errCredentialsNotFound is the specific error message returned by OS X -// when the credentials are not in the keychain. -const errCredentialsNotFound = "The specified item could not be found in the keychain." - // Osxkeychain handles secrets using the OS X Keychain as store. type Osxkeychain struct{} @@ -107,13 +103,13 @@ func splitServer3(serverURL string, item keychain.Item) (err error) { } hostAndPort := strings.Split(u.Host, ":") - item.SetServer(hostAndPort[0]) + SetServer(item, hostAndPort[0]) if len(hostAndPort) == 2 { - item.SetPort(hostAndPort[1]) + SetPort(item, hostAndPort[1]) } - item.SetProtocol(u.Scheme) - item.SetPath(u.Path) + SetProtocol(item, u.Scheme) + SetPath(item, u.Path) return } diff --git a/helper/osxkeychain/osxkeychain_darwin_test.go b/helper/osxkeychain/osxkeychain_darwin_test.go index 8956dbbe4..703ea7142 100644 --- a/helper/osxkeychain/osxkeychain_darwin_test.go +++ b/helper/osxkeychain/osxkeychain_darwin_test.go @@ -25,6 +25,7 @@ package osxkeychain import ( "testing" + "github.com/stretchr/testify/require" "github.com/versent/saml2aws/v2/helper/credentials" ) @@ -57,8 +58,12 @@ func TestOSXKeychainHelper(t *testing.T) { t.Fatalf("expected %s, got %s\n", "foobarbaz", secret) } - helper.Add(creds1) - defer helper.Delete(creds1.ServerURL) + err = helper.Add(creds1) + require.Nil(t, err) + + defer func() { + _ = helper.Delete(creds1.ServerURL) + }() if err := helper.Delete(creds.ServerURL); err != nil { t.Fatal(err) diff --git a/pkg/page/form.go b/pkg/page/form.go index 58ac74edf..cdbb6e0be 100644 --- a/pkg/page/form.go +++ b/pkg/page/form.go @@ -82,7 +82,7 @@ func NewFormFromDocument(doc *goquery.Document, formFilter string) (*Form, error } func NewFormFromResponse(res *http.Response, formFilter string) (*Form, error) { - doc, err := goquery.NewDocumentFromResponse(res) + doc, err := goquery.NewDocumentFromReader(res.Body) if err != nil { return nil, errors.Wrap(err, "failed to build document from response") } diff --git a/pkg/prompter/survey.go b/pkg/prompter/survey.go index 782f6b14d..686a835fb 100644 --- a/pkg/prompter/survey.go +++ b/pkg/prompter/survey.go @@ -22,7 +22,7 @@ func (cli *CliPrompter) RequestSecurityCode(pattern string) string { prompt := &survey.Input{ Message: fmt.Sprintf("Security Token [%s]", pattern), } - survey.AskOne(prompt, &token, survey.WithValidator(survey.Required)) + _ = survey.AskOne(prompt, &token, survey.WithValidator(survey.Required)) return token } @@ -34,7 +34,7 @@ func (cli *CliPrompter) ChooseWithDefault(pr string, defaultValue string, option Options: options, Default: defaultValue, } - survey.AskOne(prompt, &selected, survey.WithValidator(survey.Required)) + _ = survey.AskOne(prompt, &selected, survey.WithValidator(survey.Required)) // return the selected element index for i, option := range options { @@ -52,7 +52,7 @@ func (cli *CliPrompter) Choose(pr string, options []string) int { Message: pr, Options: options, } - survey.AskOne(prompt, &selected, survey.WithValidator(survey.Required)) + _ = survey.AskOne(prompt, &selected, survey.WithValidator(survey.Required)) // return the selected element index for i, option := range options { @@ -70,7 +70,7 @@ func (cli *CliPrompter) String(pr string, defaultValue string) string { Message: pr, Default: defaultValue, } - survey.AskOne(prompt, &val) + _ = survey.AskOne(prompt, &val) return val } @@ -80,7 +80,7 @@ func (cli *CliPrompter) StringRequired(pr string) string { prompt := &survey.Input{ Message: pr, } - survey.AskOne(prompt, &val, survey.WithValidator(survey.Required)) + _ = survey.AskOne(prompt, &val, survey.WithValidator(survey.Required)) return val } @@ -90,6 +90,6 @@ func (cli *CliPrompter) Password(pr string) string { prompt := &survey.Password{ Message: pr, } - survey.AskOne(prompt, &val) + _ = survey.AskOne(prompt, &val) return val } diff --git a/pkg/provider/aad/aad.go b/pkg/provider/aad/aad.go index 644f3a07c..b0a0a752b 100644 --- a/pkg/provider/aad/aad.go +++ b/pkg/provider/aad/aad.go @@ -885,13 +885,12 @@ func (ac *Client) Authenticate(loginDetails *creds.LoginDetails) (string, error) } ac.client.EnableFollowRedirect() } - } else { - // There was no explicit link to skip MFA - // and there were no MFA options available for us to process - // This can happen if MFA is enabled, but we're accessing from a MFA trusted IP - // See https://docs.microsoft.com/en-us/azure/active-directory/authentication/howto-mfa-mfasettings#targetText=MFA%20service%20settings,-Settings%20for%20app&targetText=Service%20settings%20can%20be%20accessed,Additional%20cloud-based%20MFA%20settings. - // Proceed with login as normal } + // There was no explicit link to skip MFA + // and there were no MFA options available for us to process + // This can happen if MFA is enabled, but we're accessing from a MFA trusted IP + // See https://docs.microsoft.com/en-us/azure/active-directory/authentication/howto-mfa-mfasettings#targetText=MFA%20service%20settings,-Settings%20for%20app&targetText=Service%20settings%20can%20be%20accessed,Additional%20cloud-based%20MFA%20settings. + // Proceed with login as normal // If we've been prompted with KMSI despite not going via MFA flow // Azure can do this if MFA is enabled but @@ -1044,12 +1043,10 @@ func (ac *Client) Authenticate(loginDetails *creds.LoginDetails) (string, error) if !ok { return } - if attrName == "SAMLResponse" { - samlAssertion, ok = s.Attr("value") - if !ok { - return - } + if attrName != "SAMLResponse" { + return } + samlAssertion, _ = s.Attr("value") }) if samlAssertion != "" { return samlAssertion, nil @@ -1064,17 +1061,18 @@ func (ac *Client) Authenticate(loginDetails *creds.LoginDetails) (string, error) if err != nil { return samlAssertion, errors.Wrap(err, "failed to build document from result body") } + doc.Find("input").Each(func(i int, s *goquery.Selection) { attrName, ok := s.Attr("name") if !ok { return } - if attrName == "SAMLResponse" { - samlAssertion, ok = s.Attr("value") - if !ok { - return - } + + if attrName != "SAMLResponse" { + return } + + samlAssertion, _ = s.Attr("value") }) if samlAssertion != "" { return samlAssertion, nil diff --git a/pkg/provider/adfs/adfs.go b/pkg/provider/adfs/adfs.go index 80bb54f1f..68dd708d9 100644 --- a/pkg/provider/adfs/adfs.go +++ b/pkg/provider/adfs/adfs.go @@ -203,7 +203,7 @@ func checkResponse(doc *goquery.Document) (AuthResponseType, string, error) { if name == "AuthMethod" { val, _ := s.Attr("value") switch val { - case "VIPAuthenticationProviderWindowsAccountName", "VIPAuthenticationProviderUPN": + case "VIPAuthenticationProviderWindowsAccountName", "VIPAuthenticationProviderUPN", "Defender AD FS Adapter": responseType = MFA_PROMPT case "AzureMfaAuthentication": responseType = AZURE_MFA_WAIT @@ -255,6 +255,8 @@ func updateOTPFormData(otpForm url.Values, s *goquery.Selection, token string) { otpForm.Add(name, token) } else if strings.Contains(lname, "verificationcode") { otpForm.Add(name, token) + } else if strings.Contains(lname, "challengequestionanswer") { + otpForm.Add(name, token) } else { updatePassthroughFormData(otpForm, s) } diff --git a/pkg/provider/adfs2/adfs2.go b/pkg/provider/adfs2/adfs2.go index 0640dab3e..2b6dca291 100644 --- a/pkg/provider/adfs2/adfs2.go +++ b/pkg/provider/adfs2/adfs2.go @@ -2,11 +2,12 @@ package adfs2 import ( "crypto/tls" - "github.com/versent/saml2aws/v2/pkg/provider" "log" "net/http" "net/http/cookiejar" + "github.com/versent/saml2aws/v2/pkg/provider" + "golang.org/x/net/publicsuffix" "github.com/Azure/go-ntlmssp" diff --git a/pkg/provider/adfs2/rsa.go b/pkg/provider/adfs2/rsa.go index f5bbdd44e..5dca411cc 100644 --- a/pkg/provider/adfs2/rsa.go +++ b/pkg/provider/adfs2/rsa.go @@ -40,6 +40,9 @@ func (ac *Client) authenticateRsa(loginDetails *creds.LoginDetails) (string, err */ if passcodeForm.Get("AuthMethod") == "SecurIDv2Authentication" { doc, err = ac.postPasscodeForm(passcodeActionURL, passcodeForm) + if err != nil { + return "", errors.Wrap(err, "error posting passcode form") + } } passcodeForm, passcodeActionURL, err = extractFormData(doc) @@ -96,7 +99,7 @@ func (ac *Client) postLoginForm(authSubmitURL string, authForm url.Values) (*goq logger.WithField("status", res.StatusCode).WithField("authSubmitURL", authSubmitURL).WithField("res", dump.ResponseString(res)).Debug("POST") - doc, err := goquery.NewDocumentFromResponse(res) + doc, err := goquery.NewDocumentFromReader(res.Body) if err != nil { return nil, errors.Wrap(err, "failed to build document from response") } @@ -122,7 +125,10 @@ func (ac *Client) getLoginForm(loginDetails *creds.LoginDetails) (string, url.Va // Extract the form and actionURL from the previous response - doc, err := goquery.NewDocumentFromResponse(res) + doc, err := goquery.NewDocumentFromReader(res.Body) + if err != nil { + return "", nil, errors.Wrap(err, "error extracting response data") + } authForm, authSubmitURL, err := extractFormData(doc) if err != nil { return "", nil, errors.Wrap(err, "error extracting login data") @@ -150,7 +156,7 @@ func (ac *Client) postPasscodeForm(passcodeActionURL string, passcodeForm url.Va logger.WithField("status", res.StatusCode).WithField("passcodeActionURL", passcodeActionURL).WithField("res", dump.ResponseString(res)).Debug("POST") - doc, err := goquery.NewDocumentFromResponse(res) + doc, err := goquery.NewDocumentFromReader(res.Body) if err != nil { return nil, errors.Wrap(err, "failed to build document from response") } diff --git a/pkg/provider/adfs2/rsa_test.go b/pkg/provider/adfs2/rsa_test.go index db15800fa..9d5c60f50 100644 --- a/pkg/provider/adfs2/rsa_test.go +++ b/pkg/provider/adfs2/rsa_test.go @@ -21,7 +21,7 @@ func TestClient_getLoginForm(t *testing.T) { require.Nil(t, err) ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write(data) + _, _ = w.Write(data) })) defer ts.Close() @@ -48,7 +48,7 @@ func TestClient_postLoginForm(t *testing.T) { require.Nil(t, err) ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write(data) + _, _ = w.Write(data) })) defer ts.Close() diff --git a/pkg/provider/akamai/akamai.go b/pkg/provider/akamai/akamai.go index 6bb0b2d42..2f9637ee3 100644 --- a/pkg/provider/akamai/akamai.go +++ b/pkg/provider/akamai/akamai.go @@ -126,7 +126,7 @@ func (oc *Client) Authenticate(loginDetails *creds.LoginDetails) (string, error) return samlAssertion, errors.Wrap(err, "error retrieving login request") } - doc, err := goquery.NewDocumentFromResponse(res) + doc, err := goquery.NewDocumentFromReader(res.Body) if err != nil { return samlAssertion, errors.Wrap(err, "error parsing document") } @@ -466,7 +466,7 @@ func verifyMfa(oc *Client, akamaiOrgHost string, loginDetails *creds.LoginDetail } //try to extract sid - doc, err := goquery.NewDocumentFromResponse(res) + doc, err := goquery.NewDocumentFromReader(res.Body) if err != nil { return errors.Wrap(err, "error parsing document from duo") } diff --git a/pkg/provider/base_validate.go b/pkg/provider/base_validate.go index 9bcea65a0..47cce5320 100644 --- a/pkg/provider/base_validate.go +++ b/pkg/provider/base_validate.go @@ -2,6 +2,7 @@ package provider import ( "errors" + "github.com/versent/saml2aws/v2/pkg/creds" ) diff --git a/pkg/provider/f5apm/f5apm_test.go b/pkg/provider/f5apm/f5apm_test.go index 4d42bbfc0..5aa065e0f 100644 --- a/pkg/provider/f5apm/f5apm_test.go +++ b/pkg/provider/f5apm/f5apm_test.go @@ -22,7 +22,7 @@ func TestClient_getLoginForm(t *testing.T) { require.Nil(t, err) ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write(data) + _, _ = w.Write(data) })) defer ts.Close() @@ -47,7 +47,7 @@ func TestClient_postLoginForm_user_pass(t *testing.T) { require.Nil(t, err) ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write(data) + _, _ = w.Write(data) })) defer ts.Close() diff --git a/pkg/provider/googleapps/googleapps.go b/pkg/provider/googleapps/googleapps.go index 637676360..1e58a2ea0 100644 --- a/pkg/provider/googleapps/googleapps.go +++ b/pkg/provider/googleapps/googleapps.go @@ -405,7 +405,7 @@ func (kc *Client) loadChallengePage(submitURL string, referer string, authForm u response, err := u2fClient.ChallengeU2F() if err != nil { - errors.Wrap(err, "Second factor failed.") + logger.WithError(err).Error("Second factor failed.") return kc.skipChallengePage(doc, submitURL, secondActionURL, loginDetails) } @@ -695,7 +695,7 @@ func extractKeyHandles(doc *goquery.Document, challengeTxt string) (string, []st firstIdx := strings.Index(val, "{") lastIdx := strings.LastIndex(val, "}") obj := []byte(val[firstIdx : lastIdx+1]) - json.Unmarshal(obj, &result) + _ = json.Unmarshal(obj, &result) // ignore the error and continue // Key handles for _, val := range result { list, ok := val.([]interface{}) diff --git a/pkg/provider/googleapps/googleapps_test.go b/pkg/provider/googleapps/googleapps_test.go index dd54eed78..462e61138 100644 --- a/pkg/provider/googleapps/googleapps_test.go +++ b/pkg/provider/googleapps/googleapps_test.go @@ -83,7 +83,7 @@ func TestChallengePage(t *testing.T) { require.Nil(t, err) ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write(data) + _, _ = w.Write(data) })) defer ts.Close() diff --git a/pkg/provider/googleapps/u2f_test.go b/pkg/provider/googleapps/u2f_test.go index 538c97252..6bf8b564b 100644 --- a/pkg/provider/googleapps/u2f_test.go +++ b/pkg/provider/googleapps/u2f_test.go @@ -9,9 +9,8 @@ import ( ) type fidoClientTests struct { - title string - client U2FClient - err error + title string + err error } type MockDeviceFinder struct { diff --git a/pkg/provider/http_test.go b/pkg/provider/http_test.go index 2c7479771..4cfe6c6e2 100644 --- a/pkg/provider/http_test.go +++ b/pkg/provider/http_test.go @@ -10,7 +10,7 @@ import ( func TestClientDoGetOK(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte("OK")) + _, _ = w.Write([]byte("OK")) })) defer ts.Close() @@ -33,7 +33,7 @@ func TestClientDoGetOK(t *testing.T) { func TestClientDisableRedirect(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(302) - w.Write([]byte("OK")) + _, _ = w.Write([]byte("OK")) })) defer ts.Close() @@ -56,7 +56,7 @@ func TestClientDisableRedirect(t *testing.T) { func TestClientDoResponseCheck(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(400) - w.Write([]byte("OK")) + _, _ = w.Write([]byte("OK")) })) defer ts.Close() diff --git a/pkg/provider/keycloak/keycloak.go b/pkg/provider/keycloak/keycloak.go index 9f60e83e1..8bedf03f1 100644 --- a/pkg/provider/keycloak/keycloak.go +++ b/pkg/provider/keycloak/keycloak.go @@ -82,7 +82,7 @@ func (kc *Client) getLoginForm(loginDetails *creds.LoginDetails) (string, url.Va return "", nil, errors.Wrap(err, "error retrieving form") } - doc, err := goquery.NewDocumentFromResponse(res) + doc, err := goquery.NewDocumentFromReader(res.Body) if err != nil { return "", nil, errors.Wrap(err, "failed to build document from response") } @@ -156,7 +156,7 @@ func (kc *Client) postTotpForm(totpSubmitURL string, mfaToken string, doc *goque return nil, errors.Wrap(err, "error retrieving content") } - doc, err = goquery.NewDocumentFromResponse(res) + doc, err = goquery.NewDocumentFromReader(res.Body) if err != nil { return nil, errors.Wrap(err, "error reading totp form response") } @@ -188,7 +188,7 @@ func extractSamlResponse(doc *goquery.Document) string { doc.Find("input").Each(func(i int, s *goquery.Selection) { name, ok := s.Attr("name") - if ( ok && name == "SAMLResponse" ) { + if ok && name == "SAMLResponse" { val, ok := s.Attr("value") if !ok { log.Fatalf("unable to locate saml assertion value") @@ -215,11 +215,7 @@ func containsTotpForm(doc *goquery.Document) bool { // search otp field at Keycloak >= 8.0.1 totpIndex = doc.Find("input#otp").Index() - if totpIndex != -1 { - return true - } - - return false + return totpIndex != -1 } func updateKeyCloakFormData(authForm url.Values, s *goquery.Selection, user *creds.LoginDetails) { diff --git a/pkg/provider/keycloak/keycloak_test.go b/pkg/provider/keycloak/keycloak_test.go index 37cdcb903..197c9cf33 100644 --- a/pkg/provider/keycloak/keycloak_test.go +++ b/pkg/provider/keycloak/keycloak_test.go @@ -27,7 +27,7 @@ func TestClient_getLoginForm(t *testing.T) { require.Nil(t, err) ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write(data) + _, _ = w.Write(data) })) defer ts.Close() @@ -56,12 +56,12 @@ func TestClient_getLoginFormRedirect(t *testing.T) { count := 0 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if count > 0 { - w.Write(data) + _, _ = w.Write(data) } else { w.WriteHeader(http.StatusUnauthorized) - w.Write(bytes.Replace(redirectData, []byte(exampleLoginURL), []byte("http://"+r.Host), 1)) + _, _ = w.Write(bytes.Replace(redirectData, []byte(exampleLoginURL), []byte("http://"+r.Host), 1)) } - count += 1 + count++ })) defer ts.Close() @@ -86,7 +86,7 @@ func TestClient_postLoginForm(t *testing.T) { require.Nil(t, err) ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write(data) + _, _ = w.Write(data) })) defer ts.Close() @@ -110,7 +110,7 @@ func TestClient_postTotpForm(t *testing.T) { require.Nil(t, err) ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write(data) + _, _ = w.Write(data) })) defer ts.Close() @@ -126,7 +126,8 @@ func TestClient_postTotpForm(t *testing.T) { opts := &provider.HTTPClientOptions{IsWithRetries: false} kc := Client{client: &provider.HTTPClient{Client: http.Client{}, Options: opts}} - kc.postTotpForm(ts.URL, mfaToken, doc) + _, err = kc.postTotpForm(ts.URL, mfaToken, doc) + require.Nil(t, err) pr.Mock.AssertCalled(t, "RequestSecurityCode", "000000") } @@ -137,7 +138,7 @@ func TestClient_postTotpFormWithProvidedMFAToken(t *testing.T) { require.Nil(t, err) ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write(data) + _, _ = w.Write(data) })) defer ts.Close() @@ -151,8 +152,8 @@ func TestClient_postTotpFormWithProvidedMFAToken(t *testing.T) { opts := &provider.HTTPClientOptions{IsWithRetries: false} kc := Client{client: &provider.HTTPClient{Client: http.Client{}, Options: opts}} - kc.postTotpForm(ts.URL, mfaToken, doc) - + _, err = kc.postTotpForm(ts.URL, mfaToken, doc) + require.Nil(t, err) pr.Mock.AssertNumberOfCalls(t, "RequestSecurityCode", 0) } diff --git a/pkg/provider/netiq/netiq.go b/pkg/provider/netiq/netiq.go index d49397c3b..b8fc6926d 100644 --- a/pkg/provider/netiq/netiq.go +++ b/pkg/provider/netiq/netiq.go @@ -2,6 +2,11 @@ package netiq import ( "fmt" + "net/http" + "net/url" + "regexp" + "strings" + "github.com/PuerkitoBio/goquery" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -10,10 +15,6 @@ import ( "github.com/versent/saml2aws/v2/pkg/page" "github.com/versent/saml2aws/v2/pkg/prompter" "github.com/versent/saml2aws/v2/pkg/provider" - "net/http" - "net/url" - "regexp" - "strings" ) var logger = logrus.WithField("provider", "NetIQ") diff --git a/pkg/provider/netiq/netiq_test.go b/pkg/provider/netiq/netiq_test.go index 1ed7d4eb1..6dddc201a 100644 --- a/pkg/provider/netiq/netiq_test.go +++ b/pkg/provider/netiq/netiq_test.go @@ -2,12 +2,13 @@ package netiq import ( "bytes" - "github.com/PuerkitoBio/goquery" - "github.com/stretchr/testify/require" - "github.com/versent/saml2aws/v2/pkg/page" "io/ioutil" "net/url" "testing" + + "github.com/PuerkitoBio/goquery" + "github.com/stretchr/testify/require" + "github.com/versent/saml2aws/v2/pkg/page" ) func TestIsSAMLResponsePositive(t *testing.T) { diff --git a/pkg/provider/okta/okta.go b/pkg/provider/okta/okta.go index 456ba6542..a3c51bd5d 100644 --- a/pkg/provider/okta/okta.go +++ b/pkg/provider/okta/okta.go @@ -172,7 +172,7 @@ func (oc *Client) follow(ctx context.Context, req *http.Request, loginDetails *c if err != nil { return "", errors.Wrap(err, "error following") } - doc, err := goquery.NewDocumentFromResponse(res) + doc, err := goquery.NewDocumentFromReader(res.Body) if err != nil { return "", errors.Wrap(err, "failed to build document from response") } @@ -482,7 +482,7 @@ func verifyMfa(oc *Client, oktaOrgHost string, loginDetails *creds.LoginDetails, } //try to extract sid - doc, err := goquery.NewDocumentFromResponse(res) + doc, err := goquery.NewDocumentFromReader(res.Body) if err != nil { return "", errors.Wrap(err, "error parsing document") } diff --git a/pkg/provider/okta/okta_test.go b/pkg/provider/okta/okta_test.go index f5b7bf87d..4eadaf56e 100644 --- a/pkg/provider/okta/okta_test.go +++ b/pkg/provider/okta/okta_test.go @@ -2,8 +2,9 @@ package okta import ( "errors" - "github.com/stretchr/testify/assert" "testing" + + "github.com/stretchr/testify/assert" ) type stateTokenTests struct { diff --git a/pkg/provider/onelogin/onelogin.go b/pkg/provider/onelogin/onelogin.go index a398b434c..6f8f44bde 100644 --- a/pkg/provider/onelogin/onelogin.go +++ b/pkg/provider/onelogin/onelogin.go @@ -284,7 +284,10 @@ func verifyMFA(oc *Client, oauthToken, appID, resp string) (string, error) { case IdentifierSmsMfa, IdentifierTotpMfa, IdentifierYubiKey: verifyCode := prompter.StringRequired("Enter verification code") var verifyBody bytes.Buffer - json.NewEncoder(&verifyBody).Encode(VerifyRequest{AppID: appID, DeviceID: mfaDeviceID, StateToken: stateToken, OTPToken: verifyCode}) + err := json.NewEncoder(&verifyBody).Encode(VerifyRequest{AppID: appID, DeviceID: mfaDeviceID, StateToken: stateToken, OTPToken: verifyCode}) + if err != nil { + return "", errors.Wrap(err, "error encoding body") + } req, err := http.NewRequest("POST", callbackURL, &verifyBody) if err != nil { return "", errors.Wrap(err, "error building token post request") diff --git a/pkg/provider/pingfed/pingfed.go b/pkg/provider/pingfed/pingfed.go index 342036af8..d84c7227b 100644 --- a/pkg/provider/pingfed/pingfed.go +++ b/pkg/provider/pingfed/pingfed.go @@ -68,7 +68,7 @@ func (ac *Client) follow(ctx context.Context, req *http.Request) (string, error) if err != nil { return "", errors.Wrap(err, "error following") } - doc, err := goquery.NewDocumentFromResponse(res) + doc, err := goquery.NewDocumentFromReader(res.Body) if err != nil { return "", errors.Wrap(err, "failed to build document from response") } diff --git a/pkg/provider/pingfed/pingfed_test.go b/pkg/provider/pingfed/pingfed_test.go index 4ca78935d..3d5897d23 100644 --- a/pkg/provider/pingfed/pingfed_test.go +++ b/pkg/provider/pingfed/pingfed_test.go @@ -80,7 +80,7 @@ func TestHandleLogin(t *testing.T) { doc, err := goquery.NewDocumentFromReader(bytes.NewReader(data)) require.Nil(t, err) - ctx, req, err := ac.handleLogin(ctx, doc) + _, req, err := ac.handleLogin(ctx, doc) require.Nil(t, err) b, err := ioutil.ReadAll(req.Body) diff --git a/pkg/provider/pingone/pingone.go b/pkg/provider/pingone/pingone.go index e327894ff..6d26b9e33 100644 --- a/pkg/provider/pingone/pingone.go +++ b/pkg/provider/pingone/pingone.go @@ -36,10 +36,10 @@ func SuccessOrRedirectOrUnauthorizedResponseValidator(req *http.Request, resp *h validatorResponse := provider.SuccessOrRedirectResponseValidator(req, resp) if validatorResponse == nil || resp.StatusCode == 401 { - return nil; + return nil } - return validatorResponse; + return validatorResponse } // New create a new PingOne client @@ -80,7 +80,7 @@ func (ac *Client) follow(ctx context.Context, req *http.Request) (string, error) return "", errors.Wrap(err, "error following") } - doc, err := goquery.NewDocumentFromResponse(res) + doc, err := goquery.NewDocumentFromReader(res.Body) if err != nil { return "", errors.Wrap(err, "failed to build document from response") } @@ -245,15 +245,6 @@ func (ac *Client) handleFormRedirect(ctx context.Context, doc *goquery.Document, return ctx, req, err } -func (ac *Client) handleFormSamlRequest(ctx context.Context, doc *goquery.Document, _ *http.Response) (context.Context, *http.Request, error) { - form, err := page.NewFormFromDocument(doc, "") - if err != nil { - return ctx, nil, errors.Wrap(err, "error extracting samlrequest form") - } - req, err := form.BuildRequest() - return ctx, req, err -} - func (ac *Client) handleRefresh(ctx context.Context, doc *goquery.Document, _ *http.Response) (context.Context, *http.Request, error) { loginDetails, ok := ctx.Value(ctxKey("login")).(*creds.LoginDetails) if !ok { diff --git a/pkg/provider/shell/shell.go b/pkg/provider/shell/shell.go index 31ed077a6..240ccee8b 100644 --- a/pkg/provider/shell/shell.go +++ b/pkg/provider/shell/shell.go @@ -37,7 +37,7 @@ func (oc *Client) Validate(ld *creds.LoginDetails) error { } const executableBits = 0o111 - if stat, err := os.Stat(ld.URL); os.IsNotExist(err) || ((stat.Mode() & executableBits) == 0) { + if stat, err := os.Stat(ld.URL); os.IsNotExist(err) || ((stat.Mode() & executableBits) == 0) { return errors.New("URL for shell provider does not point to a valid executable") } diff --git a/pkg/provider/shibboleth/shibboleth.go b/pkg/provider/shibboleth/shibboleth.go index fd6f8ad8b..cc1f53338 100644 --- a/pkg/provider/shibboleth/shibboleth.go +++ b/pkg/provider/shibboleth/shibboleth.go @@ -61,7 +61,7 @@ func (sc *Client) Authenticate(loginDetails *creds.LoginDetails) (string, error) return samlAssertion, errors.Wrap(err, "error retrieving form") } - doc, err := goquery.NewDocumentFromResponse(res) + doc, err := goquery.NewDocumentFromReader(res.Body) if err != nil { return samlAssertion, errors.Wrap(err, "failed to build document from response") } @@ -202,7 +202,7 @@ func verifyDuoMfa(oc *Client, duoHost string, parent string, tx string) (string, } // retrieve response from post - doc, err := goquery.NewDocumentFromResponse(res) + doc, err := goquery.NewDocumentFromReader(res.Body) if err != nil { return "", errors.Wrap(err, "error parsing document") } diff --git a/pkg/provider/shibbolethecp/shibbolethecp.go b/pkg/provider/shibbolethecp/shibbolethecp.go index e92be27cc..2c55908cf 100644 --- a/pkg/provider/shibbolethecp/shibbolethecp.go +++ b/pkg/provider/shibbolethecp/shibbolethecp.go @@ -109,7 +109,9 @@ func (c *Client) Authenticate(loginDetails *creds.LoginDetails) (string, error) } res, err := c.client.Do(req) - defer res.Body.Close() + defer func() { + _ = res.Body.Close() + }() if err != nil { return "", errors.Wrap(err, "Sending initial SOAP authnRequest") diff --git a/pkg/shell/env.go b/pkg/shell/env.go index 86282cce8..d33d2ad2d 100644 --- a/pkg/shell/env.go +++ b/pkg/shell/env.go @@ -3,6 +3,7 @@ package shell import ( "fmt" "time" + "github.com/versent/saml2aws/v2/pkg/awsconfig" "github.com/versent/saml2aws/v2/pkg/cfg" "github.com/versent/saml2aws/v2/pkg/flags" diff --git a/pkg/shell/shell_test.go b/pkg/shell/shell_test.go index 5b32676aa..096035fcf 100644 --- a/pkg/shell/shell_test.go +++ b/pkg/shell/shell_test.go @@ -2,8 +2,11 @@ package shell -import "testing" -import "github.com/stretchr/testify/assert" +import ( + "testing" + + "github.com/stretchr/testify/assert" +) func TestExecShellCmd(t *testing.T) { diff --git a/saml.go b/saml.go index 1bcef9ade..d3ee900d7 100644 --- a/saml.go +++ b/saml.go @@ -87,16 +87,16 @@ func ExtractDestinationURL(data []byte) (string, error) { return "", ErrMissingElement{Tag: responseTag} } - destination := rootElement.SelectAttrValue("Destination","none") + destination := rootElement.SelectAttrValue("Destination", "none") if destination == "none" { - // If Destination attribute is not found in Response (root) element, + // If Destination attribute is not found in Response (root) element, // get the Recipient attribute from the SubjectConfirmationData element. subjectConfirmationDataElement := doc.FindElement(".//SubjectConfirmationData") if subjectConfirmationDataElement == nil { return "", ErrMissingElement{Tag: responseTag} } - destination = subjectConfirmationDataElement.SelectAttrValue("Recipient","none") + destination = subjectConfirmationDataElement.SelectAttrValue("Recipient", "none") if destination == "none" { return "", ErrMissingElement{Tag: responseTag} } diff --git a/saml2aws.go b/saml2aws.go index 725e4d021..1b52fc0b9 100644 --- a/saml2aws.go +++ b/saml2aws.go @@ -31,7 +31,7 @@ type ProviderList map[string][]string // MFAsByProvider a list of providers with their respective supported MFAs var MFAsByProvider = ProviderList{ "AzureAD": []string{"Auto", "PhoneAppOTP", "PhoneAppNotification", "OneWaySMS"}, - "ADFS": []string{"Auto", "VIP", "Azure"}, + "ADFS": []string{"Auto", "VIP", "Azure", "Defender"}, "ADFS2": []string{"Auto", "RSA"}, // nothing automatic about ADFS 2.x "Ping": []string{"Auto"}, // automatically detects PingID "PingOne": []string{"Auto"}, // automatically detects PingID