Skip to content

Commit

Permalink
Merge pull request #892 from wakatime/bugfix/panic-transport-windows
Browse files Browse the repository at this point in the history
Catch panics when loading transport on Windows
  • Loading branch information
gandarez authored Aug 3, 2023
2 parents 33c48fd + f8fe7bf commit 543db96
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 39 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/on_push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
run: make vulncheck
-
name: Coverage
uses: codecov/codecov-action@v2
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
flags: unittests
Expand Down Expand Up @@ -189,6 +189,7 @@ jobs:
uses: ludeeus/action-shellcheck@master
with:
ignore_paths: 'bin/tests/libs'
ignore_names: govulncheck-with-excludes.sh
-
name: Setup bats
uses: mig4/setup-bats@v1
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ lint: install-linter
.PHONY: vulncheck
vulncheck:
go install golang.org/x/vuln/cmd/govulncheck@latest
govulncheck ./...
./bin/govulncheck-with-excludes.sh ./...

.PHONY: test
test:
Expand Down
67 changes: 67 additions & 0 deletions bin/govulncheck-with-excludes.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#!/usr/bin/env bash
set -Eeuo pipefail

# a wrapper / replacement for "govulncheck" which allows for excluding vulnerabilities
# (https://github.com/golang/go/issues/59507)

excludeVulns="$(jq -nc '[
# https://pkg.go.dev/vuln/GO-2023-1987
"GO-2023-1987",
empty # trailing comma hack (makes diffs smaller)
]')"
export excludeVulns

if ! command -v govulncheck > /dev/null; then
govulncheck() {
local user; user="$(id -u):$(id -g)"
local args=(
--rm --interactive --init
--user "$user"
--env HOME=/tmp
--env GOPATH=/tmp/go
--volume govulncheck:/tmp
--env CGO_ENABLED=0
--mount "type=bind,src=$PWD,dst=/wd,ro"
--workdir /wd
"${GOLANG_IMAGE:-golang:latest}"
sh -euc '
go install golang.org/x/vuln/cmd/govulncheck@latest > /dev/null
exec "$GOPATH/bin/govulncheck" "$@"
' --
)
docker run "${args[@]}" "$@"
}
fi

if out="$(govulncheck "$@")"; then
printf '%s\n' "$out"
exit 0
fi

json="$(govulncheck -json "$@")"

vulns="$(jq <<<"$json" -cs 'map(select(has("osv")) | .osv)')"
if [ "$(jq <<<"$vulns" -r 'length')" -le 0 ]; then
printf '%s\n' "$out"
exit 1
fi

filtered="$(jq <<<"$vulns" -c '
(env.excludeVulns | fromjson) as $exclude
| map(select(
.id as $id
| $exclude | index($id) | not
))
')"

text="$(jq <<<"$filtered" -r 'map("- \(.id) (aka \(.aliases | join(", ")))\n\n\t\(.details | gsub("\n"; "\n\t"))") | join("\n\n")')"

if [ -z "$text" ]; then
printf 'No vulnerabilities found.\n'
exit 0
else
printf '%s\n' "$text"
exit 1
fi
75 changes: 38 additions & 37 deletions pkg/api/transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,43 +9,8 @@ import (
"github.com/wakatime/wakatime-cli/pkg/log"
)

const serverName = "api.wakatime.com"

// NewTransport initializes a new http.Transport.
func NewTransport() *http.Transport {
return &http.Transport{
ForceAttemptHTTP2: true,
MaxConnsPerHost: 1,
MaxIdleConns: 1,
MaxIdleConnsPerHost: 1,
Proxy: nil,
TLSHandshakeTimeout: DefaultTimeoutSecs * time.Second,
}
}

// NewTransportWithHostVerificationDisabled initializes a new http.Transport with disabled host verification.
func NewTransportWithHostVerificationDisabled() *http.Transport {
t := NewTransport()

t.TLSClientConfig = &tls.Config{
MinVersion: tls.VersionTLS12,
RootCAs: CACerts(),
ServerName: serverName,
}

return t
}

// LazyCreateNewTransport uses the client's Transport if exists, or creates a new one.
func LazyCreateNewTransport(c *Client) *http.Transport {
if c != nil && c.client != nil && c.client.Transport != nil {
return c.client.Transport.(*http.Transport).Clone()
}

return NewTransport()
}

const letsencryptCerts string = `
const (
letsencryptCerts = `
-----BEGIN CERTIFICATE-----
MIIEYDCCAkigAwIBAgIQB55JKIY3b9QISMI/xjHkYzANBgkqhkiG9w0BAQsFADBP
MQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFy
Expand Down Expand Up @@ -118,6 +83,42 @@ mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
-----END CERTIFICATE-----
`
serverName = "api.wakatime.com"
)

// NewTransport initializes a new http.Transport.
func NewTransport() *http.Transport {
return &http.Transport{
ForceAttemptHTTP2: true,
MaxConnsPerHost: 1,
MaxIdleConns: 1,
MaxIdleConnsPerHost: 1,
Proxy: nil,
TLSHandshakeTimeout: DefaultTimeoutSecs * time.Second,
}
}

// NewTransportWithHostVerificationDisabled initializes a new http.Transport with disabled host verification.
func NewTransportWithHostVerificationDisabled() *http.Transport {
t := NewTransport()

t.TLSClientConfig = &tls.Config{
MinVersion: tls.VersionTLS12,
RootCAs: CACerts(),
ServerName: serverName,
}

return t
}

// LazyCreateNewTransport uses the client's Transport if exists, or creates a new one.
func LazyCreateNewTransport(c *Client) *http.Transport {
if c != nil && c.client != nil && c.client.Transport != nil {
return c.client.Transport.(*http.Transport).Clone()
}

return NewTransport()
}

// CACerts returns a root cert pool with the system's cacerts and LetsEncrypt's root certs.
func CACerts() *x509.CertPool {
Expand Down
9 changes: 9 additions & 0 deletions pkg/api/transport_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,20 @@ package api

import (
"crypto/x509"
"runtime/debug"
"syscall"
"unsafe"

"github.com/wakatime/wakatime-cli/pkg/log"
)

func loadSystemRoots() (*x509.CertPool, error) {
defer func() {
if err := recover(); err != nil {
log.Errorf("failed to load system roots on Windows. panicked: %v. Stack: %s", err, string(debug.Stack()))
}
}()

const cryptENotFound = 0x80092004

rootPtr, err := syscall.UTF16PtrFromString("ROOT")
Expand Down

0 comments on commit 543db96

Please sign in to comment.