dev: update linter (#1728)

- gofumpt everything
- fix TLS MinVersion to be at least 1.2
- add octal syntax
- remove newlines
- fix potential decompression bomb in ecjson
- remove implicit memory aliasing in for loops.

Signed-off-by: Bobby DeSimone <bobbydesimone@gmail.com>
This commit is contained in:
bobby 2020-12-30 09:02:57 -08:00 committed by GitHub
parent 5b18527fee
commit f837c92741
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
88 changed files with 373 additions and 409 deletions

View file

@ -1,163 +1,102 @@
# forked from istio
service:
# When updating this, also update bin/linters.sh accordingly
golangci-lint-version: 1.21.x # use the fixed version to not introduce new linters unexpectedly
run: run:
# timeout for analysis, e.g. 30s, 5m, default is 1m
deadline: 20m deadline: 20m
# which dirs to skip: they won't be analyzed; linters-settings:
# can use regexp here: generated.*, regexp is applied on full path; dupl:
# default value is empty list, but next dirs are always skipped independently threshold: 100
# from this option's value: funlen:
# vendor$, third_party$, testdata$, examples$, Godeps$, builtin$ lines: 100
skip-dirs: statements: 50
- genfiles$ gci:
- vendor$ local-prefixes: github.com/pomerium/pomerium
goconst:
# which files to skip: they will be analyzed, but issues from them min-len: 2
# won't be reported. Default value is empty list, but there is min-occurrences: 2
# no need to include all autogenerated files, we confidently recognize gocritic:
# autogenerated files. If it's not please let us know. enabled-tags:
skip-files: - diagnostic
- ".*\\.pb\\.go" - experimental
- ".*\\.gen\\.go" - opinionated
- performance
- style
disabled-checks:
- dupImport # https://github.com/go-critic/go-critic/issues/845
- ifElseChain
- octalLiteral
- whyNoLint
- wrapperFunc
gocyclo:
min-complexity: 15
goimports:
local-prefixes: github.com/pomerium/pomerium
golint:
min-confidence: 0
govet:
check-shadowing: false
lll:
line-length: 160
maligned:
suggest-new: true
misspell:
locale: US
nolintlint:
allow-leading-space: true # don't require machine-readable nolint directives (i.e. with no leading space)
allow-unused: false # report any unused nolint directives
require-explanation: false # don't require an explanation for nolint directives
require-specific: false # don't require nolint directives to be specific about which linter is being skipped
linters: linters:
enable-all: true disable-all: true
disable: enable:
- bodyclose
- deadcode
- depguard - depguard
- dupl - dogsled
- funlen - errcheck
- gochecknoglobals - gofmt
- gochecknoinits - goimports
- gocognit - golint
- goconst - goprintffuncname
- gocyclo - gosec
- godox - gosimple
- interfacer - govet
- maligned - ineffassign
- lll
- misspell
- nakedret - nakedret
- prealloc - nolintlint
- scopelint - rowserrcheck
- whitespace - staticcheck
- wsl - structcheck
fast: false - stylecheck
- typecheck
linters-settings: - unconvert
errcheck: - unparam
# report about not checking of errors in type assetions: `a := b.(MyStruct)`; - unused
# default is false: such cases aren't reported by default. - varcheck
check-type-assertions: false # - asciicheck
# - dupl
# report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`; # - exhaustive
# default is false: such cases aren't reported by default. # - funlen
check-blank: false # - gochecknoglobals
# - gochecknoinits
govet: # - gocognit
# report about shadowed variables # - goconst
check-shadowing: false # - gocritic
golint: # - gocyclo
# minimal confidence for issues, default is 0.8 # - godot
min-confidence: 0.8 # - godox
gofmt: # - goerr113
# simplify code: gofmt with `-s` option, true by default # - gomnd
simplify: true # - interfacer
misspell: # - maligned
# Correct spellings using locale preferences for US or UK. # - nestif
# Default is to use a neutral variety of English. # - noctx
# Setting locale to US will correct the British spelling of 'colour' to 'color'. # - prealloc
locale: US # - scopelint
lll: # - testpackage
# max line length, lines longer will be reported. Default is 120. # - whitespace
# '\t' is counted as 1 character by default, and can be changed with the tab-width option # - wsl
line-length: 160
# tab width in spaces. Default to 1.
tab-width: 1
goimports:
# put imports beginning with prefix after 3rd-party packages;
# it's a comma-separated list of prefixes
local-prefixes: github.com/pomerium/pomerium
unused:
# treat code as a program (not a library) and report unused exported identifiers; default is false.
# XXX: if you enable this setting, unused will report a lot of false-positives in text editors:
# if it's called for subdir of a project it can't find funcs usages. All text editor integrations
# with golangci-lint call it on a directory with the changed file.
check-exported: false
unparam:
# call graph construction algorithm (cha, rta). In general, use cha for libraries,
# and rta for programs with main packages. Default is cha.
algo: cha
# Inspect exported functions, default is false. Set to true if no external program/library imports your code.
# XXX: if you enable this setting, unparam will report a lot of false-positives in text editors:
# if it's called for subdir of a project it can't find external interfaces. All text editor integrations
# with golangci-lint call it on a directory with the changed file.
check-exported: false
gocritic:
enabled-checks:
- appendCombine
- argOrder
- assignOp
- badCond
- boolExprSimplify
- builtinShadow
- captLocal
- caseOrder
- codegenComment
- commentedOutCode
- commentedOutImport
- defaultCaseOrder
- deprecatedComment
- docStub
- dupArg
- dupBranchBody
- dupCase
- dupSubExpr
- elseif
- emptyFallthrough
- equalFold
- flagDeref
- flagName
- hexLiteral
- indexAlloc
- initClause
- methodExprCall
- nilValReturn
- offBy1
- rangeExprCopy
- regexpMust
- sloppyLen
- stringXbytes
- switchTrue
- typeAssertChain
- typeSwitchVar
- typeUnparen
- underef
- unlambda
- unnecessaryBlock
- unslice
- valSwap
- weakCond
- yodaStyleExpr
# Unused
# - appendAssign
# - commentFormatting
# - emptyStringTest
# - exitAfterDefer
# - ifElseChain
# - hugeParam
# - importShadow
# - nestingReduce
# - paramTypeCombine
# - ptrToRefParam
# - rangeValCopy
# - singleCaseSwitch
# - sloppyReassign
# - unlabelStmt
# - unnamedResult
# - wrapperFunc
issues: issues:
# List of regexps of issue texts to exclude, empty list by default. # List of regexps of issue texts to exclude, empty list by default.
@ -204,16 +143,26 @@ issues:
- "SA1019" - "SA1019"
exclude-rules: exclude-rules:
# https://github.com/go-critic/go-critic/issues/926
- linters:
- gocritic
text: "unnecessaryDefer:"
# Exclude some linters from running on test files. # Exclude some linters from running on test files.
- path: _test\.go$|^tests/|^integration/|^samples/|templates\.go$ - path: _test\.go$|^tests/|^integration/|^samples/|templates\.go$
linters: linters:
- errcheck
- maligned
- lll
- gosec
- bodyclose - bodyclose
- errcheck
- gomnd
- gosec
- lll
- maligned
- staticcheck
- unparam - unparam
- unused - unused
- scopelint
- gosec
- gosimple
# erroneously thinks google api url is a cred # erroneously thinks google api url is a cred
- path: internal/identity/google.go - path: internal/identity/google.go
text: "Potential hardcoded credentials" text: "Potential hardcoded credentials"
@ -228,14 +177,8 @@ issues:
text: "Potential hardcoded credentials" text: "Potential hardcoded credentials"
linters: linters:
- gosec - gosec
# Independently from option `exclude` we use default exclude patterns,
# it can be disabled by this option. To list all
# excluded by default patterns execute `golangci-lint run --help`.
# Default value for this option is true.
exclude-use-default: false
# Maximum issues count per one linter. Set to 0 to disable. Default is 50. # golangci.com configuration
max-per-linter: 0 # https://github.com/golangci/golangci/wiki/Configuration
service:
# Maximum count of issues with the same text. Set to 0 to disable. Default is 3. golangci-lint-version: 1.34.x # use the fixed version to not introduce new linters unexpectedly
max-same-issues: 0

View file

@ -32,10 +32,11 @@ GOOSARCHES = linux/amd64 darwin/amd64 windows/amd64
GOOS = $(shell $(GO) env GOOS) GOOS = $(shell $(GO) env GOOS)
GOARCH= $(shell $(GO) env GOARCH) GOARCH= $(shell $(GO) env GOARCH)
MISSPELL_VERSION = v0.3.4 MISSPELL_VERSION = v0.3.4
GOLANGCI_VERSION = v1.21.0 GOLANGCI_VERSION = v1.34.1
OPA_VERSION = v0.25.2 OPA_VERSION = v0.25.2
GETENVOY_VERSION = v0.2.0 GETENVOY_VERSION = v0.2.0
GORELEASER_VERSION = v0.150.0 GORELEASER_VERSION = v0.150.0
.PHONY: all .PHONY: all
all: clean build-deps test lint spellcheck build ## Runs a clean, build, fmt, lint, test, and vet. all: clean build-deps test lint spellcheck build ## Runs a clean, build, fmt, lint, test, and vet.

View file

@ -10,7 +10,6 @@ import (
) )
func newTestOptions(t *testing.T) *config.Options { func newTestOptions(t *testing.T) *config.Options {
opts := config.NewDefaultOptions() opts := config.NewDefaultOptions()
opts.AuthenticateURLString = "https://authenticate.example" opts.AuthenticateURLString = "https://authenticate.example"
opts.AuthorizeURLString = "https://authorize.example" opts.AuthorizeURLString = "https://authorize.example"

View file

@ -13,11 +13,12 @@ import (
"github.com/golang/protobuf/ptypes" "github.com/golang/protobuf/ptypes"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/pomerium/csrf"
"github.com/rs/cors" "github.com/rs/cors"
"golang.org/x/oauth2" "golang.org/x/oauth2"
"gopkg.in/square/go-jose.v2/jwt" "gopkg.in/square/go-jose.v2/jwt"
"github.com/pomerium/csrf"
"github.com/pomerium/pomerium/internal/httputil" "github.com/pomerium/pomerium/internal/httputil"
"github.com/pomerium/pomerium/internal/identity" "github.com/pomerium/pomerium/internal/identity"
"github.com/pomerium/pomerium/internal/identity/manager" "github.com/pomerium/pomerium/internal/identity/manager"

View file

@ -113,7 +113,6 @@ func TestAuthenticate_Handler(t *testing.T) {
if body == "" { if body == "" {
t.Errorf("handler returned unexpected body: got %v want %v", body, expected) t.Errorf("handler returned unexpected body: got %v want %v", body, expected)
} }
} }
func TestAuthenticate_SignIn(t *testing.T) { func TestAuthenticate_SignIn(t *testing.T) {
@ -593,6 +592,7 @@ func TestJwksEndpoint(t *testing.T) {
expected := "{\"keys\":[{\"use\":\"sig\",\"kty\":\"EC\",\"kid\":\"5b419ade1895fec2d2def6cd33b1b9a018df60db231dc5ecb85cbed6d942813c\",\"crv\":\"P-256\",\"alg\":\"ES256\",\"x\":\"UG5xCP0JTT1H6Iol8jKuTIPVLM04CgW9PlEypNRmWlo\",\"y\":\"KChF0fR09zm884ymInM29PtSsFdnzExNfLsP-ta1AgQ\"}]}\n" expected := "{\"keys\":[{\"use\":\"sig\",\"kty\":\"EC\",\"kid\":\"5b419ade1895fec2d2def6cd33b1b9a018df60db231dc5ecb85cbed6d942813c\",\"crv\":\"P-256\",\"alg\":\"ES256\",\"x\":\"UG5xCP0JTT1H6Iol8jKuTIPVLM04CgW9PlEypNRmWlo\",\"y\":\"KChF0fR09zm884ymInM29PtSsFdnzExNfLsP-ta1AgQ\"}]}\n"
assert.Equal(t, expected, body) assert.Equal(t, expected, body)
} }
func TestAuthenticate_Dashboard(t *testing.T) { func TestAuthenticate_Dashboard(t *testing.T) {
t.Parallel() t.Parallel()
@ -706,7 +706,6 @@ func TestAuthenticate_FrontchannelLogout(t *testing.T) {
}, },
get: func(ctx context.Context, in *databroker.GetRequest, opts ...grpc.CallOption) (*databroker.GetResponse, error) { get: func(ctx context.Context, in *databroker.GetRequest, opts ...grpc.CallOption) (*databroker.GetResponse, error) {
if !tt.widthSession { if !tt.widthSession {
return nil, nil return nil, nil
} }

View file

@ -18,39 +18,57 @@ func TestNew(t *testing.T) {
config config.Options config config.Options
wantErr bool wantErr bool
}{ }{
{"good", {
"good",
config.Options{ config.Options{
AuthenticateURL: mustParseURL("https://authN.example.com"), AuthenticateURL: mustParseURL("https://authN.example.com"),
DataBrokerURL: mustParseURL("https://cache.example.com"), DataBrokerURL: mustParseURL("https://cache.example.com"),
SharedKey: "2p/Wi2Q6bYDfzmoSEbKqYKtg+DUoLWTEHHs7vOhvL7w=", SharedKey: "2p/Wi2Q6bYDfzmoSEbKqYKtg+DUoLWTEHHs7vOhvL7w=",
Policies: policies}, Policies: policies,
false}, },
{"bad shared secret", false,
},
{
"bad shared secret",
config.Options{ config.Options{
AuthenticateURL: mustParseURL("https://authN.example.com"), AuthenticateURL: mustParseURL("https://authN.example.com"),
DataBrokerURL: mustParseURL("https://cache.example.com"), DataBrokerURL: mustParseURL("https://cache.example.com"),
SharedKey: "AZA85podM73CjLCjViDNz1EUvvejKpWp7Hysr0knXA==", SharedKey: "AZA85podM73CjLCjViDNz1EUvvejKpWp7Hysr0knXA==",
Policies: policies}, true}, Policies: policies,
{"really bad shared secret", },
true,
},
{
"really bad shared secret",
config.Options{ config.Options{
AuthenticateURL: mustParseURL("https://authN.example.com"), AuthenticateURL: mustParseURL("https://authN.example.com"),
DataBrokerURL: mustParseURL("https://cache.example.com"), DataBrokerURL: mustParseURL("https://cache.example.com"),
SharedKey: "sup", SharedKey: "sup",
Policies: policies}, true}, Policies: policies,
{"validation error, short secret", },
true,
},
{
"validation error, short secret",
config.Options{ config.Options{
AuthenticateURL: mustParseURL("https://authN.example.com"), AuthenticateURL: mustParseURL("https://authN.example.com"),
DataBrokerURL: mustParseURL("https://cache.example.com"), DataBrokerURL: mustParseURL("https://cache.example.com"),
SharedKey: "AZA85podM73CjLCjViDNz1EUvvejKpWp7Hysr0knXA==", SharedKey: "AZA85podM73CjLCjViDNz1EUvvejKpWp7Hysr0knXA==",
Policies: policies}, true}, Policies: policies,
},
true,
},
{"empty options", config.Options{}, true}, {"empty options", config.Options{}, true},
{"bad cache url", {
"bad cache url",
config.Options{ config.Options{
AuthenticateURL: mustParseURL("https://authN.example.com"), AuthenticateURL: mustParseURL("https://authN.example.com"),
DataBrokerURL: &url.URL{}, DataBrokerURL: &url.URL{},
SharedKey: "AZA85podM73CjLCjViDNz1EUvvejKpWp7Hysr0knXA==", SharedKey: "AZA85podM73CjLCjViDNz1EUvvejKpWp7Hysr0knXA==",
Policies: policies}, Policies: policies,
true}, },
true,
},
} }
for _, tt := range tests { for _, tt := range tests {
tt := tt tt := tt

View file

@ -50,7 +50,6 @@ func (a *Authorize) deniedResponse(
in *envoy_service_auth_v2.CheckRequest, in *envoy_service_auth_v2.CheckRequest,
code int32, reason string, headers map[string]string, code int32, reason string, headers map[string]string,
) *envoy_service_auth_v2.CheckResponse { ) *envoy_service_auth_v2.CheckResponse {
returnHTMLError := true returnHTMLError := true
inHeaders := in.GetAttributes().GetRequest().GetHttp().GetHeaders() inHeaders := in.GetAttributes().GetRequest().GetHttp().GetHeaders()
if inHeaders != nil { if inHeaders != nil {
@ -67,7 +66,6 @@ func (a *Authorize) htmlDeniedResponse(
in *envoy_service_auth_v2.CheckRequest, in *envoy_service_auth_v2.CheckRequest,
code int32, reason string, headers map[string]string, code int32, reason string, headers map[string]string,
) *envoy_service_auth_v2.CheckResponse { ) *envoy_service_auth_v2.CheckResponse {
opts := a.currentOptions.Load() opts := a.currentOptions.Load()
debugEndpoint := opts.GetAuthenticateURL().ResolveReference(&url.URL{Path: "/.pomerium/"}) debugEndpoint := opts.GetAuthenticateURL().ResolveReference(&url.URL{Path: "/.pomerium/"})

View file

@ -53,5 +53,4 @@ func TestCustomEvaluator(t *testing.T) {
} }
assert.NotNil(t, res) assert.NotNil(t, res)
}) })
} }

View file

@ -222,6 +222,7 @@ func (e *Evaluator) JWTPayload(req *Request) map[string]interface{} {
return payload return payload
} }
func newSigner(options *config.Options) (jose.Signer, *jose.JSONWebKey, error) { func newSigner(options *config.Options) (jose.Signer, *jose.JSONWebKey, error) {
// if we don't have a signing key, generate one // if we don't have a signing key, generate one
if options.SigningKey == "" { if options.SigningKey == "" {
@ -257,7 +258,6 @@ func newSigner(options *config.Options) (jose.Signer, *jose.JSONWebKey, error) {
Algorithm: jose.SignatureAlgorithm(jwk.Algorithm), Algorithm: jose.SignatureAlgorithm(jwk.Algorithm),
Key: jwk, Key: jwk,
}, signerOpt.WithHeader("kid", jwk.KeyID)) }, signerOpt.WithHeader("kid", jwk.KeyID))
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("couldn't create signer: %w", err) return nil, nil, fmt.Errorf("couldn't create signer: %w", err)
} }

View file

@ -71,14 +71,12 @@ type gcpTokenSourceKey struct {
audience string audience string
} }
var ( var gcpTokenSources = struct {
gcpTokenSources = struct {
sync.Mutex sync.Mutex
m map[gcpTokenSourceKey]oauth2.TokenSource m map[gcpTokenSourceKey]oauth2.TokenSource
}{ }{
m: make(map[gcpTokenSourceKey]oauth2.TokenSource), m: make(map[gcpTokenSourceKey]oauth2.TokenSource),
} }
)
func normalizeServiceAccount(serviceAccount string) (string, error) { func normalizeServiceAccount(serviceAccount string) (string, error) {
serviceAccount = strings.TrimSpace(serviceAccount) serviceAccount = strings.TrimSpace(serviceAccount)

View file

@ -111,7 +111,6 @@ func Test_getEvaluatorRequest(t *testing.T) {
} }
func Test_handleForwardAuth(t *testing.T) { func Test_handleForwardAuth(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
checkReq *envoy_service_auth_v2.CheckRequest checkReq *envoy_service_auth_v2.CheckRequest
@ -452,6 +451,7 @@ func TestSync(t *testing.T) {
}) })
} }
} }
func mustParseURL(str string) *url.URL { func mustParseURL(str string) *url.URL {
u, err := url.Parse(str) u, err := url.Parse(str)
if err != nil { if err != nil {
@ -492,7 +492,8 @@ func TestAuthorize_Check(t *testing.T) {
want *envoy_service_auth_v2.CheckResponse want *envoy_service_auth_v2.CheckResponse
wantErr bool wantErr bool
}{ }{
{"basic deny", {
"basic deny",
&envoy_service_auth_v2.CheckRequest{ &envoy_service_auth_v2.CheckRequest{
Attributes: &envoy_service_auth_v2.AttributeContext{ Attributes: &envoy_service_auth_v2.AttributeContext{
Source: &envoy_service_auth_v2.AttributeContext_Peer{ Source: &envoy_service_auth_v2.AttributeContext_Peer{
@ -520,8 +521,10 @@ func TestAuthorize_Check(t *testing.T) {
DeniedResponse: &envoy_service_auth_v2.DeniedHttpResponse{}, DeniedResponse: &envoy_service_auth_v2.DeniedHttpResponse{},
}, },
}, },
false}, false,
{"basic forward-auth deny", },
{
"basic forward-auth deny",
&envoy_service_auth_v2.CheckRequest{ &envoy_service_auth_v2.CheckRequest{
Attributes: &envoy_service_auth_v2.AttributeContext{ Attributes: &envoy_service_auth_v2.AttributeContext{
Source: &envoy_service_auth_v2.AttributeContext_Peer{ Source: &envoy_service_auth_v2.AttributeContext_Peer{
@ -543,11 +546,11 @@ func TestAuthorize_Check(t *testing.T) {
DeniedResponse: &envoy_service_auth_v2.DeniedHttpResponse{}, DeniedResponse: &envoy_service_auth_v2.DeniedHttpResponse{},
}, },
}, },
false}, false,
},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
got, err := a.Check(context.TODO(), tt.in) got, err := a.Check(context.TODO(), tt.in)
if (err != nil) != tt.wantErr { if (err != nil) != tt.wantErr {
t.Errorf("Authorize.Check() error = %v, wantErr %v", err, tt.wantErr) t.Errorf("Authorize.Check() error = %v, wantErr %v", err, tt.wantErr)
@ -557,7 +560,6 @@ func TestAuthorize_Check(t *testing.T) {
if diff := cmp.Diff(got, tt.want, cmpOpts...); diff != "" { if diff := cmp.Diff(got, tt.want, cmpOpts...); diff != "" {
t.Errorf("NewStore() = %s", diff) t.Errorf("NewStore() = %s", diff)
} }
}) })
} }
} }

View file

@ -17,7 +17,7 @@ func configHome() string {
} }
ch := filepath.Join(cfgDir, "pomerium-cli") ch := filepath.Join(cfgDir, "pomerium-cli")
err = os.MkdirAll(ch, 0755) err = os.MkdirAll(ch, 0o755)
if err != nil { if err != nil {
fatalf("error creating user config dir: %v", err) fatalf("error creating user config dir: %v", err)
} }
@ -69,7 +69,7 @@ func loadCachedCredential(serverURL string) *ExecCredential {
func saveCachedCredential(serverURL string, creds *ExecCredential) { func saveCachedCredential(serverURL string, creds *ExecCredential) {
fn := cachedCredentialPath(serverURL) fn := cachedCredentialPath(serverURL)
err := os.MkdirAll(filepath.Dir(fn), 0755) err := os.MkdirAll(filepath.Dir(fn), 0o755)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "failed to create cache directory: %v", err) fmt.Fprintf(os.Stderr, "failed to create cache directory: %v", err)
return return

View file

@ -10,8 +10,10 @@ import (
"github.com/pomerium/pomerium/internal/version" "github.com/pomerium/pomerium/internal/version"
) )
var versionFlag = flag.Bool("version", false, "prints the version") var (
var configFile = flag.String("config", "", "Specify configuration file location") versionFlag = flag.Bool("version", false, "prints the version")
configFile = flag.String("config", "", "Specify configuration file location")
)
func main() { func main() {
if err := run(context.Background()); err != nil { if err := run(context.Background()); err != nil {

View file

@ -42,7 +42,6 @@ func Test_isAuthenticate(t *testing.T) {
{"jiberish", "xd23", false}, {"jiberish", "xd23", false},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
if got := IsAuthenticate(tt.service); got != tt.want { if got := IsAuthenticate(tt.service); got != tt.want {
t.Errorf("isAuthenticate() = %v, want %v", got, tt.want) t.Errorf("isAuthenticate() = %v, want %v", got, tt.want)
@ -66,7 +65,6 @@ func Test_isAuthorize(t *testing.T) {
{"jiberish", "xd23", false}, {"jiberish", "xd23", false},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
if got := IsAuthorize(tt.service); got != tt.want { if got := IsAuthorize(tt.service); got != tt.want {
t.Errorf("isAuthenticate() = %v, want %v", got, tt.want) t.Errorf("isAuthenticate() = %v, want %v", got, tt.want)
@ -74,6 +72,7 @@ func Test_isAuthorize(t *testing.T) {
}) })
} }
} }
func Test_IsProxy(t *testing.T) { func Test_IsProxy(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
@ -87,7 +86,6 @@ func Test_IsProxy(t *testing.T) {
{"jiberish", "xd23", false}, {"jiberish", "xd23", false},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
if got := IsProxy(tt.service); got != tt.want { if got := IsProxy(tt.service); got != tt.want {
t.Errorf("IsProxy() = %v, want %v", got, tt.want) t.Errorf("IsProxy() = %v, want %v", got, tt.want)
@ -111,7 +109,6 @@ func Test_IsCache(t *testing.T) {
{"cache", "cache", true}, {"cache", "cache", true},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
if got := IsCache(tt.service); got != tt.want { if got := IsCache(tt.service); got != tt.want {
t.Errorf("IsCache() = %v, want %v", got, tt.want) t.Errorf("IsCache() = %v, want %v", got, tt.want)

View file

@ -36,6 +36,7 @@ func (t *httpTransport) update(options *Options) {
if err == nil { if err == nil {
nt.TLSClientConfig = &tls.Config{ nt.TLSClientConfig = &tls.Config{
RootCAs: rootCAs, RootCAs: rootCAs,
MinVersion: tls.VersionTLS12,
} }
} else { } else {
log.Error().Err(err).Msg("config: error getting cert pool") log.Error().Err(err).Msg("config: error getting cert pool")

View file

@ -418,7 +418,6 @@ func (o *Options) parseHeaders() error {
headerFields := strings.SplitN(headerSlice[n], ":", 2) headerFields := strings.SplitN(headerSlice[n], ":", 2)
if len(headerFields) == 2 { if len(headerFields) == 2 {
headers[headerFields[0]] = headerFields[1] headers[headerFields[0]] = headerFields[1]
} else { } else {
// Something went wrong // Something went wrong
return fmt.Errorf("failed to decode headers from '%s'", o.HeadersEnv) return fmt.Errorf("failed to decode headers from '%s'", o.HeadersEnv)

View file

@ -146,7 +146,6 @@ func Test_parseHeaders(t *testing.T) {
} }
}) })
} }
} }
func Test_parsePolicyFile(t *testing.T) { func Test_parsePolicyFile(t *testing.T) {
@ -188,7 +187,6 @@ func Test_parsePolicyFile(t *testing.T) {
t.Errorf("parsePolicyEnv() = diff:%s", diff) t.Errorf("parsePolicyEnv() = diff:%s", diff)
} }
} }
}) })
} }
} }
@ -227,7 +225,8 @@ func TestOptionsFromViper(t *testing.T) {
want *Options want *Options
wantErr bool wantErr bool
}{ }{
{"good", {
"good",
[]byte(`{"autocert_dir":"","insecure_server":true,"policy":[{"from": "https://from.example","to":"https://to.example"}]}`), []byte(`{"autocert_dir":"","insecure_server":true,"policy":[{"from": "https://from.example","to":"https://to.example"}]}`),
&Options{ &Options{
Policies: []Policy{{From: "https://from.example", To: "https://to.example"}}, Policies: []Policy{{From: "https://from.example", To: "https://to.example"}},
@ -248,8 +247,10 @@ func TestOptionsFromViper(t *testing.T) {
QPS: 1.0, QPS: 1.0,
DataBrokerStorageType: "memory", DataBrokerStorageType: "memory",
}, },
false}, false,
{"good disable header", },
{
"good disable header",
[]byte(`{"autocert_dir":"","insecure_server":true,"headers": {"disable":"true"},"policy":[{"from": "https://from.example","to":"https://to.example"}]}`), []byte(`{"autocert_dir":"","insecure_server":true,"headers": {"disable":"true"},"policy":[{"from": "https://from.example","to":"https://to.example"}]}`),
&Options{ &Options{
Policies: []Policy{{From: "https://from.example", To: "https://to.example"}}, Policies: []Policy{{From: "https://from.example", To: "https://to.example"}},
@ -266,7 +267,8 @@ func TestOptionsFromViper(t *testing.T) {
QPS: 1.0, QPS: 1.0,
DataBrokerStorageType: "memory", DataBrokerStorageType: "memory",
}, },
false}, false,
},
{"bad url", []byte(`{"policy":[{"from": "https://","to":"https://to.example"}]}`), nil, true}, {"bad url", []byte(`{"policy":[{"from": "https://","to":"https://to.example"}]}`), nil, true},
{"bad policy", []byte(`{"policy":[{"allow_public_unauthenticated_access": "dog","to":"https://to.example"}]}`), nil, true}, {"bad policy", []byte(`{"policy":[{"allow_public_unauthenticated_access": "dog","to":"https://to.example"}]}`), nil, true},
{"bad file", []byte(`{''''}`), nil, true}, {"bad file", []byte(`{''''}`), nil, true},
@ -358,7 +360,6 @@ func Test_AutoCertOptionsFromEnvVar(t *testing.T) {
if o.AutocertOptions.Folder != "/test" { if o.AutocertOptions.Folder != "/test" {
t.Errorf("o.AutocertOptions.Folder: want /test, got %s", o.AutocertOptions.Folder) t.Errorf("o.AutocertOptions.Folder: want /test, got %s", o.AutocertOptions.Folder)
} }
} }
func TestHTTPRedirectAddressStripQuotes(t *testing.T) { func TestHTTPRedirectAddressStripQuotes(t *testing.T) {
@ -440,7 +441,8 @@ func TestCompareByteSliceSlice(t *testing.T) {
{0, 1, 2, 3}, {0, 1, 2, 3},
}, },
}, },
{-1, {
-1,
Bytes{ Bytes{
{0, 1, 2, 3}, {0, 1, 2, 3},
}, },
@ -449,7 +451,8 @@ func TestCompareByteSliceSlice(t *testing.T) {
{4, 5, 6, 7}, {4, 5, 6, 7},
}, },
}, },
{1, {
1,
Bytes{ Bytes{
{0, 1, 2, 3}, {0, 1, 2, 3},
{4, 5, 6, 7}, {4, 5, 6, 7},

View file

@ -12,9 +12,7 @@ import (
) )
func main() { func main() {
var ( var certFile, keyFile, mutualAuthCAFile, bindAddr string
certFile, keyFile, mutualAuthCAFile, bindAddr string
)
flag.StringVar(&certFile, "cert-file", "", "the tls cert file to use") flag.StringVar(&certFile, "cert-file", "", "the tls cert file to use")
flag.StringVar(&keyFile, "key-file", "", "the tls key file to use") flag.StringVar(&keyFile, "key-file", "", "the tls key file to use")

View file

@ -10,9 +10,7 @@ import (
) )
func main() { func main() {
var ( var certFile, keyFile, bindAddr string
certFile, keyFile, bindAddr string
)
flag.StringVar(&certFile, "cert-file", "", "the tls cert file to use") flag.StringVar(&certFile, "cert-file", "", "the tls cert file to use")
flag.StringVar(&keyFile, "key-file", "", "the tls key file to use") flag.StringVar(&keyFile, "key-file", "", "the tls key file to use")

View file

@ -141,5 +141,4 @@ func TestHealth(t *testing.T) {
}) })
} }
} }
} }

View file

@ -29,14 +29,14 @@ type TLSCertsBundle struct {
func bootstrapCerts(ctx context.Context) (*TLSCertsBundle, error) { func bootstrapCerts(ctx context.Context) (*TLSCertsBundle, error) {
wd := filepath.Join(os.TempDir(), "pomerium-integration-tests", "certs") wd := filepath.Join(os.TempDir(), "pomerium-integration-tests", "certs")
err := os.MkdirAll(wd, 0755) err := os.MkdirAll(wd, 0o755)
if err != nil { if err != nil {
return nil, fmt.Errorf("error creating integration tests working directory: %w", err) return nil, fmt.Errorf("error creating integration tests working directory: %w", err)
} }
var bundle TLSCertsBundle var bundle TLSCertsBundle
var generators = []struct { generators := []struct {
certs *TLSCerts certs *TLSCerts
caroot string caroot string
install bool install bool
@ -48,7 +48,7 @@ func bootstrapCerts(ctx context.Context) (*TLSCertsBundle, error) {
} }
for _, generator := range generators { for _, generator := range generators {
err = os.MkdirAll(generator.caroot, 0755) err = os.MkdirAll(generator.caroot, 0o755)
if err != nil { if err != nil {
return nil, fmt.Errorf("error creating integration tests %s working directory: %w", return nil, fmt.Errorf("error creating integration tests %s working directory: %w",
filepath.Base(generator.caroot), err) filepath.Base(generator.caroot), err)

View file

@ -72,8 +72,10 @@ func (cluster *Cluster) Setup(ctx context.Context) error {
func (cluster *Cluster) GetNodePortAddr(ctx context.Context, namespace, svcName string) (hostport string, err error) { func (cluster *Cluster) GetNodePortAddr(ctx context.Context, namespace, svcName string) (hostport string, err error) {
var buf bytes.Buffer var buf bytes.Buffer
args := []string{"get", "service", "--namespace", namespace, "--output", "json", args := []string{
svcName} "get", "service", "--namespace", namespace, "--output", "json",
svcName,
}
err = run(ctx, "kubectl", withArgs(args...), withStdout(&buf)) err = run(ctx, "kubectl", withArgs(args...), withStdout(&buf))
if err != nil { if err != nil {
return "", fmt.Errorf("error getting service details with kubectl: %w", err) return "", fmt.Errorf("error getting service details with kubectl: %w", err)

View file

@ -46,5 +46,4 @@ func (d *localDialer) remapHost(ctx context.Context, hostport string) string {
} }
return dst return dst
} }

View file

@ -115,7 +115,6 @@ func TestPreserveHostHeader(t *testing.T) {
assert.NotEqual(t, "httpdetails.localhost.pomerium.io", result.Host, assert.NotEqual(t, "httpdetails.localhost.pomerium.io", result.Host,
"destination host should not be preserved in %v", result) "destination host should not be preserved in %v", result)
}) })
} }
func TestSetRequestHeaders(t *testing.T) { func TestSetRequestHeaders(t *testing.T) {
@ -146,7 +145,6 @@ func TestSetRequestHeaders(t *testing.T) {
assert.Equal(t, "custom-request-header-value", result.Headers["X-Custom-Request-Header"], assert.Equal(t, "custom-request-header-value", result.Headers["X-Custom-Request-Header"],
"expected custom request header to be sent upstream") "expected custom request header to be sent upstream")
} }
func TestRemoveRequestHeaders(t *testing.T) { func TestRemoveRequestHeaders(t *testing.T) {
@ -178,7 +176,6 @@ func TestRemoveRequestHeaders(t *testing.T) {
_, exist := result.Headers["X-Custom-Request-Header-To-Remove"] _, exist := result.Headers["X-Custom-Request-Header-To-Remove"]
assert.False(t, exist, "expected X-Custom-Request-Header-To-Remove not to be present.") assert.False(t, exist, "expected X-Custom-Request-Header-To-Remove not to be present.")
} }
func TestWebsocket(t *testing.T) { func TestWebsocket(t *testing.T) {

View file

@ -130,7 +130,7 @@ func TestConfig(t *testing.T) {
mockACME = newMockACME(srv) mockACME = newMockACME(srv)
tmpdir := filepath.Join(os.TempDir(), uuid.New().String()) tmpdir := filepath.Join(os.TempDir(), uuid.New().String())
_ = os.MkdirAll(tmpdir, 0755) _ = os.MkdirAll(tmpdir, 0o755)
defer os.RemoveAll(tmpdir) defer os.RemoveAll(tmpdir)
li, err := net.Listen("tcp", "127.0.0.1:0") li, err := net.Listen("tcp", "127.0.0.1:0")

View file

@ -44,7 +44,7 @@ func NewLocalJWTCache() (*LocalJWTCache, error) {
dir := filepath.Join(root, "pomerium-cli", "jwts") dir := filepath.Join(root, "pomerium-cli", "jwts")
err = os.MkdirAll(dir, 0755) err = os.MkdirAll(dir, 0o755)
if err != nil { if err != nil {
return nil, fmt.Errorf("error creating user cache directory: %w", err) return nil, fmt.Errorf("error creating user cache directory: %w", err)
} }
@ -81,7 +81,7 @@ func (cache *LocalJWTCache) LoadJWT(key string) (rawJWT string, err error) {
// StoreJWT stores a raw JWT in the local cache. // StoreJWT stores a raw JWT in the local cache.
func (cache *LocalJWTCache) StoreJWT(key string, rawJWT string) error { func (cache *LocalJWTCache) StoreJWT(key string, rawJWT string) error {
path := filepath.Join(cache.dir, cache.fileName(key)) path := filepath.Join(cache.dir, cache.fileName(key))
err := ioutil.WriteFile(path, []byte(rawJWT), 0600) err := ioutil.WriteFile(path, []byte(rawJWT), 0o600)
if err != nil { if err != nil {
return err return err
} }

View file

@ -19,7 +19,7 @@ func TestLocalJWTCache(t *testing.T) {
dir: filepath.Join(os.TempDir(), uuid.New().String()), dir: filepath.Join(os.TempDir(), uuid.New().String()),
} }
err := os.MkdirAll(c.dir, 0755) err := os.MkdirAll(c.dir, 0o755)
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
return return
} }

View file

@ -132,5 +132,5 @@ func (srv *Server) streamAggregatedResourcesOutgoingStep(
// DeltaAggregatedResources is not implemented. // DeltaAggregatedResources is not implemented.
func (srv *Server) DeltaAggregatedResources(in envoy_service_discovery_v3.AggregatedDiscoveryService_DeltaAggregatedResourcesServer) error { func (srv *Server) DeltaAggregatedResources(in envoy_service_discovery_v3.AggregatedDiscoveryService_DeltaAggregatedResourcesServer) error {
return fmt.Errorf("DeltaAggregatedResources not implemented") return fmt.Errorf("method DeltaAggregatedResources not implemented")
} }

View file

@ -143,14 +143,14 @@ func inlineBytesAsFilename(name string, bs []byte) *envoy_config_core_v3.DataSou
cacheDir = filepath.Join(os.TempDir()) cacheDir = filepath.Join(os.TempDir())
} }
cacheDir = filepath.Join(cacheDir, "pomerium", "envoy", "files") cacheDir = filepath.Join(cacheDir, "pomerium", "envoy", "files")
if err = os.MkdirAll(cacheDir, 0755); err != nil { if err = os.MkdirAll(cacheDir, 0o755); err != nil {
log.Error().Err(err).Msg("error creating cache directory, falling back to inline bytes") log.Error().Err(err).Msg("error creating cache directory, falling back to inline bytes")
return inlineBytes(bs) return inlineBytes(bs)
} }
fp := filepath.Join(cacheDir, name) fp := filepath.Join(cacheDir, name)
if _, err = os.Stat(fp); os.IsNotExist(err) { if _, err = os.Stat(fp); os.IsNotExist(err) {
err = ioutil.WriteFile(fp, bs, 0600) err = ioutil.WriteFile(fp, bs, 0o600)
if err != nil { if err != nil {
log.Error().Err(err).Msg("error writing cache file, falling back to inline bytes") log.Error().Err(err).Msg("error writing cache file, falling back to inline bytes")
return inlineBytes(bs) return inlineBytes(bs)
@ -227,7 +227,6 @@ func getRootCertificateAuthority() (string, error) {
log.Error().Strs("known-locations", knownRootLocations). log.Error().Strs("known-locations", knownRootLocations).
Msgf("no root certificates were found in any of the known locations") Msgf("no root certificates were found in any of the known locations")
} else { } else {
log.Info().Msgf("using %s as the system root certificate authority bundle", rootCABundle.value) log.Info().Msgf("using %s as the system root certificate authority bundle", rootCABundle.value)
} }
}) })

View file

@ -41,7 +41,8 @@ func (srv *Server) buildClusters(options *config.Options) []*envoy_config_cluste
clusters = append(clusters, buildInternalCluster(options, authzURL.Host, authzURL, true)) clusters = append(clusters, buildInternalCluster(options, authzURL.Host, authzURL, true))
if config.IsProxy(options.Services) { if config.IsProxy(options.Services) {
for _, policy := range options.Policies { for i := range options.Policies {
policy := options.Policies[i]
clusters = append(clusters, buildPolicyCluster(options, &policy)) clusters = append(clusters, buildPolicyCluster(options, &policy))
} }
} }

View file

@ -180,7 +180,8 @@ func buildPolicyRoutes(options *config.Options, domain string) []*envoy_config_r
var routes []*envoy_config_route_v3.Route var routes []*envoy_config_route_v3.Route
responseHeadersToAdd := toEnvoyHeaders(options.Headers) responseHeadersToAdd := toEnvoyHeaders(options.Headers)
for i, policy := range options.Policies { for i := range options.Policies {
policy := options.Policies[i]
if !hostMatchesDomain(policy.Source.URL, domain) { if !hostMatchesDomain(policy.Source.URL, domain) {
continue continue
} }

View file

@ -536,7 +536,6 @@ func Test_buildPolicyRoutes(t *testing.T) {
} }
] ]
`, routes) `, routes)
}) })
} }

View file

@ -19,9 +19,7 @@ import (
"github.com/pomerium/pomerium/pkg/grpc/databroker" "github.com/pomerium/pomerium/pkg/grpc/databroker"
) )
var ( var configTypeURL string
configTypeURL string
)
func init() { func init() {
any, _ := ptypes.MarshalAny(new(configpb.Config)) any, _ := ptypes.MarshalAny(new(configpb.Config))

View file

@ -275,7 +275,6 @@ func TestProvider_UserGroups(t *testing.T) {
listOptionMatcher{expected: management.IncludeTotals(true)}, listOptionMatcher{expected: management.IncludeTotals(true)},
listOptionMatcher{expected: management.Page(0)}, listOptionMatcher{expected: management.Page(0)},
).Return(&management.UserList{}, nil) ).Return(&management.UserList{}, nil)
}, },
expectedGroups: []*directory.Group{ expectedGroups: []*directory.Group{
{ {
@ -351,7 +350,6 @@ func TestProvider_UserGroups(t *testing.T) {
{ID: stringPtr("i-am-user-id-3")}, {ID: stringPtr("i-am-user-id-3")},
}, },
}, nil) }, nil)
}, },
expectedGroups: []*directory.Group{ expectedGroups: []*directory.Group{
{ {
@ -507,7 +505,6 @@ func TestProvider_UserGroups(t *testing.T) {
assert.Equal(t, expectedServiceAccount, mNewManagersFunc.CalledWithServiceAccount) assert.Equal(t, expectedServiceAccount, mNewManagersFunc.CalledWithServiceAccount)
}) })
} }
} }
func TestParseServiceAccount(t *testing.T) { func TestParseServiceAccount(t *testing.T) {
@ -517,7 +514,8 @@ func TestParseServiceAccount(t *testing.T) {
expectedServiceAccount *ServiceAccount expectedServiceAccount *ServiceAccount
expectedError error expectedError error
}{ }{
{"valid", "eyJjbGllbnRfaWQiOiJpLWFtLWNsaWVudC1pZCIsInNlY3JldCI6ImktYW0tc2VjcmV0In0K", {
"valid", "eyJjbGllbnRfaWQiOiJpLWFtLWNsaWVudC1pZCIsInNlY3JldCI6ImktYW0tc2VjcmV0In0K",
&ServiceAccount{ &ServiceAccount{
ClientID: "i-am-client-id", ClientID: "i-am-client-id",
Secret: "i-am-secret", Secret: "i-am-secret",

View file

@ -5,9 +5,10 @@
package mock_auth0 package mock_auth0
import ( import (
reflect "reflect"
gomock "github.com/golang/mock/gomock" gomock "github.com/golang/mock/gomock"
management "gopkg.in/auth0.v4/management" management "gopkg.in/auth0.v4/management"
reflect "reflect"
) )
// MockRoleManager is a mock of RoleManager interface // MockRoleManager is a mock of RoleManager interface

View file

@ -24,12 +24,10 @@ import (
// Name is the provider name. // Name is the provider name.
const Name = "github" const Name = "github"
var ( var defaultURL = &url.URL{
defaultURL = &url.URL{
Scheme: "https", Scheme: "https",
Host: "api.github.com", Host: "api.github.com",
} }
)
type config struct { type config struct {
httpClient *http.Client httpClient *http.Client

View file

@ -22,12 +22,10 @@ import (
// Name is the provider name. // Name is the provider name.
const Name = "gitlab" const Name = "gitlab"
var ( var defaultURL = &url.URL{
defaultURL = &url.URL{
Scheme: "https", Scheme: "https",
Host: "gitlab.com", Host: "gitlab.com",
} }
)
type config struct { type config struct {
httpClient *http.Client httpClient *http.Client

View file

@ -7,6 +7,7 @@ import (
"crypto/cipher" "crypto/cipher"
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"io" "io"
@ -14,6 +15,12 @@ import (
"github.com/pomerium/pomerium/pkg/cryptutil" "github.com/pomerium/pomerium/pkg/cryptutil"
) )
// 10mb reasonable default?
const maxMemory = int64(10 << 20)
// ErrMessageTooLarge is returned if the data is too large to be processed.
var ErrMessageTooLarge = errors.New("ecjson: message too large")
// EncryptedCompressedJSON implements SecureEncoder for JSON using an AEAD cipher. // EncryptedCompressedJSON implements SecureEncoder for JSON using an AEAD cipher.
// //
// See https://en.wikipedia.org/wiki/Authenticated_encryption // See https://en.wikipedia.org/wiki/Authenticated_encryption
@ -74,7 +81,6 @@ func (c *EncryptedCompressedJSON) Unmarshal(data []byte, s interface{}) error {
return err return err
} }
return nil return nil
} }
// compress gzips a set of bytes // compress gzips a set of bytes
@ -104,8 +110,12 @@ func decompress(data []byte) ([]byte, error) {
} }
defer reader.Close() defer reader.Close()
var buf bytes.Buffer var buf bytes.Buffer
if _, err = io.Copy(&buf, reader); err != nil { n, err := io.CopyN(&buf, reader, maxMemory+1)
if err != nil && err != io.EOF {
return nil, err return nil, err
} }
if n > maxMemory {
return nil, ErrMessageTooLarge
}
return buf.Bytes(), nil return buf.Bytes(), nil
} }

View file

@ -5,9 +5,11 @@ import (
"github.com/pomerium/pomerium/internal/encoding" "github.com/pomerium/pomerium/internal/encoding"
) )
var _ encoding.MarshalUnmarshaler = &Encoder{} var (
var _ encoding.Marshaler = &Encoder{} _ encoding.MarshalUnmarshaler = &Encoder{}
var _ encoding.Unmarshaler = &Encoder{} _ encoding.Marshaler = &Encoder{}
_ encoding.Unmarshaler = &Encoder{}
)
// Encoder MockCSRFStore is a mock implementation of Cipher. // Encoder MockCSRFStore is a mock implementation of Cipher.
type Encoder struct { type Encoder struct {

View file

@ -28,7 +28,7 @@ func extractEmbeddedEnvoy() (outPath string, err error) {
} }
defer rc.Close() defer rc.Close()
err = os.MkdirAll(embeddedFilesDirectory, 0755) err = os.MkdirAll(embeddedFilesDirectory, 0o755)
if err != nil { if err != nil {
return "", fmt.Errorf("error creating embedded file directory: (directory=%s): %w", embeddedFilesDirectory, err) return "", fmt.Errorf("error creating embedded file directory: (directory=%s): %w", embeddedFilesDirectory, err)
} }
@ -51,7 +51,7 @@ func extractEmbeddedEnvoy() (outPath string, err error) {
return "", fmt.Errorf("error extracting embedded envoy binary to temporary directory (path=%s): %w", outPath, err) return "", fmt.Errorf("error extracting embedded envoy binary to temporary directory (path=%s): %w", outPath, err)
} }
err = os.Chmod(outPath, 0755) err = os.Chmod(outPath, 0o755)
if err != nil { if err != nil {
return "", fmt.Errorf("error chmoding embedded envoy binary: %w", err) return "", fmt.Errorf("error chmoding embedded envoy binary: %w", err)
} }

View file

@ -65,7 +65,7 @@ type Server struct {
// NewServer creates a new server with traffic routed by envoy. // NewServer creates a new server with traffic routed by envoy.
func NewServer(src config.Source, grpcPort, httpPort string) (*Server, error) { func NewServer(src config.Source, grpcPort, httpPort string) (*Server, error) {
wd := filepath.Join(os.TempDir(), workingDirectoryName) wd := filepath.Join(os.TempDir(), workingDirectoryName)
err := os.MkdirAll(wd, 0755) err := os.MkdirAll(wd, 0o755)
if err != nil { if err != nil {
return nil, fmt.Errorf("error creating temporary working directory for envoy: %w", err) return nil, fmt.Errorf("error creating temporary working directory for envoy: %w", err)
} }

View file

@ -6,7 +6,6 @@ import (
) )
func TestIsReadableFile(t *testing.T) { func TestIsReadableFile(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
args string args string

View file

@ -17,20 +17,26 @@ func TestHash(t *testing.T) {
}{ }{
{"string", "string", 6134271061086542852, false}, {"string", "string", 6134271061086542852, false},
{"num", 7, 609900476111905877, false}, {"num", 7, 609900476111905877, false},
{"compound struct", struct { {
"compound struct",
struct {
NESCarts []string NESCarts []string
numberOfCarts int numberOfCarts int
}{ }{
[]string{"Battletoads", "Mega Man 1", "Clash at Demonhead"}, []string{"Battletoads", "Mega Man 1", "Clash at Demonhead"},
12, 12,
}, },
1349584765528830812, false}, 1349584765528830812, false,
{"compound struct with embedded func (errors!)", struct { },
{
"compound struct with embedded func (errors!)",
struct {
AnswerToEverythingFn func() int AnswerToEverythingFn func() int
}{ }{
func() int { return 42 }, func() int { return 42 },
}, },
0, true}, 0, true,
},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {

View file

@ -10,8 +10,10 @@ import (
"github.com/pomerium/pomerium/internal/version" "github.com/pomerium/pomerium/internal/version"
) )
var errorTemplate = template.Must(frontend.NewTemplates()) var (
var fullVersion = version.FullVersion() errorTemplate = template.Must(frontend.NewTemplates())
fullVersion = version.FullVersion()
)
// HTTPError contains an HTTP status code and wrapped error. // HTTPError contains an HTTP status code and wrapped error.
type HTTPError struct { type HTTPError struct {

View file

@ -10,7 +10,6 @@ import (
) )
func TestHTTPError_ErrorResponse(t *testing.T) { func TestHTTPError_ErrorResponse(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
Status int Status int
@ -46,7 +45,6 @@ func TestHTTPError_ErrorResponse(t *testing.T) {
t.Errorf("ErrorResponse status:\n %s", diff) t.Errorf("ErrorResponse status:\n %s", diff)
} }
} }
}) })
} }
} }
@ -69,7 +67,6 @@ func TestNewError(t *testing.T) {
if err != nil && !errors.Is(err, tt.err) { if err != nil && !errors.Is(err, tt.err) {
t.Errorf("NewError() unwrap fail = %v, wantErr %v", err, tt.wantErr) t.Errorf("NewError() unwrap fail = %v, wantErr %v", err, tt.wantErr)
} }
}) })
} }
} }

View file

@ -28,7 +28,6 @@ func TestHealthCheck(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
r := httptest.NewRequest(tt.method, "/", nil) r := httptest.NewRequest(tt.method, "/", nil)
w := httptest.NewRecorder() w := httptest.NewRecorder()
@ -56,7 +55,6 @@ func TestRedirect(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
r := httptest.NewRequest(tt.method, "/", nil) r := httptest.NewRequest(tt.method, "/", nil)
w := httptest.NewRecorder() w := httptest.NewRecorder()
@ -72,7 +70,6 @@ func TestRedirect(t *testing.T) {
} }
func TestHandlerFunc_ServeHTTP(t *testing.T) { func TestHandlerFunc_ServeHTTP(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
f HandlerFunc f HandlerFunc
@ -95,7 +92,6 @@ func TestHandlerFunc_ServeHTTP(t *testing.T) {
} }
func TestRenderJSON(t *testing.T) { func TestRenderJSON(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
code int code int
@ -103,7 +99,8 @@ func TestRenderJSON(t *testing.T) {
wantBody string wantBody string
wantCode int wantCode int
}{ }{
{"simple", {
"simple",
http.StatusTeapot, http.StatusTeapot,
struct { struct {
A string A string
@ -117,7 +114,8 @@ func TestRenderJSON(t *testing.T) {
"{\"A\":\"A\",\"B\":\"B\",\"C\":1}\n", "{\"A\":\"A\",\"B\":\"B\",\"C\":1}\n",
http.StatusTeapot, http.StatusTeapot,
}, },
{"map", {
"map",
http.StatusOK, http.StatusOK,
map[string]interface{}{ map[string]interface{}{
"C": 1, // notice order does not matter "C": 1, // notice order does not matter
@ -127,12 +125,14 @@ func TestRenderJSON(t *testing.T) {
// alphabetical // alphabetical
"{\"A\":\"A\",\"B\":\"B\",\"C\":1}\n", http.StatusOK, "{\"A\":\"A\",\"B\":\"B\",\"C\":1}\n", http.StatusOK,
}, },
{"bad!", {
"bad!",
http.StatusOK, http.StatusOK,
map[string]interface{}{ map[string]interface{}{
"BAD BOI": math.Inf(1), "BAD BOI": math.Inf(1),
}, },
`{"error":"json: unsupported value: +Inf"}`, http.StatusInternalServerError}, `{"error":"json: unsupported value: +Inf"}`, http.StatusInternalServerError,
},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {

View file

@ -4,6 +4,7 @@ import (
"net/http" "net/http"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/pomerium/csrf" "github.com/pomerium/csrf"
) )

View file

@ -18,7 +18,6 @@ import (
) )
func TestNewServer(t *testing.T) { func TestNewServer(t *testing.T) {
// to support envs that won't let us use 443 without root // to support envs that won't let us use 443 without root
defaultServerOptions.Addr = ":0" defaultServerOptions.Addr = ":0"
@ -31,7 +30,8 @@ func TestNewServer(t *testing.T) {
wantErr bool wantErr bool
}{ }{
{"good basic http handler", {
"good basic http handler",
&ServerOptions{ &ServerOptions{
Addr: ":0", Addr: ":0",
Insecure: true, Insecure: true,
@ -39,45 +39,56 @@ func TestNewServer(t *testing.T) {
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello, http") fmt.Fprintln(w, "Hello, http")
}), }),
false}, false,
{"bad neither insecure nor certs set", },
{
"bad neither insecure nor certs set",
&ServerOptions{ &ServerOptions{
Addr: ":0", Addr: ":0",
}, },
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello, http") fmt.Fprintln(w, "Hello, http")
}), }),
true}, true,
{"good no address", },
{
"good no address",
&ServerOptions{ &ServerOptions{
Insecure: true, Insecure: true,
}, },
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello, http") fmt.Fprintln(w, "Hello, http")
}), }),
false}, false,
{"empty handler", },
{
"empty handler",
nil, nil,
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello, http") fmt.Fprintln(w, "Hello, http")
}), }),
true}, true,
{"bad port - invalid port range ", },
{
"bad port - invalid port range ",
&ServerOptions{ &ServerOptions{
Addr: ":65536", Addr: ":65536",
Insecure: true, Insecure: true,
}, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { }, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello, http") fmt.Fprintln(w, "Hello, http")
}), }),
true}, true,
{"good tls set", },
{
"good tls set",
&ServerOptions{ &ServerOptions{
TLSConfig: &tls.Config{}, TLSConfig: &tls.Config{},
}, },
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello, http") fmt.Fprintln(w, "Hello, http")
}), }),
false}, false,
},
} }
for _, tt := range tests { for _, tt := range tests {
@ -113,10 +124,10 @@ func TestNewServer(t *testing.T) {
syscall.Kill(syscall.Getpid(), syscall.SIGINT) syscall.Kill(syscall.Getpid(), syscall.SIGINT)
waitSig(t, c, syscall.SIGINT) waitSig(t, c, syscall.SIGINT)
} }
}) })
} }
} }
func waitSig(t *testing.T, c <-chan os.Signal, sig os.Signal) { func waitSig(t *testing.T, c <-chan os.Signal, sig os.Signal) {
select { select {
case s := <-c: case s := <-c:

View file

@ -41,7 +41,6 @@ func ExampleWith() {
sublog := log.With().Str("foo", "bar").Logger() sublog := log.With().Str("foo", "bar").Logger()
sublog.Debug().Msg("hello world") sublog.Debug().Msg("hello world")
// Output: {"level":"debug","foo":"bar","time":1199811905,"message":"hello world"} // Output: {"level":"debug","foo":"bar","time":1199811905,"message":"hello world"}
} }
// Simple logging example using the Printf function in the log package // Simple logging example using the Printf function in the log package

View file

@ -292,6 +292,7 @@ func TestLogHeadersHandler(t *testing.T) {
t.Errorf("Invalid log output, got: %s, want: %s", got, want) t.Errorf("Invalid log output, got: %s, want: %s", got, want)
} }
} }
func TestAccessHandler(t *testing.T) { func TestAccessHandler(t *testing.T) {
out := &bytes.Buffer{} out := &bytes.Buffer{}
@ -300,7 +301,6 @@ func TestAccessHandler(t *testing.T) {
h := AccessHandler(func(r *http.Request, status, size int, duration time.Duration) { h := AccessHandler(func(r *http.Request, status, size int, duration time.Duration) {
l := FromRequest(r) l := FromRequest(r)
l.Log().Int("status", status).Int("size", size).Msg("info") l.Log().Int("status", status).Int("size", size).Msg("info")
})(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { })(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
l := FromRequest(r) l := FromRequest(r)
l.Log().Msg("some inner logging") l.Log().Msg("some inner logging")
@ -316,5 +316,4 @@ func TestAccessHandler(t *testing.T) {
if diff := cmp.Diff(want, got); diff != "" { if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("TestAccessHandler: %s", diff) t.Errorf("TestAccessHandler: %s", diff)
} }
} }

View file

@ -32,7 +32,6 @@ func TestSetHeaders(t *testing.T) {
if got := w.Header().Get(k); want != got { if got := w.Header().Get(k); want != got {
t.Errorf("want %s got %q", want, got) t.Errorf("want %s got %q", want, got)
} }
} }
}) })
rr := httptest.NewRecorder() rr := httptest.NewRecorder()
@ -80,7 +79,6 @@ func TestStripCookie(t *testing.T) {
handler := StripCookie(tt.pomeriumCookie)(testHandler) handler := StripCookie(tt.pomeriumCookie)(testHandler)
handler.ServeHTTP(rr, req) handler.ServeHTTP(rr, req)
}) })
} }
} }

View file

@ -162,10 +162,12 @@ func (f *httpFancyWriter) ReadFrom(r io.Reader) (int64, error) {
return n, err return n, err
} }
var _ http.Flusher = &httpFancyWriter{} var (
var _ http.Hijacker = &httpFancyWriter{} _ http.Flusher = &httpFancyWriter{}
var _ http.Pusher = &http2FancyWriter{} _ http.Hijacker = &httpFancyWriter{}
var _ io.ReaderFrom = &httpFancyWriter{} _ http.Pusher = &http2FancyWriter{}
_ io.ReaderFrom = &httpFancyWriter{}
)
// http2FancyWriter is a HTTP2 writer that additionally satisfies // http2FancyWriter is a HTTP2 writer that additionally satisfies
// http.Flusher, and io.ReaderFrom. It exists for the common case // http.Flusher, and io.ReaderFrom. It exists for the common case

View file

@ -12,8 +12,10 @@ import (
"github.com/pomerium/pomerium/internal/sessions" "github.com/pomerium/pomerium/internal/sessions"
) )
var _ sessions.SessionStore = &Store{} var (
var _ sessions.SessionLoader = &Store{} _ sessions.SessionStore = &Store{}
_ sessions.SessionLoader = &Store{}
)
// timeNow is time.Now but pulled out as a variable for tests. // timeNow is time.Now but pulled out as a variable for tests.
var timeNow = time.Now var timeNow = time.Now

View file

@ -56,6 +56,7 @@ func TestNewStore(t *testing.T) {
}) })
} }
} }
func TestNewCookieLoader(t *testing.T) { func TestNewCookieLoader(t *testing.T) {
cipher, err := cryptutil.NewAEADCipher(cryptutil.NewKey()) cipher, err := cryptutil.NewAEADCipher(cryptutil.NewKey())
if err != nil { if err != nil {

View file

@ -97,7 +97,6 @@ func TestVerifier(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
r := httptest.NewRequest(http.MethodGet, "/", nil) r := httptest.NewRequest(http.MethodGet, "/", nil)
r.Header.Set("Accept", "application/json") r.Header.Set("Accept", "application/json")
w := httptest.NewRecorder() w := httptest.NewRecorder()

View file

@ -9,8 +9,10 @@ import (
"github.com/pomerium/pomerium/internal/sessions" "github.com/pomerium/pomerium/internal/sessions"
) )
var _ sessions.SessionStore = &Store{} var (
var _ sessions.SessionLoader = &Store{} _ sessions.SessionStore = &Store{}
_ sessions.SessionLoader = &Store{}
)
// Store is a mock implementation of the SessionStore interface // Store is a mock implementation of the SessionStore interface
type Store struct { type Store struct {

View file

@ -17,7 +17,8 @@ func TestStore(t *testing.T) {
wantLoadErr bool wantLoadErr bool
wantSaveErr bool wantSaveErr bool
}{ }{
{"basic", {
"basic",
&Store{ &Store{
ResponseSession: "test", ResponseSession: "test",
Session: &sessions.State{Subject: "0101"}, Session: &sessions.State{Subject: "0101"},
@ -27,7 +28,8 @@ func TestStore(t *testing.T) {
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwcm9ncmFtYXRpYyI6ZmFsc2UsInN1YiI6IjAxMDEifQ.xQQPXGN3q3j_CHbz6p9D-vZ1DaiPWwKdQhNxNHoYzvM", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwcm9ncmFtYXRpYyI6ZmFsc2UsInN1YiI6IjAxMDEifQ.xQQPXGN3q3j_CHbz6p9D-vZ1DaiPWwKdQhNxNHoYzvM",
&sessions.State{Subject: "0101"}, &sessions.State{Subject: "0101"},
false, false,
false}, false,
},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {

View file

@ -9,8 +9,10 @@ import (
"github.com/pomerium/pomerium/internal/sessions" "github.com/pomerium/pomerium/internal/sessions"
) )
var _ sessions.SessionStore = &Store{} var (
var _ sessions.SessionLoader = &Store{} _ sessions.SessionStore = &Store{}
_ sessions.SessionLoader = &Store{}
)
const ( const (
defaultQueryParamKey = "pomerium_session" defaultQueryParamKey = "pomerium_session"

View file

@ -14,7 +14,6 @@ import (
) )
func TestNewQueryParamStore(t *testing.T) { func TestNewQueryParamStore(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
State *sessions.State State *sessions.State

View file

@ -23,7 +23,6 @@ type GRPCServerStatsHandler struct {
// TagRPC implements grpc.stats.Handler and adds metrics and tracing metadata to the context of a given RPC // TagRPC implements grpc.stats.Handler and adds metrics and tracing metadata to the context of a given RPC
func (h *GRPCServerStatsHandler) TagRPC(ctx context.Context, tagInfo *grpcstats.RPCTagInfo) context.Context { func (h *GRPCServerStatsHandler) TagRPC(ctx context.Context, tagInfo *grpcstats.RPCTagInfo) context.Context {
handledCtx := h.Handler.TagRPC(ctx, tagInfo) handledCtx := h.Handler.TagRPC(ctx, tagInfo)
metricCtx := h.metricsHandler.TagRPC(handledCtx, tagInfo) metricCtx := h.metricsHandler.TagRPC(handledCtx, tagInfo)

View file

@ -21,7 +21,6 @@ func (m *mockTagHandler) TagRPC(ctx context.Context, tagInfo *grpcstats.RPCTagIn
} }
func Test_GRPCServerStatsHandler(t *testing.T) { func Test_GRPCServerStatsHandler(t *testing.T) {
metricsHandler := &mockTagHandler{} metricsHandler := &mockTagHandler{}
h := &GRPCServerStatsHandler{ h := &GRPCServerStatsHandler{
metricsHandler: metricsHandler, metricsHandler: metricsHandler,

View file

@ -8,12 +8,10 @@ import (
// HTTPStatsRoundTripper creates tracing and metrics RoundTripper for a pomerium service // HTTPStatsRoundTripper creates tracing and metrics RoundTripper for a pomerium service
func HTTPStatsRoundTripper(service string, destination string) func(next http.RoundTripper) http.RoundTripper { func HTTPStatsRoundTripper(service string, destination string) func(next http.RoundTripper) http.RoundTripper {
return metrics.HTTPMetricsRoundTripper(ServiceName(service), destination) return metrics.HTTPMetricsRoundTripper(ServiceName(service), destination)
} }
// HTTPStatsHandler creates tracing and metrics Handler for a pomerium service // HTTPStatsHandler creates tracing and metrics Handler for a pomerium service
func HTTPStatsHandler(service string) func(next http.Handler) http.Handler { func HTTPStatsHandler(service string) func(next http.Handler) http.Handler {
return metrics.HTTPMetricsHandler(ServiceName(service)) return metrics.HTTPMetricsHandler(ServiceName(service))
} }

View file

@ -20,13 +20,15 @@ var (
GRPCClientRequestCountView, GRPCClientRequestCountView,
GRPCClientRequestDurationView, GRPCClientRequestDurationView,
GRPCClientResponseSizeView, GRPCClientResponseSizeView,
GRPCClientRequestSizeView} GRPCClientRequestSizeView,
}
// GRPCServerViews contains opencensus views for GRPC Server metrics. // GRPCServerViews contains opencensus views for GRPC Server metrics.
GRPCServerViews = []*view.View{ GRPCServerViews = []*view.View{
GRPCServerRequestCountView, GRPCServerRequestCountView,
GRPCServerRequestDurationView, GRPCServerRequestDurationView,
GRPCServerResponseSizeView, GRPCServerResponseSizeView,
GRPCServerRequestSizeView} GRPCServerRequestSizeView,
}
// GRPCServerRequestCountView is an OpenCensus view which counts GRPC Server // GRPCServerRequestCountView is an OpenCensus view which counts GRPC Server
// requests by pomerium service, grpc service, grpc method, and status // requests by pomerium service, grpc service, grpc method, and status
@ -123,7 +125,6 @@ func GRPCClientInterceptor(service string) grpc.UnaryClientInterceptor {
cc *grpc.ClientConn, cc *grpc.ClientConn,
invoker grpc.UnaryInvoker, invoker grpc.UnaryInvoker,
opts ...grpc.CallOption) error { opts ...grpc.CallOption) error {
// Split the method into parts for better slicing // Split the method into parts for better slicing
rpcInfo := strings.SplitN(method, "/", 3) rpcInfo := strings.SplitN(method, "/", 3)
var rpcMethod string var rpcMethod string
@ -148,7 +149,6 @@ func GRPCClientInterceptor(service string) grpc.UnaryClientInterceptor {
// Calls the invoker to execute RPC // Calls the invoker to execute RPC
return invoker(taggedCtx, method, req, reply, cc, opts...) return invoker(taggedCtx, method, req, reply, cc, opts...)
} }
} }
// GRPCServerMetricsHandler implements a telemetry tagRPCHandler methods for metrics // GRPCServerMetricsHandler implements a telemetry tagRPCHandler methods for metrics
@ -163,7 +163,6 @@ func NewGRPCServerMetricsHandler(service string) *GRPCServerMetricsHandler {
// TagRPC handles adding any metrics related values to the incoming context // TagRPC handles adding any metrics related values to the incoming context
func (h *GRPCServerMetricsHandler) TagRPC(ctx context.Context, tagInfo *grpcstats.RPCTagInfo) context.Context { func (h *GRPCServerMetricsHandler) TagRPC(ctx context.Context, tagInfo *grpcstats.RPCTagInfo) context.Context {
// Split the method into parts for better slicing // Split the method into parts for better slicing
rpcInfo := strings.SplitN(tagInfo.FullMethodName, "/", 3) rpcInfo := strings.SplitN(tagInfo.FullMethodName, "/", 3)
var rpcMethod string var rpcMethod string

View file

@ -55,8 +55,8 @@ func newTestCC(t *testing.T) *grpc.ClientConn {
} }
return testCC return testCC
} }
func Test_GRPCClientInterceptor(t *testing.T) {
func Test_GRPCClientInterceptor(t *testing.T) {
interceptor := GRPCClientInterceptor("test_service") interceptor := GRPCClientInterceptor("test_service")
tests := []struct { tests := []struct {
@ -99,7 +99,6 @@ func Test_GRPCClientInterceptor(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
view.Unregister(GRPCClientViews...) view.Unregister(GRPCClientViews...)
view.Register(GRPCClientViews...) view.Register(GRPCClientViews...)
@ -115,7 +114,6 @@ func Test_GRPCClientInterceptor(t *testing.T) {
testDataRetrieval(GRPCClientRequestDurationView, t, tt.wantgrpcClientRequestDuration) testDataRetrieval(GRPCClientRequestDurationView, t, tt.wantgrpcClientRequestDuration)
testDataRetrieval(GRPCClientRequestCountView, t, tt.wantgrpcClientRequestCount) testDataRetrieval(GRPCClientRequestCountView, t, tt.wantgrpcClientRequestCount)
testDataRetrieval(GRPCClientRequestSizeView, t, tt.wantgrpcClientRequestSize) testDataRetrieval(GRPCClientRequestSizeView, t, tt.wantgrpcClientRequestSize)
}) })
} }
} }
@ -128,8 +126,8 @@ func mockServerRPCHandle(metricsHandler *GRPCServerMetricsHandler, method string
statsHandler.HandleRPC(ctx, &stats.InPayload{Client: false, Length: len(message)}) statsHandler.HandleRPC(ctx, &stats.InPayload{Client: false, Length: len(message)})
statsHandler.HandleRPC(ctx, &stats.OutPayload{Client: false, Length: len(message)}) statsHandler.HandleRPC(ctx, &stats.OutPayload{Client: false, Length: len(message)})
statsHandler.HandleRPC(ctx, &stats.End{Client: false, Error: errorCode}) statsHandler.HandleRPC(ctx, &stats.End{Client: false, Error: errorCode})
} }
func Test_GRPCServerMetricsHandler(t *testing.T) { func Test_GRPCServerMetricsHandler(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
@ -171,7 +169,6 @@ func Test_GRPCServerMetricsHandler(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
view.Unregister(GRPCServerViews...) view.Unregister(GRPCServerViews...)
view.Register(GRPCServerViews...) view.Register(GRPCServerViews...)
@ -182,7 +179,6 @@ func Test_GRPCServerMetricsHandler(t *testing.T) {
testDataRetrieval(GRPCServerRequestDurationView, t, tt.wantgrpcServerRequestDuration) testDataRetrieval(GRPCServerRequestDurationView, t, tt.wantgrpcServerRequestDuration)
testDataRetrieval(GRPCServerRequestCountView, t, tt.wantgrpcServerRequestCount) testDataRetrieval(GRPCServerRequestCountView, t, tt.wantgrpcServerRequestCount)
testDataRetrieval(GRPCServerRequestSizeView, t, tt.wantgrpcServerRequestSizeView) testDataRetrieval(GRPCServerRequestSizeView, t, tt.wantgrpcServerRequestSizeView)
}) })
} }
} }

View file

@ -18,13 +18,15 @@ var (
HTTPClientViews = []*view.View{ HTTPClientViews = []*view.View{
HTTPClientRequestCountView, HTTPClientRequestCountView,
HTTPClientRequestDurationView, HTTPClientRequestDurationView,
HTTPClientResponseSizeView} HTTPClientResponseSizeView,
}
// HTTPServerViews contains opencensus views for HTTP Server metrics. // HTTPServerViews contains opencensus views for HTTP Server metrics.
HTTPServerViews = []*view.View{ HTTPServerViews = []*view.View{
HTTPServerRequestCountView, HTTPServerRequestCountView,
HTTPServerRequestDurationView, HTTPServerRequestDurationView,
HTTPServerRequestSizeView, HTTPServerRequestSizeView,
HTTPServerResponseSizeView} HTTPServerResponseSizeView,
}
// HTTPServerRequestCountView is an OpenCensus View that tracks HTTP server // HTTPServerRequestCountView is an OpenCensus View that tracks HTTP server
// requests by pomerium service, host, method and status // requests by pomerium service, host, method and status

View file

@ -22,7 +22,6 @@ func testDataRetrieval(v *view.View, t *testing.T, want string) {
} }
name := v.Name name := v.Name
data, err := view.RetrieveData(name) data, err := view.RetrieveData(name)
if err != nil { if err != nil {
t.Fatalf("%s: failed to retrieve data line %s", name, err) t.Fatalf("%s: failed to retrieve data line %s", name, err)
} }
@ -53,7 +52,6 @@ func newTestMux() http.Handler {
} }
func Test_HTTPMetricsHandler(t *testing.T) { func Test_HTTPMetricsHandler(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
url string url string

View file

@ -50,7 +50,6 @@ var (
// SetConfigInfo records the status, checksum and timestamp of a configuration // SetConfigInfo records the status, checksum and timestamp of a configuration
// reload. You must register InfoViews or the related config views before calling // reload. You must register InfoViews or the related config views before calling
func SetConfigInfo(service string, success bool) { func SetConfigInfo(service string, success bool) {
if success { if success {
serviceTag := tag.Insert(TagKeyService, service) serviceTag := tag.Insert(TagKeyService, service)
if err := stats.RecordWithTags( if err := stats.RecordWithTags(

View file

@ -30,5 +30,4 @@ func Test_AddRedisMetrics(t *testing.T) {
testMetricRetrieval(registry.registry.Read(), t, labelValues, tt.want, tt.name) testMetricRetrieval(registry.registry.Read(), t, labelValues, tt.want, tt.name)
}) })
} }
} }

View file

@ -74,7 +74,6 @@ func registerDefaultViews() error {
// newProxyMetricsHandler creates a subrequest to the envoy control plane for metrics and // newProxyMetricsHandler creates a subrequest to the envoy control plane for metrics and
// combines them with our own // combines them with our own
func newProxyMetricsHandler(promHandler http.Handler, envoyURL url.URL) http.HandlerFunc { func newProxyMetricsHandler(promHandler http.Handler, envoyURL url.URL) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
defer promHandler.ServeHTTP(w, r) defer promHandler.ServeHTTP(w, r)

View file

@ -10,7 +10,6 @@ import (
) )
func newEnvoyMetricsHandler() http.HandlerFunc { func newEnvoyMetricsHandler() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(` w.Write([]byte(`
# TYPE envoy_server_initialization_time_ms histogram # TYPE envoy_server_initialization_time_ms histogram
@ -47,7 +46,6 @@ func getMetrics(t *testing.T, envoyURL *url.URL) []byte {
} }
func Test_PrometheusHandler(t *testing.T) { func Test_PrometheusHandler(t *testing.T) {
t.Run("no envoy", func(t *testing.T) { t.Run("no envoy", func(t *testing.T) {
b := getMetrics(t, &url.URL{}) b := getMetrics(t, &url.URL{})
@ -67,7 +65,5 @@ func Test_PrometheusHandler(t *testing.T) {
if m, _ := regexp.Match(`(?m)^# TYPE envoy_.*`, b); !m { if m, _ := regexp.Match(`(?m)^# TYPE envoy_.*`, b); !m {
t.Errorf("Metrics endpoint did not contain envoy metrics: %s", b) t.Errorf("Metrics endpoint did not contain envoy metrics: %s", b)
} }
}) })
} }

View file

@ -11,9 +11,7 @@ import (
"github.com/pomerium/pomerium/internal/version" "github.com/pomerium/pomerium/internal/version"
) )
var ( var registry = newMetricRegistry()
registry = newMetricRegistry()
)
// metricRegistry holds the non-view metrics and handles safe // metricRegistry holds the non-view metrics and handles safe
// initialization and updates. Behavior without using newMetricRegistry() // initialization and updates. Behavior without using newMetricRegistry()
@ -108,7 +106,6 @@ func (r *metricRegistry) setConfigChecksum(service string, checksum uint64) {
} }
func (r *metricRegistry) addInt64DerivedGaugeMetric(name string, desc string, service string, f func() int64) { func (r *metricRegistry) addInt64DerivedGaugeMetric(name string, desc string, service string, f func() int64) {
m, err := r.registry.AddInt64DerivedGauge(name, metric.WithDescription(desc), metric.WithLabelKeys("service")) m, err := r.registry.AddInt64DerivedGauge(name, metric.WithDescription(desc), metric.WithLabelKeys("service"))
if err != nil { if err != nil {
log.Error().Err(err).Str("service", service).Msg("telemetry/metrics: failed to register metric") log.Error().Err(err).Str("service", service).Msg("telemetry/metrics: failed to register metric")
@ -123,7 +120,6 @@ func (r *metricRegistry) addInt64DerivedGaugeMetric(name string, desc string, se
} }
func (r *metricRegistry) addInt64DerivedCumulativeMetric(name string, desc string, service string, f func() int64) { func (r *metricRegistry) addInt64DerivedCumulativeMetric(name string, desc string, service string, f func() int64) {
m, err := r.registry.AddInt64DerivedCumulative(name, metric.WithDescription(desc), metric.WithLabelKeys("service")) m, err := r.registry.AddInt64DerivedCumulative(name, metric.WithDescription(desc), metric.WithLabelKeys("service"))
if err != nil { if err != nil {
log.Error().Err(err).Str("service", service).Msg("telemetry/metrics: failed to register metric") log.Error().Err(err).Str("service", service).Msg("telemetry/metrics: failed to register metric")

View file

@ -10,7 +10,6 @@ import (
) )
func Test_RecordStorageOperation(t *testing.T) { func Test_RecordStorageOperation(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
tags *StorageOperationTags tags *StorageOperationTags

View file

@ -7,7 +7,6 @@ import (
) )
func Test_ServiceName(t *testing.T) { func Test_ServiceName(t *testing.T) {
t.Parallel() t.Parallel()
tests := []struct { tests := []struct {
name string name string

View file

@ -26,7 +26,6 @@ func (t *mockTransport) RoundTrip(r *http.Request) (*http.Response, error) {
func mockMiddleware(id string) func(next http.RoundTripper) http.RoundTripper { func mockMiddleware(id string) func(next http.RoundTripper) http.RoundTripper {
return func(next http.RoundTripper) http.RoundTripper { return func(next http.RoundTripper) http.RoundTripper {
return RoundTripperFunc(func(r *http.Request) (*http.Response, error) { return RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
resp, _ := next.RoundTrip(r) resp, _ := next.RoundTrip(r)
body, _ := ioutil.ReadAll(resp.Body) body, _ := ioutil.ReadAll(resp.Body)
@ -77,7 +76,6 @@ func TestNilThen(t *testing.T) {
if NewChain().Then(nil) != http.DefaultTransport { if NewChain().Then(nil) != http.DefaultTransport {
t.Error("Then does not treat nil as DefaultTransport") t.Error("Then does not treat nil as DefaultTransport")
} }
} }
func TestAppend(t *testing.T) { func TestAppend(t *testing.T) {

View file

@ -20,11 +20,14 @@ func TestSignedURL(t *testing.T) {
want url.URL want url.URL
wantErr bool wantErr bool
}{ }{
{"good", "test-key", url.URL{Scheme: "https", Host: "pomerium.io"}, {
"good", "test-key",
url.URL{Scheme: "https", Host: "pomerium.io"},
func() time.Time { return original }, func() time.Time { return original }, func() time.Time { return original }, func() time.Time { return original },
"https://pomerium.io?pomerium_expiry=1574118151&pomerium_issued=1574117851&pomerium_signature=XtvM-Y-oPvoGGV2Q5G0vrQ_CgNeYhVyTG5dHIqLsBOU%3D", "https://pomerium.io?pomerium_expiry=1574118151&pomerium_issued=1574117851&pomerium_signature=XtvM-Y-oPvoGGV2Q5G0vrQ_CgNeYhVyTG5dHIqLsBOU%3D",
url.URL{Scheme: "https", Host: "pomerium.io", RawQuery: "pomerium_expiry=1574118151&pomerium_issued=1574117851&pomerium_signature=XtvM-Y-oPvoGGV2Q5G0vrQ_CgNeYhVyTG5dHIqLsBOU%3D"}, url.URL{Scheme: "https", Host: "pomerium.io", RawQuery: "pomerium_expiry=1574118151&pomerium_issued=1574117851&pomerium_signature=XtvM-Y-oPvoGGV2Q5G0vrQ_CgNeYhVyTG5dHIqLsBOU%3D"},
false}, false,
},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {

View file

@ -169,7 +169,6 @@ func TestParseEnvoyQueryParams(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
got := ParseEnvoyQueryParams(tt.u) got := ParseEnvoyQueryParams(tt.u)
if diff := cmp.Diff(got, tt.want); diff != "" { if diff := cmp.Diff(got, tt.want); diff != "" {
t.Errorf("ParseEnvoyQueryParams() = %v", diff) t.Errorf("ParseEnvoyQueryParams() = %v", diff)

View file

@ -34,6 +34,7 @@ func TestFullVersionVersion(t *testing.T) {
} }
} }
} }
func BenchmarkFullVersion(b *testing.B) { func BenchmarkFullVersion(b *testing.B) {
Version = "1.0.0" Version = "1.0.0"
GitCommit = "314501b" GitCommit = "314501b"

View file

@ -32,7 +32,6 @@ TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ=
` `
func TestCertifcateFromBase64(t *testing.T) { func TestCertifcateFromBase64(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
cert string cert string
@ -40,18 +39,24 @@ func TestCertifcateFromBase64(t *testing.T) {
// want *tls.Certificate // want *tls.Certificate
wantErr bool wantErr bool
}{ }{
{"good", {
"good",
"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVJVENDQWdtZ0F3SUJBZ0lSQVBqTEJxS1lwcWU0ekhQc0dWdFR6T0F3RFFZSktvWklodmNOQVFFTEJRQXcKRWpFUU1BNEdBMVVFQXhNSFoyOXZaQzFqWVRBZUZ3MHhPVEE0TVRBeE9EUTVOREJhRncweU1UQXlNVEF4TnpRdwpNREZhTUJNeEVUQVBCZ05WQkFNVENIQnZiV1Z5YVhWdE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBCk1JSUJDZ0tDQVFFQTY3S2pxbVFZR3EwTVZ0QUNWcGVDbVhtaW5sUWJEUEdMbXNaQVVFd3VlSFFucnQzV3R2cEQKT202QWxhSk1VblcrSHU1NWpqb2thbEtlVmpUS21nWUdicVV6VkRvTWJQRGFIZWtsdGRCVE1HbE9VRnNQNFVKUwpEck80emROK3pvNDI4VFgyUG5HMkZDZFZLR3k0UEU4aWxIYldMY3I4NzFZalY1MWZ3OENMRFg5UFpKTnU4NjFDCkY3VjlpRUptNnNTZlFsbW5oTjhqMytXelZiUFFOeTFXc1I3aTllOWo2M0VxS3QyMlE5T1hMK1dBY0tza29JU20KQ05WUlVBalU4WVJWY2dRSkIrelEzNEFRUGx6ME9wNU8vUU4vTWVkamFGOHdMUytpdi96dmlTOGNxUGJ4bzZzTApxNkZOVGx0ay9Ra3hlQ2VLS1RRZS8za1BZdlFBZG5sNjVRSURBUUFCbzNFd2J6QU9CZ05WSFE4QkFmOEVCQU1DCkE3Z3dIUVlEVlIwbEJCWXdGQVlJS3dZQkJRVUhBd0VHQ0NzR0FRVUZCd01DTUIwR0ExVWREZ1FXQkJRQ1FYbWIKc0hpcS9UQlZUZVhoQ0dpNjhrVy9DakFmQmdOVkhTTUVHREFXZ0JSNTRKQ3pMRlg0T0RTQ1J0dWNBUGZOdVhWegpuREFOQmdrcWhraUc5dzBCQVFzRkFBT0NBZ0VBcm9XL2trMllleFN5NEhaQXFLNDVZaGQ5ay9QVTFiaDlFK1BRCk5jZFgzTUdEY2NDRUFkc1k4dll3NVE1cnhuMGFzcSt3VGFCcGxoYS9rMi9VVW9IQ1RqUVp1Mk94dEF3UTdPaWIKVE1tMEorU3NWT3d4YnFQTW9rK1RqVE16NFdXaFFUTzVwRmNoZDZXZXNCVHlJNzJ0aG1jcDd1c2NLU2h3YktIegpQY2h1QTQ4SzhPdi96WkxmZnduQVNZb3VCczJjd1ZiRDI3ZXZOMzdoMGFzR1BrR1VXdm1PSDduTHNVeTh3TTdqCkNGL3NwMmJmTC9OYVdNclJnTHZBMGZMS2pwWTQrVEpPbkVxQmxPcCsrbHlJTEZMcC9qMHNybjRNUnlKK0t6UTEKR1RPakVtQ1QvVEFtOS9XSThSL0FlYjcwTjEzTytYNEtaOUJHaDAxTzN3T1Vqd3BZZ3lxSnNoRnNRUG50VmMrSQpKQmF4M2VQU3NicUcwTFkzcHdHUkpRNmMrd1lxdGk2Y0tNTjliYlRkMDhCNUk1N1RRTHhNcUoycTFnWmw1R1VUCmVFZGNWRXltMnZmd0NPd0lrbGNBbThxTm5kZGZKV1FabE5VaHNOVWFBMkVINnlDeXdaZm9aak9hSDEwTXowV20KeTNpZ2NSZFQ3Mi9NR2VkZk93MlV0MVVvRFZmdEcxcysrditUQ1lpNmpUQU05dkZPckJ4UGlOeGFkUENHR2NZZAowakZIc2FWOGFPV1dQQjZBQ1JteHdDVDdRTnRTczM2MlpIOUlFWWR4Q00yMDUrZmluVHhkOUcwSmVRRTd2Kyt6CldoeWo2ZmJBWUIxM2wvN1hkRnpNSW5BOGxpekdrVHB2RHMxeTBCUzlwV3ppYmhqbVFoZGZIejdCZGpGTHVvc2wKZzlNZE5sND0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=", "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVJVENDQWdtZ0F3SUJBZ0lSQVBqTEJxS1lwcWU0ekhQc0dWdFR6T0F3RFFZSktvWklodmNOQVFFTEJRQXcKRWpFUU1BNEdBMVVFQXhNSFoyOXZaQzFqWVRBZUZ3MHhPVEE0TVRBeE9EUTVOREJhRncweU1UQXlNVEF4TnpRdwpNREZhTUJNeEVUQVBCZ05WQkFNVENIQnZiV1Z5YVhWdE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBCk1JSUJDZ0tDQVFFQTY3S2pxbVFZR3EwTVZ0QUNWcGVDbVhtaW5sUWJEUEdMbXNaQVVFd3VlSFFucnQzV3R2cEQKT202QWxhSk1VblcrSHU1NWpqb2thbEtlVmpUS21nWUdicVV6VkRvTWJQRGFIZWtsdGRCVE1HbE9VRnNQNFVKUwpEck80emROK3pvNDI4VFgyUG5HMkZDZFZLR3k0UEU4aWxIYldMY3I4NzFZalY1MWZ3OENMRFg5UFpKTnU4NjFDCkY3VjlpRUptNnNTZlFsbW5oTjhqMytXelZiUFFOeTFXc1I3aTllOWo2M0VxS3QyMlE5T1hMK1dBY0tza29JU20KQ05WUlVBalU4WVJWY2dRSkIrelEzNEFRUGx6ME9wNU8vUU4vTWVkamFGOHdMUytpdi96dmlTOGNxUGJ4bzZzTApxNkZOVGx0ay9Ra3hlQ2VLS1RRZS8za1BZdlFBZG5sNjVRSURBUUFCbzNFd2J6QU9CZ05WSFE4QkFmOEVCQU1DCkE3Z3dIUVlEVlIwbEJCWXdGQVlJS3dZQkJRVUhBd0VHQ0NzR0FRVUZCd01DTUIwR0ExVWREZ1FXQkJRQ1FYbWIKc0hpcS9UQlZUZVhoQ0dpNjhrVy9DakFmQmdOVkhTTUVHREFXZ0JSNTRKQ3pMRlg0T0RTQ1J0dWNBUGZOdVhWegpuREFOQmdrcWhraUc5dzBCQVFzRkFBT0NBZ0VBcm9XL2trMllleFN5NEhaQXFLNDVZaGQ5ay9QVTFiaDlFK1BRCk5jZFgzTUdEY2NDRUFkc1k4dll3NVE1cnhuMGFzcSt3VGFCcGxoYS9rMi9VVW9IQ1RqUVp1Mk94dEF3UTdPaWIKVE1tMEorU3NWT3d4YnFQTW9rK1RqVE16NFdXaFFUTzVwRmNoZDZXZXNCVHlJNzJ0aG1jcDd1c2NLU2h3YktIegpQY2h1QTQ4SzhPdi96WkxmZnduQVNZb3VCczJjd1ZiRDI3ZXZOMzdoMGFzR1BrR1VXdm1PSDduTHNVeTh3TTdqCkNGL3NwMmJmTC9OYVdNclJnTHZBMGZMS2pwWTQrVEpPbkVxQmxPcCsrbHlJTEZMcC9qMHNybjRNUnlKK0t6UTEKR1RPakVtQ1QvVEFtOS9XSThSL0FlYjcwTjEzTytYNEtaOUJHaDAxTzN3T1Vqd3BZZ3lxSnNoRnNRUG50VmMrSQpKQmF4M2VQU3NicUcwTFkzcHdHUkpRNmMrd1lxdGk2Y0tNTjliYlRkMDhCNUk1N1RRTHhNcUoycTFnWmw1R1VUCmVFZGNWRXltMnZmd0NPd0lrbGNBbThxTm5kZGZKV1FabE5VaHNOVWFBMkVINnlDeXdaZm9aak9hSDEwTXowV20KeTNpZ2NSZFQ3Mi9NR2VkZk93MlV0MVVvRFZmdEcxcysrditUQ1lpNmpUQU05dkZPckJ4UGlOeGFkUENHR2NZZAowakZIc2FWOGFPV1dQQjZBQ1JteHdDVDdRTnRTczM2MlpIOUlFWWR4Q00yMDUrZmluVHhkOUcwSmVRRTd2Kyt6CldoeWo2ZmJBWUIxM2wvN1hkRnpNSW5BOGxpekdrVHB2RHMxeTBCUzlwV3ppYmhqbVFoZGZIejdCZGpGTHVvc2wKZzlNZE5sND0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=",
"LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcGdJQkFBS0NBUUVBNjdLanFtUVlHcTBNVnRBQ1ZwZUNtWG1pbmxRYkRQR0xtc1pBVUV3dWVIUW5ydDNXCnR2cERPbTZBbGFKTVVuVytIdTU1ampva2FsS2VWalRLbWdZR2JxVXpWRG9NYlBEYUhla2x0ZEJUTUdsT1VGc1AKNFVKU0RyTzR6ZE4rem80MjhUWDJQbkcyRkNkVktHeTRQRThpbEhiV0xjcjg3MVlqVjUxZnc4Q0xEWDlQWkpOdQo4NjFDRjdWOWlFSm02c1NmUWxtbmhOOGozK1d6VmJQUU55MVdzUjdpOWU5ajYzRXFLdDIyUTlPWEwrV0FjS3NrCm9JU21DTlZSVUFqVThZUlZjZ1FKQit6UTM0QVFQbHowT3A1Ty9RTi9NZWRqYUY4d0xTK2l2L3p2aVM4Y3FQYngKbzZzTHE2Rk5UbHRrL1FreGVDZUtLVFFlLzNrUFl2UUFkbmw2NVFJREFRQUJBb0lCQVFEQVQ0eXN2V2pSY3pxcgpKcU9SeGFPQTJEY3dXazJML1JXOFhtQWhaRmRTWHV2MkNQbGxhTU1yelBmTG41WUlmaHQzSDNzODZnSEdZc3pnClo4aWJiYWtYNUdFQ0t5N3lRSDZuZ3hFS3pRVGpiampBNWR3S0h0UFhQUnJmamQ1Y2FMczVpcDcxaWxCWEYxU3IKWERIaXUycnFtaC9kVTArWGRMLzNmK2VnVDl6bFQ5YzRyUm84dnZueWNYejFyMnVhRVZ2VExsWHVsb2NpeEVrcgoySjlTMmxveWFUb2tFTnNlMDNpSVdaWnpNNElZcVowOGJOeG9IWCszQXVlWExIUStzRkRKMlhaVVdLSkZHMHUyClp3R2w3YlZpRTFQNXdiQUdtZzJDeDVCN1MrdGQyUEpSV3Frb2VxY3F2RVdCc3RFL1FEcDFpVThCOHpiQXd0Y3IKZHc5TXZ6Q2hBb0dCQVBObzRWMjF6MGp6MWdEb2tlTVN5d3JnL2E4RkJSM2R2Y0xZbWV5VXkybmd3eHVucnFsdwo2U2IrOWdrOGovcXEvc3VQSDhVdzNqSHNKYXdGSnNvTkVqNCt2b1ZSM3UrbE5sTEw5b21rMXBoU0dNdVp0b3huCm5nbUxVbkJUMGI1M3BURkJ5WGsveE5CbElreWdBNlg5T2MreW5na3RqNlRyVnMxUERTdnVJY0s1QW9HQkFQZmoKcEUzR2F6cVFSemx6TjRvTHZmQWJBdktCZ1lPaFNnemxsK0ZLZkhzYWJGNkdudFd1dWVhY1FIWFpYZTA1c2tLcApXN2xYQ3dqQU1iUXI3QmdlazcrOSszZElwL1RnYmZCYnN3Syt6Vng3Z2doeWMrdytXRWExaHByWTZ6YXdxdkFaCkhRU2lMUEd1UGp5WXBQa1E2ZFdEczNmWHJGZ1dlTmd4SkhTZkdaT05Bb0dCQUt5WTF3MUM2U3Y2c3VuTC8vNTcKQ2Z5NTAwaXlqNUZBOWRqZkRDNWt4K1JZMnlDV0ExVGsybjZyVmJ6dzg4czBTeDMrYS9IQW1CM2dMRXBSRU5NKwo5NHVwcENFWEQ3VHdlcGUxUnlrTStKbmp4TzlDSE41c2J2U25sUnBQWlMvZzJRTVhlZ3grK2trbkhXNG1ITkFyCndqMlRrMXBBczFXbkJ0TG9WaGVyY01jSkFvR0JBSTYwSGdJb0Y5SysvRUcyY21LbUg5SDV1dGlnZFU2eHEwK0IKWE0zMWMzUHE0amdJaDZlN3pvbFRxa2d0dWtTMjBraE45dC9ibkI2TmhnK1N1WGVwSXFWZldVUnlMejVwZE9ESgo2V1BMTTYzcDdCR3cwY3RPbU1NYi9VRm5Yd0U4OHlzRlNnOUF6VjdVVUQvU0lDYkI5ZHRVMWh4SHJJK0pZRWdWCkFrZWd6N2lCQW9HQkFJRncrQVFJZUIwM01UL0lCbGswNENQTDJEak0rNDhoVGRRdjgwMDBIQU9mUWJrMEVZUDEKQ2FLR3RDbTg2MXpBZjBzcS81REtZQ0l6OS9HUzNYRk00Qm1rRk9nY1NXVENPNmZmTGdLM3FmQzN4WDJudlpIOQpYZGNKTDQrZndhY0x4c2JJKzhhUWNOVHRtb3pkUjEzQnNmUmIrSGpUL2o3dkdrYlFnSkhCT0syegotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=", "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcGdJQkFBS0NBUUVBNjdLanFtUVlHcTBNVnRBQ1ZwZUNtWG1pbmxRYkRQR0xtc1pBVUV3dWVIUW5ydDNXCnR2cERPbTZBbGFKTVVuVytIdTU1ampva2FsS2VWalRLbWdZR2JxVXpWRG9NYlBEYUhla2x0ZEJUTUdsT1VGc1AKNFVKU0RyTzR6ZE4rem80MjhUWDJQbkcyRkNkVktHeTRQRThpbEhiV0xjcjg3MVlqVjUxZnc4Q0xEWDlQWkpOdQo4NjFDRjdWOWlFSm02c1NmUWxtbmhOOGozK1d6VmJQUU55MVdzUjdpOWU5ajYzRXFLdDIyUTlPWEwrV0FjS3NrCm9JU21DTlZSVUFqVThZUlZjZ1FKQit6UTM0QVFQbHowT3A1Ty9RTi9NZWRqYUY4d0xTK2l2L3p2aVM4Y3FQYngKbzZzTHE2Rk5UbHRrL1FreGVDZUtLVFFlLzNrUFl2UUFkbmw2NVFJREFRQUJBb0lCQVFEQVQ0eXN2V2pSY3pxcgpKcU9SeGFPQTJEY3dXazJML1JXOFhtQWhaRmRTWHV2MkNQbGxhTU1yelBmTG41WUlmaHQzSDNzODZnSEdZc3pnClo4aWJiYWtYNUdFQ0t5N3lRSDZuZ3hFS3pRVGpiampBNWR3S0h0UFhQUnJmamQ1Y2FMczVpcDcxaWxCWEYxU3IKWERIaXUycnFtaC9kVTArWGRMLzNmK2VnVDl6bFQ5YzRyUm84dnZueWNYejFyMnVhRVZ2VExsWHVsb2NpeEVrcgoySjlTMmxveWFUb2tFTnNlMDNpSVdaWnpNNElZcVowOGJOeG9IWCszQXVlWExIUStzRkRKMlhaVVdLSkZHMHUyClp3R2w3YlZpRTFQNXdiQUdtZzJDeDVCN1MrdGQyUEpSV3Frb2VxY3F2RVdCc3RFL1FEcDFpVThCOHpiQXd0Y3IKZHc5TXZ6Q2hBb0dCQVBObzRWMjF6MGp6MWdEb2tlTVN5d3JnL2E4RkJSM2R2Y0xZbWV5VXkybmd3eHVucnFsdwo2U2IrOWdrOGovcXEvc3VQSDhVdzNqSHNKYXdGSnNvTkVqNCt2b1ZSM3UrbE5sTEw5b21rMXBoU0dNdVp0b3huCm5nbUxVbkJUMGI1M3BURkJ5WGsveE5CbElreWdBNlg5T2MreW5na3RqNlRyVnMxUERTdnVJY0s1QW9HQkFQZmoKcEUzR2F6cVFSemx6TjRvTHZmQWJBdktCZ1lPaFNnemxsK0ZLZkhzYWJGNkdudFd1dWVhY1FIWFpYZTA1c2tLcApXN2xYQ3dqQU1iUXI3QmdlazcrOSszZElwL1RnYmZCYnN3Syt6Vng3Z2doeWMrdytXRWExaHByWTZ6YXdxdkFaCkhRU2lMUEd1UGp5WXBQa1E2ZFdEczNmWHJGZ1dlTmd4SkhTZkdaT05Bb0dCQUt5WTF3MUM2U3Y2c3VuTC8vNTcKQ2Z5NTAwaXlqNUZBOWRqZkRDNWt4K1JZMnlDV0ExVGsybjZyVmJ6dzg4czBTeDMrYS9IQW1CM2dMRXBSRU5NKwo5NHVwcENFWEQ3VHdlcGUxUnlrTStKbmp4TzlDSE41c2J2U25sUnBQWlMvZzJRTVhlZ3grK2trbkhXNG1ITkFyCndqMlRrMXBBczFXbkJ0TG9WaGVyY01jSkFvR0JBSTYwSGdJb0Y5SysvRUcyY21LbUg5SDV1dGlnZFU2eHEwK0IKWE0zMWMzUHE0amdJaDZlN3pvbFRxa2d0dWtTMjBraE45dC9ibkI2TmhnK1N1WGVwSXFWZldVUnlMejVwZE9ESgo2V1BMTTYzcDdCR3cwY3RPbU1NYi9VRm5Yd0U4OHlzRlNnOUF6VjdVVUQvU0lDYkI5ZHRVMWh4SHJJK0pZRWdWCkFrZWd6N2lCQW9HQkFJRncrQVFJZUIwM01UL0lCbGswNENQTDJEak0rNDhoVGRRdjgwMDBIQU9mUWJrMEVZUDEKQ2FLR3RDbTg2MXpBZjBzcS81REtZQ0l6OS9HUzNYRk00Qm1rRk9nY1NXVENPNmZmTGdLM3FmQzN4WDJudlpIOQpYZGNKTDQrZndhY0x4c2JJKzhhUWNOVHRtb3pkUjEzQnNmUmIrSGpUL2o3dkdrYlFnSkhCT0syegotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=",
false}, false,
{"bad cert", },
{
"bad cert",
"!=", "!=",
"LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcGdJQkFBS0NBUUVBNjdLanFtUVlHcTBNVnRBQ1ZwZUNtWG1pbmxRYkRQR0xtc1pBVUV3dWVIUW5ydDNXCnR2cERPbTZBbGFKTVVuVytIdTU1ampva2FsS2VWalRLbWdZR2JxVXpWRG9NYlBEYUhla2x0ZEJUTUdsT1VGc1AKNFVKU0RyTzR6ZE4rem80MjhUWDJQbkcyRkNkVktHeTRQRThpbEhiV0xjcjg3MVlqVjUxZnc4Q0xEWDlQWkpOdQo4NjFDRjdWOWlFSm02c1NmUWxtbmhOOGozK1d6VmJQUU55MVdzUjdpOWU5ajYzRXFLdDIyUTlPWEwrV0FjS3NrCm9JU21DTlZSVUFqVThZUlZjZ1FKQit6UTM0QVFQbHowT3A1Ty9RTi9NZWRqYUY4d0xTK2l2L3p2aVM4Y3FQYngKbzZzTHE2Rk5UbHRrL1FreGVDZUtLVFFlLzNrUFl2UUFkbmw2NVFJREFRQUJBb0lCQVFEQVQ0eXN2V2pSY3pxcgpKcU9SeGFPQTJEY3dXazJML1JXOFhtQWhaRmRTWHV2MkNQbGxhTU1yelBmTG41WUlmaHQzSDNzODZnSEdZc3pnClo4aWJiYWtYNUdFQ0t5N3lRSDZuZ3hFS3pRVGpiampBNWR3S0h0UFhQUnJmamQ1Y2FMczVpcDcxaWxCWEYxU3IKWERIaXUycnFtaC9kVTArWGRMLzNmK2VnVDl6bFQ5YzRyUm84dnZueWNYejFyMnVhRVZ2VExsWHVsb2NpeEVrcgoySjlTMmxveWFUb2tFTnNlMDNpSVdaWnpNNElZcVowOGJOeG9IWCszQXVlWExIUStzRkRKMlhaVVdLSkZHMHUyClp3R2w3YlZpRTFQNXdiQUdtZzJDeDVCN1MrdGQyUEpSV3Frb2VxY3F2RVdCc3RFL1FEcDFpVThCOHpiQXd0Y3IKZHc5TXZ6Q2hBb0dCQVBObzRWMjF6MGp6MWdEb2tlTVN5d3JnL2E4RkJSM2R2Y0xZbWV5VXkybmd3eHVucnFsdwo2U2IrOWdrOGovcXEvc3VQSDhVdzNqSHNKYXdGSnNvTkVqNCt2b1ZSM3UrbE5sTEw5b21rMXBoU0dNdVp0b3huCm5nbUxVbkJUMGI1M3BURkJ5WGsveE5CbElreWdBNlg5T2MreW5na3RqNlRyVnMxUERTdnVJY0s1QW9HQkFQZmoKcEUzR2F6cVFSemx6TjRvTHZmQWJBdktCZ1lPaFNnemxsK0ZLZkhzYWJGNkdudFd1dWVhY1FIWFpYZTA1c2tLcApXN2xYQ3dqQU1iUXI3QmdlazcrOSszZElwL1RnYmZCYnN3Syt6Vng3Z2doeWMrdytXRWExaHByWTZ6YXdxdkFaCkhRU2lMUEd1UGp5WXBQa1E2ZFdEczNmWHJGZ1dlTmd4SkhTZkdaT05Bb0dCQUt5WTF3MUM2U3Y2c3VuTC8vNTcKQ2Z5NTAwaXlqNUZBOWRqZkRDNWt4K1JZMnlDV0ExVGsybjZyVmJ6dzg4czBTeDMrYS9IQW1CM2dMRXBSRU5NKwo5NHVwcENFWEQ3VHdlcGUxUnlrTStKbmp4TzlDSE41c2J2U25sUnBQWlMvZzJRTVhlZ3grK2trbkhXNG1ITkFyCndqMlRrMXBBczFXbkJ0TG9WaGVyY01jSkFvR0JBSTYwSGdJb0Y5SysvRUcyY21LbUg5SDV1dGlnZFU2eHEwK0IKWE0zMWMzUHE0amdJaDZlN3pvbFRxa2d0dWtTMjBraE45dC9ibkI2TmhnK1N1WGVwSXFWZldVUnlMejVwZE9ESgo2V1BMTTYzcDdCR3cwY3RPbU1NYi9VRm5Yd0U4OHlzRlNnOUF6VjdVVUQvU0lDYkI5ZHRVMWh4SHJJK0pZRWdWCkFrZWd6N2lCQW9HQkFJRncrQVFJZUIwM01UL0lCbGswNENQTDJEak0rNDhoVGRRdjgwMDBIQU9mUWJrMEVZUDEKQ2FLR3RDbTg2MXpBZjBzcS81REtZQ0l6OS9HUzNYRk00Qm1rRk9nY1NXVENPNmZmTGdLM3FmQzN4WDJudlpIOQpYZGNKTDQrZndhY0x4c2JJKzhhUWNOVHRtb3pkUjEzQnNmUmIrSGpUL2o3dkdrYlFnSkhCT0syegotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=", "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcGdJQkFBS0NBUUVBNjdLanFtUVlHcTBNVnRBQ1ZwZUNtWG1pbmxRYkRQR0xtc1pBVUV3dWVIUW5ydDNXCnR2cERPbTZBbGFKTVVuVytIdTU1ampva2FsS2VWalRLbWdZR2JxVXpWRG9NYlBEYUhla2x0ZEJUTUdsT1VGc1AKNFVKU0RyTzR6ZE4rem80MjhUWDJQbkcyRkNkVktHeTRQRThpbEhiV0xjcjg3MVlqVjUxZnc4Q0xEWDlQWkpOdQo4NjFDRjdWOWlFSm02c1NmUWxtbmhOOGozK1d6VmJQUU55MVdzUjdpOWU5ajYzRXFLdDIyUTlPWEwrV0FjS3NrCm9JU21DTlZSVUFqVThZUlZjZ1FKQit6UTM0QVFQbHowT3A1Ty9RTi9NZWRqYUY4d0xTK2l2L3p2aVM4Y3FQYngKbzZzTHE2Rk5UbHRrL1FreGVDZUtLVFFlLzNrUFl2UUFkbmw2NVFJREFRQUJBb0lCQVFEQVQ0eXN2V2pSY3pxcgpKcU9SeGFPQTJEY3dXazJML1JXOFhtQWhaRmRTWHV2MkNQbGxhTU1yelBmTG41WUlmaHQzSDNzODZnSEdZc3pnClo4aWJiYWtYNUdFQ0t5N3lRSDZuZ3hFS3pRVGpiampBNWR3S0h0UFhQUnJmamQ1Y2FMczVpcDcxaWxCWEYxU3IKWERIaXUycnFtaC9kVTArWGRMLzNmK2VnVDl6bFQ5YzRyUm84dnZueWNYejFyMnVhRVZ2VExsWHVsb2NpeEVrcgoySjlTMmxveWFUb2tFTnNlMDNpSVdaWnpNNElZcVowOGJOeG9IWCszQXVlWExIUStzRkRKMlhaVVdLSkZHMHUyClp3R2w3YlZpRTFQNXdiQUdtZzJDeDVCN1MrdGQyUEpSV3Frb2VxY3F2RVdCc3RFL1FEcDFpVThCOHpiQXd0Y3IKZHc5TXZ6Q2hBb0dCQVBObzRWMjF6MGp6MWdEb2tlTVN5d3JnL2E4RkJSM2R2Y0xZbWV5VXkybmd3eHVucnFsdwo2U2IrOWdrOGovcXEvc3VQSDhVdzNqSHNKYXdGSnNvTkVqNCt2b1ZSM3UrbE5sTEw5b21rMXBoU0dNdVp0b3huCm5nbUxVbkJUMGI1M3BURkJ5WGsveE5CbElreWdBNlg5T2MreW5na3RqNlRyVnMxUERTdnVJY0s1QW9HQkFQZmoKcEUzR2F6cVFSemx6TjRvTHZmQWJBdktCZ1lPaFNnemxsK0ZLZkhzYWJGNkdudFd1dWVhY1FIWFpYZTA1c2tLcApXN2xYQ3dqQU1iUXI3QmdlazcrOSszZElwL1RnYmZCYnN3Syt6Vng3Z2doeWMrdytXRWExaHByWTZ6YXdxdkFaCkhRU2lMUEd1UGp5WXBQa1E2ZFdEczNmWHJGZ1dlTmd4SkhTZkdaT05Bb0dCQUt5WTF3MUM2U3Y2c3VuTC8vNTcKQ2Z5NTAwaXlqNUZBOWRqZkRDNWt4K1JZMnlDV0ExVGsybjZyVmJ6dzg4czBTeDMrYS9IQW1CM2dMRXBSRU5NKwo5NHVwcENFWEQ3VHdlcGUxUnlrTStKbmp4TzlDSE41c2J2U25sUnBQWlMvZzJRTVhlZ3grK2trbkhXNG1ITkFyCndqMlRrMXBBczFXbkJ0TG9WaGVyY01jSkFvR0JBSTYwSGdJb0Y5SysvRUcyY21LbUg5SDV1dGlnZFU2eHEwK0IKWE0zMWMzUHE0amdJaDZlN3pvbFRxa2d0dWtTMjBraE45dC9ibkI2TmhnK1N1WGVwSXFWZldVUnlMejVwZE9ESgo2V1BMTTYzcDdCR3cwY3RPbU1NYi9VRm5Yd0U4OHlzRlNnOUF6VjdVVUQvU0lDYkI5ZHRVMWh4SHJJK0pZRWdWCkFrZWd6N2lCQW9HQkFJRncrQVFJZUIwM01UL0lCbGswNENQTDJEak0rNDhoVGRRdjgwMDBIQU9mUWJrMEVZUDEKQ2FLR3RDbTg2MXpBZjBzcS81REtZQ0l6OS9HUzNYRk00Qm1rRk9nY1NXVENPNmZmTGdLM3FmQzN4WDJudlpIOQpYZGNKTDQrZndhY0x4c2JJKzhhUWNOVHRtb3pkUjEzQnNmUmIrSGpUL2o3dkdrYlFnSkhCT0syegotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=",
true}, true,
{"bad key", },
{
"bad key",
"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVJVENDQWdtZ0F3SUJBZ0lSQVBqTEJxS1lwcWU0ekhQc0dWdFR6T0F3RFFZSktvWklodmNOQVFFTEJRQXcKRWpFUU1BNEdBMVVFQXhNSFoyOXZaQzFqWVRBZUZ3MHhPVEE0TVRBeE9EUTVOREJhRncweU1UQXlNVEF4TnpRdwpNREZhTUJNeEVUQVBCZ05WQkFNVENIQnZiV1Z5YVhWdE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBCk1JSUJDZ0tDQVFFQTY3S2pxbVFZR3EwTVZ0QUNWcGVDbVhtaW5sUWJEUEdMbXNaQVVFd3VlSFFucnQzV3R2cEQKT202QWxhSk1VblcrSHU1NWpqb2thbEtlVmpUS21nWUdicVV6VkRvTWJQRGFIZWtsdGRCVE1HbE9VRnNQNFVKUwpEck80emROK3pvNDI4VFgyUG5HMkZDZFZLR3k0UEU4aWxIYldMY3I4NzFZalY1MWZ3OENMRFg5UFpKTnU4NjFDCkY3VjlpRUptNnNTZlFsbW5oTjhqMytXelZiUFFOeTFXc1I3aTllOWo2M0VxS3QyMlE5T1hMK1dBY0tza29JU20KQ05WUlVBalU4WVJWY2dRSkIrelEzNEFRUGx6ME9wNU8vUU4vTWVkamFGOHdMUytpdi96dmlTOGNxUGJ4bzZzTApxNkZOVGx0ay9Ra3hlQ2VLS1RRZS8za1BZdlFBZG5sNjVRSURBUUFCbzNFd2J6QU9CZ05WSFE4QkFmOEVCQU1DCkE3Z3dIUVlEVlIwbEJCWXdGQVlJS3dZQkJRVUhBd0VHQ0NzR0FRVUZCd01DTUIwR0ExVWREZ1FXQkJRQ1FYbWIKc0hpcS9UQlZUZVhoQ0dpNjhrVy9DakFmQmdOVkhTTUVHREFXZ0JSNTRKQ3pMRlg0T0RTQ1J0dWNBUGZOdVhWegpuREFOQmdrcWhraUc5dzBCQVFzRkFBT0NBZ0VBcm9XL2trMllleFN5NEhaQXFLNDVZaGQ5ay9QVTFiaDlFK1BRCk5jZFgzTUdEY2NDRUFkc1k4dll3NVE1cnhuMGFzcSt3VGFCcGxoYS9rMi9VVW9IQ1RqUVp1Mk94dEF3UTdPaWIKVE1tMEorU3NWT3d4YnFQTW9rK1RqVE16NFdXaFFUTzVwRmNoZDZXZXNCVHlJNzJ0aG1jcDd1c2NLU2h3YktIegpQY2h1QTQ4SzhPdi96WkxmZnduQVNZb3VCczJjd1ZiRDI3ZXZOMzdoMGFzR1BrR1VXdm1PSDduTHNVeTh3TTdqCkNGL3NwMmJmTC9OYVdNclJnTHZBMGZMS2pwWTQrVEpPbkVxQmxPcCsrbHlJTEZMcC9qMHNybjRNUnlKK0t6UTEKR1RPakVtQ1QvVEFtOS9XSThSL0FlYjcwTjEzTytYNEtaOUJHaDAxTzN3T1Vqd3BZZ3lxSnNoRnNRUG50VmMrSQpKQmF4M2VQU3NicUcwTFkzcHdHUkpRNmMrd1lxdGk2Y0tNTjliYlRkMDhCNUk1N1RRTHhNcUoycTFnWmw1R1VUCmVFZGNWRXltMnZmd0NPd0lrbGNBbThxTm5kZGZKV1FabE5VaHNOVWFBMkVINnlDeXdaZm9aak9hSDEwTXowV20KeTNpZ2NSZFQ3Mi9NR2VkZk93MlV0MVVvRFZmdEcxcysrditUQ1lpNmpUQU05dkZPckJ4UGlOeGFkUENHR2NZZAowakZIc2FWOGFPV1dQQjZBQ1JteHdDVDdRTnRTczM2MlpIOUlFWWR4Q00yMDUrZmluVHhkOUcwSmVRRTd2Kyt6CldoeWo2ZmJBWUIxM2wvN1hkRnpNSW5BOGxpekdrVHB2RHMxeTBCUzlwV3ppYmhqbVFoZGZIejdCZGpGTHVvc2wKZzlNZE5sND0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=", "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVJVENDQWdtZ0F3SUJBZ0lSQVBqTEJxS1lwcWU0ekhQc0dWdFR6T0F3RFFZSktvWklodmNOQVFFTEJRQXcKRWpFUU1BNEdBMVVFQXhNSFoyOXZaQzFqWVRBZUZ3MHhPVEE0TVRBeE9EUTVOREJhRncweU1UQXlNVEF4TnpRdwpNREZhTUJNeEVUQVBCZ05WQkFNVENIQnZiV1Z5YVhWdE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBCk1JSUJDZ0tDQVFFQTY3S2pxbVFZR3EwTVZ0QUNWcGVDbVhtaW5sUWJEUEdMbXNaQVVFd3VlSFFucnQzV3R2cEQKT202QWxhSk1VblcrSHU1NWpqb2thbEtlVmpUS21nWUdicVV6VkRvTWJQRGFIZWtsdGRCVE1HbE9VRnNQNFVKUwpEck80emROK3pvNDI4VFgyUG5HMkZDZFZLR3k0UEU4aWxIYldMY3I4NzFZalY1MWZ3OENMRFg5UFpKTnU4NjFDCkY3VjlpRUptNnNTZlFsbW5oTjhqMytXelZiUFFOeTFXc1I3aTllOWo2M0VxS3QyMlE5T1hMK1dBY0tza29JU20KQ05WUlVBalU4WVJWY2dRSkIrelEzNEFRUGx6ME9wNU8vUU4vTWVkamFGOHdMUytpdi96dmlTOGNxUGJ4bzZzTApxNkZOVGx0ay9Ra3hlQ2VLS1RRZS8za1BZdlFBZG5sNjVRSURBUUFCbzNFd2J6QU9CZ05WSFE4QkFmOEVCQU1DCkE3Z3dIUVlEVlIwbEJCWXdGQVlJS3dZQkJRVUhBd0VHQ0NzR0FRVUZCd01DTUIwR0ExVWREZ1FXQkJRQ1FYbWIKc0hpcS9UQlZUZVhoQ0dpNjhrVy9DakFmQmdOVkhTTUVHREFXZ0JSNTRKQ3pMRlg0T0RTQ1J0dWNBUGZOdVhWegpuREFOQmdrcWhraUc5dzBCQVFzRkFBT0NBZ0VBcm9XL2trMllleFN5NEhaQXFLNDVZaGQ5ay9QVTFiaDlFK1BRCk5jZFgzTUdEY2NDRUFkc1k4dll3NVE1cnhuMGFzcSt3VGFCcGxoYS9rMi9VVW9IQ1RqUVp1Mk94dEF3UTdPaWIKVE1tMEorU3NWT3d4YnFQTW9rK1RqVE16NFdXaFFUTzVwRmNoZDZXZXNCVHlJNzJ0aG1jcDd1c2NLU2h3YktIegpQY2h1QTQ4SzhPdi96WkxmZnduQVNZb3VCczJjd1ZiRDI3ZXZOMzdoMGFzR1BrR1VXdm1PSDduTHNVeTh3TTdqCkNGL3NwMmJmTC9OYVdNclJnTHZBMGZMS2pwWTQrVEpPbkVxQmxPcCsrbHlJTEZMcC9qMHNybjRNUnlKK0t6UTEKR1RPakVtQ1QvVEFtOS9XSThSL0FlYjcwTjEzTytYNEtaOUJHaDAxTzN3T1Vqd3BZZ3lxSnNoRnNRUG50VmMrSQpKQmF4M2VQU3NicUcwTFkzcHdHUkpRNmMrd1lxdGk2Y0tNTjliYlRkMDhCNUk1N1RRTHhNcUoycTFnWmw1R1VUCmVFZGNWRXltMnZmd0NPd0lrbGNBbThxTm5kZGZKV1FabE5VaHNOVWFBMkVINnlDeXdaZm9aak9hSDEwTXowV20KeTNpZ2NSZFQ3Mi9NR2VkZk93MlV0MVVvRFZmdEcxcysrditUQ1lpNmpUQU05dkZPckJ4UGlOeGFkUENHR2NZZAowakZIc2FWOGFPV1dQQjZBQ1JteHdDVDdRTnRTczM2MlpIOUlFWWR4Q00yMDUrZmluVHhkOUcwSmVRRTd2Kyt6CldoeWo2ZmJBWUIxM2wvN1hkRnpNSW5BOGxpekdrVHB2RHMxeTBCUzlwV3ppYmhqbVFoZGZIejdCZGpGTHVvc2wKZzlNZE5sND0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=",
"!=", "!=",
true}, true,
},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
@ -91,7 +96,6 @@ func TestPublicKeyMarshaling(t *testing.T) {
if !bytes.Equal(pemBytes, []byte(pemECPublicKeyP256)) { if !bytes.Equal(pemBytes, []byte(pemECPublicKeyP256)) {
t.Fatal("public key encoding did not match") t.Fatal("public key encoding did not match")
} }
} }
func TestPrivateKeyBadDecode(t *testing.T) { func TestPrivateKeyBadDecode(t *testing.T) {

View file

@ -24,7 +24,6 @@ func GenerateHMAC(data []byte, key string) []byte {
h := hmac.New(sha512.New512_256, []byte(key)) h := hmac.New(sha512.New512_256, []byte(key))
h.Write(data) h.Write(data)
return h.Sum(nil) return h.Sum(nil)
} }
// CheckHMAC securely checks the supplied MAC against a message using the // CheckHMAC securely checks the supplied MAC against a message using the

View file

@ -18,13 +18,15 @@ func TestPrivateJWKFromBytes(t *testing.T) {
want string want string
wantErr bool wantErr bool
}{ }{
{"good RS256", {
"good RS256",
"LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcGdJQkFBS0NBUUVBNjdLanFtUVlHcTBNVnRBQ1ZwZUNtWG1pbmxRYkRQR0xtc1pBVUV3dWVIUW5ydDNXCnR2cERPbTZBbGFKTVVuVytIdTU1ampva2FsS2VWalRLbWdZR2JxVXpWRG9NYlBEYUhla2x0ZEJUTUdsT1VGc1AKNFVKU0RyTzR6ZE4rem80MjhUWDJQbkcyRkNkVktHeTRQRThpbEhiV0xjcjg3MVlqVjUxZnc4Q0xEWDlQWkpOdQo4NjFDRjdWOWlFSm02c1NmUWxtbmhOOGozK1d6VmJQUU55MVdzUjdpOWU5ajYzRXFLdDIyUTlPWEwrV0FjS3NrCm9JU21DTlZSVUFqVThZUlZjZ1FKQit6UTM0QVFQbHowT3A1Ty9RTi9NZWRqYUY4d0xTK2l2L3p2aVM4Y3FQYngKbzZzTHE2Rk5UbHRrL1FreGVDZUtLVFFlLzNrUFl2UUFkbmw2NVFJREFRQUJBb0lCQVFEQVQ0eXN2V2pSY3pxcgpKcU9SeGFPQTJEY3dXazJML1JXOFhtQWhaRmRTWHV2MkNQbGxhTU1yelBmTG41WUlmaHQzSDNzODZnSEdZc3pnClo4aWJiYWtYNUdFQ0t5N3lRSDZuZ3hFS3pRVGpiampBNWR3S0h0UFhQUnJmamQ1Y2FMczVpcDcxaWxCWEYxU3IKWERIaXUycnFtaC9kVTArWGRMLzNmK2VnVDl6bFQ5YzRyUm84dnZueWNYejFyMnVhRVZ2VExsWHVsb2NpeEVrcgoySjlTMmxveWFUb2tFTnNlMDNpSVdaWnpNNElZcVowOGJOeG9IWCszQXVlWExIUStzRkRKMlhaVVdLSkZHMHUyClp3R2w3YlZpRTFQNXdiQUdtZzJDeDVCN1MrdGQyUEpSV3Frb2VxY3F2RVdCc3RFL1FEcDFpVThCOHpiQXd0Y3IKZHc5TXZ6Q2hBb0dCQVBObzRWMjF6MGp6MWdEb2tlTVN5d3JnL2E4RkJSM2R2Y0xZbWV5VXkybmd3eHVucnFsdwo2U2IrOWdrOGovcXEvc3VQSDhVdzNqSHNKYXdGSnNvTkVqNCt2b1ZSM3UrbE5sTEw5b21rMXBoU0dNdVp0b3huCm5nbUxVbkJUMGI1M3BURkJ5WGsveE5CbElreWdBNlg5T2MreW5na3RqNlRyVnMxUERTdnVJY0s1QW9HQkFQZmoKcEUzR2F6cVFSemx6TjRvTHZmQWJBdktCZ1lPaFNnemxsK0ZLZkhzYWJGNkdudFd1dWVhY1FIWFpYZTA1c2tLcApXN2xYQ3dqQU1iUXI3QmdlazcrOSszZElwL1RnYmZCYnN3Syt6Vng3Z2doeWMrdytXRWExaHByWTZ6YXdxdkFaCkhRU2lMUEd1UGp5WXBQa1E2ZFdEczNmWHJGZ1dlTmd4SkhTZkdaT05Bb0dCQUt5WTF3MUM2U3Y2c3VuTC8vNTcKQ2Z5NTAwaXlqNUZBOWRqZkRDNWt4K1JZMnlDV0ExVGsybjZyVmJ6dzg4czBTeDMrYS9IQW1CM2dMRXBSRU5NKwo5NHVwcENFWEQ3VHdlcGUxUnlrTStKbmp4TzlDSE41c2J2U25sUnBQWlMvZzJRTVhlZ3grK2trbkhXNG1ITkFyCndqMlRrMXBBczFXbkJ0TG9WaGVyY01jSkFvR0JBSTYwSGdJb0Y5SysvRUcyY21LbUg5SDV1dGlnZFU2eHEwK0IKWE0zMWMzUHE0amdJaDZlN3pvbFRxa2d0dWtTMjBraE45dC9ibkI2TmhnK1N1WGVwSXFWZldVUnlMejVwZE9ESgo2V1BMTTYzcDdCR3cwY3RPbU1NYi9VRm5Yd0U4OHlzRlNnOUF6VjdVVUQvU0lDYkI5ZHRVMWh4SHJJK0pZRWdWCkFrZWd6N2lCQW9HQkFJRncrQVFJZUIwM01UL0lCbGswNENQTDJEak0rNDhoVGRRdjgwMDBIQU9mUWJrMEVZUDEKQ2FLR3RDbTg2MXpBZjBzcS81REtZQ0l6OS9HUzNYRk00Qm1rRk9nY1NXVENPNmZmTGdLM3FmQzN4WDJudlpIOQpYZGNKTDQrZndhY0x4c2JJKzhhUWNOVHRtb3pkUjEzQnNmUmIrSGpUL2o3dkdrYlFnSkhCT0syegotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=", "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcGdJQkFBS0NBUUVBNjdLanFtUVlHcTBNVnRBQ1ZwZUNtWG1pbmxRYkRQR0xtc1pBVUV3dWVIUW5ydDNXCnR2cERPbTZBbGFKTVVuVytIdTU1ampva2FsS2VWalRLbWdZR2JxVXpWRG9NYlBEYUhla2x0ZEJUTUdsT1VGc1AKNFVKU0RyTzR6ZE4rem80MjhUWDJQbkcyRkNkVktHeTRQRThpbEhiV0xjcjg3MVlqVjUxZnc4Q0xEWDlQWkpOdQo4NjFDRjdWOWlFSm02c1NmUWxtbmhOOGozK1d6VmJQUU55MVdzUjdpOWU5ajYzRXFLdDIyUTlPWEwrV0FjS3NrCm9JU21DTlZSVUFqVThZUlZjZ1FKQit6UTM0QVFQbHowT3A1Ty9RTi9NZWRqYUY4d0xTK2l2L3p2aVM4Y3FQYngKbzZzTHE2Rk5UbHRrL1FreGVDZUtLVFFlLzNrUFl2UUFkbmw2NVFJREFRQUJBb0lCQVFEQVQ0eXN2V2pSY3pxcgpKcU9SeGFPQTJEY3dXazJML1JXOFhtQWhaRmRTWHV2MkNQbGxhTU1yelBmTG41WUlmaHQzSDNzODZnSEdZc3pnClo4aWJiYWtYNUdFQ0t5N3lRSDZuZ3hFS3pRVGpiampBNWR3S0h0UFhQUnJmamQ1Y2FMczVpcDcxaWxCWEYxU3IKWERIaXUycnFtaC9kVTArWGRMLzNmK2VnVDl6bFQ5YzRyUm84dnZueWNYejFyMnVhRVZ2VExsWHVsb2NpeEVrcgoySjlTMmxveWFUb2tFTnNlMDNpSVdaWnpNNElZcVowOGJOeG9IWCszQXVlWExIUStzRkRKMlhaVVdLSkZHMHUyClp3R2w3YlZpRTFQNXdiQUdtZzJDeDVCN1MrdGQyUEpSV3Frb2VxY3F2RVdCc3RFL1FEcDFpVThCOHpiQXd0Y3IKZHc5TXZ6Q2hBb0dCQVBObzRWMjF6MGp6MWdEb2tlTVN5d3JnL2E4RkJSM2R2Y0xZbWV5VXkybmd3eHVucnFsdwo2U2IrOWdrOGovcXEvc3VQSDhVdzNqSHNKYXdGSnNvTkVqNCt2b1ZSM3UrbE5sTEw5b21rMXBoU0dNdVp0b3huCm5nbUxVbkJUMGI1M3BURkJ5WGsveE5CbElreWdBNlg5T2MreW5na3RqNlRyVnMxUERTdnVJY0s1QW9HQkFQZmoKcEUzR2F6cVFSemx6TjRvTHZmQWJBdktCZ1lPaFNnemxsK0ZLZkhzYWJGNkdudFd1dWVhY1FIWFpYZTA1c2tLcApXN2xYQ3dqQU1iUXI3QmdlazcrOSszZElwL1RnYmZCYnN3Syt6Vng3Z2doeWMrdytXRWExaHByWTZ6YXdxdkFaCkhRU2lMUEd1UGp5WXBQa1E2ZFdEczNmWHJGZ1dlTmd4SkhTZkdaT05Bb0dCQUt5WTF3MUM2U3Y2c3VuTC8vNTcKQ2Z5NTAwaXlqNUZBOWRqZkRDNWt4K1JZMnlDV0ExVGsybjZyVmJ6dzg4czBTeDMrYS9IQW1CM2dMRXBSRU5NKwo5NHVwcENFWEQ3VHdlcGUxUnlrTStKbmp4TzlDSE41c2J2U25sUnBQWlMvZzJRTVhlZ3grK2trbkhXNG1ITkFyCndqMlRrMXBBczFXbkJ0TG9WaGVyY01jSkFvR0JBSTYwSGdJb0Y5SysvRUcyY21LbUg5SDV1dGlnZFU2eHEwK0IKWE0zMWMzUHE0amdJaDZlN3pvbFRxa2d0dWtTMjBraE45dC9ibkI2TmhnK1N1WGVwSXFWZldVUnlMejVwZE9ESgo2V1BMTTYzcDdCR3cwY3RPbU1NYi9VRm5Yd0U4OHlzRlNnOUF6VjdVVUQvU0lDYkI5ZHRVMWh4SHJJK0pZRWdWCkFrZWd6N2lCQW9HQkFJRncrQVFJZUIwM01UL0lCbGswNENQTDJEak0rNDhoVGRRdjgwMDBIQU9mUWJrMEVZUDEKQ2FLR3RDbTg2MXpBZjBzcS81REtZQ0l6OS9HUzNYRk00Qm1rRk9nY1NXVENPNmZmTGdLM3FmQzN4WDJudlpIOQpYZGNKTDQrZndhY0x4c2JJKzhhUWNOVHRtb3pkUjEzQnNmUmIrSGpUL2o3dkdrYlFnSkhCT0syegotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=",
jose.RS256, jose.RS256,
`{"use":"sig","kty":"RSA","kid":"f0cc8033b422c2a199dcb456dde29589a9f5edd27d1c345bdf308957e957becf","alg":"RS256","n":"67KjqmQYGq0MVtACVpeCmXminlQbDPGLmsZAUEwueHQnrt3WtvpDOm6AlaJMUnW-Hu55jjokalKeVjTKmgYGbqUzVDoMbPDaHekltdBTMGlOUFsP4UJSDrO4zdN-zo428TX2PnG2FCdVKGy4PE8ilHbWLcr871YjV51fw8CLDX9PZJNu861CF7V9iEJm6sSfQlmnhN8j3-WzVbPQNy1WsR7i9e9j63EqKt22Q9OXL-WAcKskoISmCNVRUAjU8YRVcgQJB-zQ34AQPlz0Op5O_QN_MedjaF8wLS-iv_zviS8cqPbxo6sLq6FNTltk_QkxeCeKKTQe_3kPYvQAdnl65Q","e":"AQAB","d":"wE-MrL1o0XM6qyajkcWjgNg3MFpNi_0VvF5gIWRXUl7r9gj5ZWjDK8z3y5-WCH4bdx97POoBxmLM4GfIm22pF-RhAisu8kB-p4MRCs0E4244wOXcCh7T1z0a343eXGi7OYqe9YpQVxdUq1wx4rtq6pof3VNPl3S_93_noE_c5U_XOK0aPL758nF89a9rmhFb0y5V7paHIsRJK9ifUtpaMmk6JBDbHtN4iFmWczOCGKmdPGzcaB1_twLnlyx0PrBQydl2VFiiRRtLtmcBpe21YhNT-cGwBpoNgseQe0vrXdjyUVqpKHqnKrxFgbLRP0A6dYlPAfM2wMLXK3cPTL8woQ","p":"82jhXbXPSPPWAOiR4xLLCuD9rwUFHd29wtiZ7JTLaeDDG6euqXDpJv72CTyP-qr-y48fxTDeMewlrAUmyg0SPj6-hVHe76U2Usv2iaTWmFIYy5m2jGeeCYtScFPRvnelMUHJeT_E0GUiTKADpf05z7KeCS2PpOtWzU8NK-4hwrk","q":"9-OkTcZrOpBHOXM3igu98BsC8oGBg6FKDOWX4Up8expsXoae1a655pxAddld7TmyQqlbuVcLCMAxtCvsGB6Tv737d0in9OBt8FuzAr7NXHuCCHJz7D5YRrWGmtjrNrCq8BkdBKIs8a4-PJik-RDp1YOzd9esWBZ42DEkdJ8Zk40","dp":"rJjXDULpK_qy6cv__nsJ_LnTSLKPkUD12N8MLmTH5FjbIJYDVOTafqtVvPDzyzRLHf5r8cCYHeAsSlEQ0z73i6mkIRcPtPB6l7VHKQz4mePE70Ic3mxu9KeVGk9lL-DZAxd6DH76SScdbiYc0CvCPZOTWkCzVacG0uhWF6twxwk","dq":"jrQeAigX0r78QbZyYqYf0fm62KB1TrGrT4FczfVzc-riOAiHp7vOiVOqSC26RLbSSE3239ucHo2GD5K5d6kipV9ZRHIvPml04MnpY8szrensEbDRy06Ywxv9QWdfATzzKwVKD0DNXtRQP9IgJsH121TWHEesj4lgSBUCR6DPuIE","qi":"gXD4BAh4HTcxP8gGWTTgI8vYOMz7jyFN1C_zTTQcA59BuTQRg_UJooa0KbzrXMB_Syr_kMpgIjP38ZLdcUzgGaQU6BxJZMI7p98uArep8LfFfae9kf1d1wkvj5_BpwvGxsj7xpBw1O2ajN1HXcGx9Fv4eNP-Pu8aRtCAkcE4rbM"}`, `{"use":"sig","kty":"RSA","kid":"f0cc8033b422c2a199dcb456dde29589a9f5edd27d1c345bdf308957e957becf","alg":"RS256","n":"67KjqmQYGq0MVtACVpeCmXminlQbDPGLmsZAUEwueHQnrt3WtvpDOm6AlaJMUnW-Hu55jjokalKeVjTKmgYGbqUzVDoMbPDaHekltdBTMGlOUFsP4UJSDrO4zdN-zo428TX2PnG2FCdVKGy4PE8ilHbWLcr871YjV51fw8CLDX9PZJNu861CF7V9iEJm6sSfQlmnhN8j3-WzVbPQNy1WsR7i9e9j63EqKt22Q9OXL-WAcKskoISmCNVRUAjU8YRVcgQJB-zQ34AQPlz0Op5O_QN_MedjaF8wLS-iv_zviS8cqPbxo6sLq6FNTltk_QkxeCeKKTQe_3kPYvQAdnl65Q","e":"AQAB","d":"wE-MrL1o0XM6qyajkcWjgNg3MFpNi_0VvF5gIWRXUl7r9gj5ZWjDK8z3y5-WCH4bdx97POoBxmLM4GfIm22pF-RhAisu8kB-p4MRCs0E4244wOXcCh7T1z0a343eXGi7OYqe9YpQVxdUq1wx4rtq6pof3VNPl3S_93_noE_c5U_XOK0aPL758nF89a9rmhFb0y5V7paHIsRJK9ifUtpaMmk6JBDbHtN4iFmWczOCGKmdPGzcaB1_twLnlyx0PrBQydl2VFiiRRtLtmcBpe21YhNT-cGwBpoNgseQe0vrXdjyUVqpKHqnKrxFgbLRP0A6dYlPAfM2wMLXK3cPTL8woQ","p":"82jhXbXPSPPWAOiR4xLLCuD9rwUFHd29wtiZ7JTLaeDDG6euqXDpJv72CTyP-qr-y48fxTDeMewlrAUmyg0SPj6-hVHe76U2Usv2iaTWmFIYy5m2jGeeCYtScFPRvnelMUHJeT_E0GUiTKADpf05z7KeCS2PpOtWzU8NK-4hwrk","q":"9-OkTcZrOpBHOXM3igu98BsC8oGBg6FKDOWX4Up8expsXoae1a655pxAddld7TmyQqlbuVcLCMAxtCvsGB6Tv737d0in9OBt8FuzAr7NXHuCCHJz7D5YRrWGmtjrNrCq8BkdBKIs8a4-PJik-RDp1YOzd9esWBZ42DEkdJ8Zk40","dp":"rJjXDULpK_qy6cv__nsJ_LnTSLKPkUD12N8MLmTH5FjbIJYDVOTafqtVvPDzyzRLHf5r8cCYHeAsSlEQ0z73i6mkIRcPtPB6l7VHKQz4mePE70Ic3mxu9KeVGk9lL-DZAxd6DH76SScdbiYc0CvCPZOTWkCzVacG0uhWF6twxwk","dq":"jrQeAigX0r78QbZyYqYf0fm62KB1TrGrT4FczfVzc-riOAiHp7vOiVOqSC26RLbSSE3239ucHo2GD5K5d6kipV9ZRHIvPml04MnpY8szrensEbDRy06Ywxv9QWdfATzzKwVKD0DNXtRQP9IgJsH121TWHEesj4lgSBUCR6DPuIE","qi":"gXD4BAh4HTcxP8gGWTTgI8vYOMz7jyFN1C_zTTQcA59BuTQRg_UJooa0KbzrXMB_Syr_kMpgIjP38ZLdcUzgGaQU6BxJZMI7p98uArep8LfFfae9kf1d1wkvj5_BpwvGxsj7xpBw1O2ajN1HXcGx9Fv4eNP-Pu8aRtCAkcE4rbM"}`,
false, false,
}, },
{"good SS256", {
"good SS256",
"LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUJlMFRxbXJkSXBZWE03c3pSRERWYndXOS83RWJHVWhTdFFJalhsVHNXM1BvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFb0xaRDI2bEdYREhRQmhhZkdlbEVmRDdlNmYzaURjWVJPVjdUbFlIdHF1Y1BFL2hId2dmYQpNY3FBUEZsRmpueUpySXJhYTFlQ2xZRTJ6UktTQk5kNXBRPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=", "LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUJlMFRxbXJkSXBZWE03c3pSRERWYndXOS83RWJHVWhTdFFJalhsVHNXM1BvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFb0xaRDI2bEdYREhRQmhhZkdlbEVmRDdlNmYzaURjWVJPVjdUbFlIdHF1Y1BFL2hId2dmYQpNY3FBUEZsRmpueUpySXJhYTFlQ2xZRTJ6UktTQk5kNXBRPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=",
jose.ES256, jose.ES256,
`{"use":"sig","kty":"EC","kid":"d591aa6e01e57ea8b80f349dc5de8517aa7b1f12f77700d89cbdba83938c0c61","crv":"P-256","alg":"ES256","x":"oLZD26lGXDHQBhafGelEfD7e6f3iDcYROV7TlYHtquc","y":"DxP4R8IH2jHKgDxZRY58iayK2mtXgpWBNs0SkgTXeaU","d":"F7ROqat0ilhczuzNEMNVvBb3_sRsZSFK1AiNeVOxbc8"}`, `{"use":"sig","kty":"EC","kid":"d591aa6e01e57ea8b80f349dc5de8517aa7b1f12f77700d89cbdba83938c0c61","crv":"P-256","alg":"ES256","x":"oLZD26lGXDHQBhafGelEfD7e6f3iDcYROV7TlYHtquc","y":"DxP4R8IH2jHKgDxZRY58iayK2mtXgpWBNs0SkgTXeaU","d":"F7ROqat0ilhczuzNEMNVvBb3_sRsZSFK1AiNeVOxbc8"}`,
@ -63,27 +65,31 @@ func TestPublicJWKFromBytes(t *testing.T) {
want string want string
wantErr bool wantErr bool
}{ }{
{"good RS256", {
"good RS256",
"LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcGdJQkFBS0NBUUVBNjdLanFtUVlHcTBNVnRBQ1ZwZUNtWG1pbmxRYkRQR0xtc1pBVUV3dWVIUW5ydDNXCnR2cERPbTZBbGFKTVVuVytIdTU1ampva2FsS2VWalRLbWdZR2JxVXpWRG9NYlBEYUhla2x0ZEJUTUdsT1VGc1AKNFVKU0RyTzR6ZE4rem80MjhUWDJQbkcyRkNkVktHeTRQRThpbEhiV0xjcjg3MVlqVjUxZnc4Q0xEWDlQWkpOdQo4NjFDRjdWOWlFSm02c1NmUWxtbmhOOGozK1d6VmJQUU55MVdzUjdpOWU5ajYzRXFLdDIyUTlPWEwrV0FjS3NrCm9JU21DTlZSVUFqVThZUlZjZ1FKQit6UTM0QVFQbHowT3A1Ty9RTi9NZWRqYUY4d0xTK2l2L3p2aVM4Y3FQYngKbzZzTHE2Rk5UbHRrL1FreGVDZUtLVFFlLzNrUFl2UUFkbmw2NVFJREFRQUJBb0lCQVFEQVQ0eXN2V2pSY3pxcgpKcU9SeGFPQTJEY3dXazJML1JXOFhtQWhaRmRTWHV2MkNQbGxhTU1yelBmTG41WUlmaHQzSDNzODZnSEdZc3pnClo4aWJiYWtYNUdFQ0t5N3lRSDZuZ3hFS3pRVGpiampBNWR3S0h0UFhQUnJmamQ1Y2FMczVpcDcxaWxCWEYxU3IKWERIaXUycnFtaC9kVTArWGRMLzNmK2VnVDl6bFQ5YzRyUm84dnZueWNYejFyMnVhRVZ2VExsWHVsb2NpeEVrcgoySjlTMmxveWFUb2tFTnNlMDNpSVdaWnpNNElZcVowOGJOeG9IWCszQXVlWExIUStzRkRKMlhaVVdLSkZHMHUyClp3R2w3YlZpRTFQNXdiQUdtZzJDeDVCN1MrdGQyUEpSV3Frb2VxY3F2RVdCc3RFL1FEcDFpVThCOHpiQXd0Y3IKZHc5TXZ6Q2hBb0dCQVBObzRWMjF6MGp6MWdEb2tlTVN5d3JnL2E4RkJSM2R2Y0xZbWV5VXkybmd3eHVucnFsdwo2U2IrOWdrOGovcXEvc3VQSDhVdzNqSHNKYXdGSnNvTkVqNCt2b1ZSM3UrbE5sTEw5b21rMXBoU0dNdVp0b3huCm5nbUxVbkJUMGI1M3BURkJ5WGsveE5CbElreWdBNlg5T2MreW5na3RqNlRyVnMxUERTdnVJY0s1QW9HQkFQZmoKcEUzR2F6cVFSemx6TjRvTHZmQWJBdktCZ1lPaFNnemxsK0ZLZkhzYWJGNkdudFd1dWVhY1FIWFpYZTA1c2tLcApXN2xYQ3dqQU1iUXI3QmdlazcrOSszZElwL1RnYmZCYnN3Syt6Vng3Z2doeWMrdytXRWExaHByWTZ6YXdxdkFaCkhRU2lMUEd1UGp5WXBQa1E2ZFdEczNmWHJGZ1dlTmd4SkhTZkdaT05Bb0dCQUt5WTF3MUM2U3Y2c3VuTC8vNTcKQ2Z5NTAwaXlqNUZBOWRqZkRDNWt4K1JZMnlDV0ExVGsybjZyVmJ6dzg4czBTeDMrYS9IQW1CM2dMRXBSRU5NKwo5NHVwcENFWEQ3VHdlcGUxUnlrTStKbmp4TzlDSE41c2J2U25sUnBQWlMvZzJRTVhlZ3grK2trbkhXNG1ITkFyCndqMlRrMXBBczFXbkJ0TG9WaGVyY01jSkFvR0JBSTYwSGdJb0Y5SysvRUcyY21LbUg5SDV1dGlnZFU2eHEwK0IKWE0zMWMzUHE0amdJaDZlN3pvbFRxa2d0dWtTMjBraE45dC9ibkI2TmhnK1N1WGVwSXFWZldVUnlMejVwZE9ESgo2V1BMTTYzcDdCR3cwY3RPbU1NYi9VRm5Yd0U4OHlzRlNnOUF6VjdVVUQvU0lDYkI5ZHRVMWh4SHJJK0pZRWdWCkFrZWd6N2lCQW9HQkFJRncrQVFJZUIwM01UL0lCbGswNENQTDJEak0rNDhoVGRRdjgwMDBIQU9mUWJrMEVZUDEKQ2FLR3RDbTg2MXpBZjBzcS81REtZQ0l6OS9HUzNYRk00Qm1rRk9nY1NXVENPNmZmTGdLM3FmQzN4WDJudlpIOQpYZGNKTDQrZndhY0x4c2JJKzhhUWNOVHRtb3pkUjEzQnNmUmIrSGpUL2o3dkdrYlFnSkhCT0syegotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=", "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcGdJQkFBS0NBUUVBNjdLanFtUVlHcTBNVnRBQ1ZwZUNtWG1pbmxRYkRQR0xtc1pBVUV3dWVIUW5ydDNXCnR2cERPbTZBbGFKTVVuVytIdTU1ampva2FsS2VWalRLbWdZR2JxVXpWRG9NYlBEYUhla2x0ZEJUTUdsT1VGc1AKNFVKU0RyTzR6ZE4rem80MjhUWDJQbkcyRkNkVktHeTRQRThpbEhiV0xjcjg3MVlqVjUxZnc4Q0xEWDlQWkpOdQo4NjFDRjdWOWlFSm02c1NmUWxtbmhOOGozK1d6VmJQUU55MVdzUjdpOWU5ajYzRXFLdDIyUTlPWEwrV0FjS3NrCm9JU21DTlZSVUFqVThZUlZjZ1FKQit6UTM0QVFQbHowT3A1Ty9RTi9NZWRqYUY4d0xTK2l2L3p2aVM4Y3FQYngKbzZzTHE2Rk5UbHRrL1FreGVDZUtLVFFlLzNrUFl2UUFkbmw2NVFJREFRQUJBb0lCQVFEQVQ0eXN2V2pSY3pxcgpKcU9SeGFPQTJEY3dXazJML1JXOFhtQWhaRmRTWHV2MkNQbGxhTU1yelBmTG41WUlmaHQzSDNzODZnSEdZc3pnClo4aWJiYWtYNUdFQ0t5N3lRSDZuZ3hFS3pRVGpiampBNWR3S0h0UFhQUnJmamQ1Y2FMczVpcDcxaWxCWEYxU3IKWERIaXUycnFtaC9kVTArWGRMLzNmK2VnVDl6bFQ5YzRyUm84dnZueWNYejFyMnVhRVZ2VExsWHVsb2NpeEVrcgoySjlTMmxveWFUb2tFTnNlMDNpSVdaWnpNNElZcVowOGJOeG9IWCszQXVlWExIUStzRkRKMlhaVVdLSkZHMHUyClp3R2w3YlZpRTFQNXdiQUdtZzJDeDVCN1MrdGQyUEpSV3Frb2VxY3F2RVdCc3RFL1FEcDFpVThCOHpiQXd0Y3IKZHc5TXZ6Q2hBb0dCQVBObzRWMjF6MGp6MWdEb2tlTVN5d3JnL2E4RkJSM2R2Y0xZbWV5VXkybmd3eHVucnFsdwo2U2IrOWdrOGovcXEvc3VQSDhVdzNqSHNKYXdGSnNvTkVqNCt2b1ZSM3UrbE5sTEw5b21rMXBoU0dNdVp0b3huCm5nbUxVbkJUMGI1M3BURkJ5WGsveE5CbElreWdBNlg5T2MreW5na3RqNlRyVnMxUERTdnVJY0s1QW9HQkFQZmoKcEUzR2F6cVFSemx6TjRvTHZmQWJBdktCZ1lPaFNnemxsK0ZLZkhzYWJGNkdudFd1dWVhY1FIWFpYZTA1c2tLcApXN2xYQ3dqQU1iUXI3QmdlazcrOSszZElwL1RnYmZCYnN3Syt6Vng3Z2doeWMrdytXRWExaHByWTZ6YXdxdkFaCkhRU2lMUEd1UGp5WXBQa1E2ZFdEczNmWHJGZ1dlTmd4SkhTZkdaT05Bb0dCQUt5WTF3MUM2U3Y2c3VuTC8vNTcKQ2Z5NTAwaXlqNUZBOWRqZkRDNWt4K1JZMnlDV0ExVGsybjZyVmJ6dzg4czBTeDMrYS9IQW1CM2dMRXBSRU5NKwo5NHVwcENFWEQ3VHdlcGUxUnlrTStKbmp4TzlDSE41c2J2U25sUnBQWlMvZzJRTVhlZ3grK2trbkhXNG1ITkFyCndqMlRrMXBBczFXbkJ0TG9WaGVyY01jSkFvR0JBSTYwSGdJb0Y5SysvRUcyY21LbUg5SDV1dGlnZFU2eHEwK0IKWE0zMWMzUHE0amdJaDZlN3pvbFRxa2d0dWtTMjBraE45dC9ibkI2TmhnK1N1WGVwSXFWZldVUnlMejVwZE9ESgo2V1BMTTYzcDdCR3cwY3RPbU1NYi9VRm5Yd0U4OHlzRlNnOUF6VjdVVUQvU0lDYkI5ZHRVMWh4SHJJK0pZRWdWCkFrZWd6N2lCQW9HQkFJRncrQVFJZUIwM01UL0lCbGswNENQTDJEak0rNDhoVGRRdjgwMDBIQU9mUWJrMEVZUDEKQ2FLR3RDbTg2MXpBZjBzcS81REtZQ0l6OS9HUzNYRk00Qm1rRk9nY1NXVENPNmZmTGdLM3FmQzN4WDJudlpIOQpYZGNKTDQrZndhY0x4c2JJKzhhUWNOVHRtb3pkUjEzQnNmUmIrSGpUL2o3dkdrYlFnSkhCT0syegotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=",
jose.RS256, jose.RS256,
`{"use":"sig","kty":"RSA","kid":"f0cc8033b422c2a199dcb456dde29589a9f5edd27d1c345bdf308957e957becf","alg":"RS256","n":"67KjqmQYGq0MVtACVpeCmXminlQbDPGLmsZAUEwueHQnrt3WtvpDOm6AlaJMUnW-Hu55jjokalKeVjTKmgYGbqUzVDoMbPDaHekltdBTMGlOUFsP4UJSDrO4zdN-zo428TX2PnG2FCdVKGy4PE8ilHbWLcr871YjV51fw8CLDX9PZJNu861CF7V9iEJm6sSfQlmnhN8j3-WzVbPQNy1WsR7i9e9j63EqKt22Q9OXL-WAcKskoISmCNVRUAjU8YRVcgQJB-zQ34AQPlz0Op5O_QN_MedjaF8wLS-iv_zviS8cqPbxo6sLq6FNTltk_QkxeCeKKTQe_3kPYvQAdnl65Q","e":"AQAB"}`, `{"use":"sig","kty":"RSA","kid":"f0cc8033b422c2a199dcb456dde29589a9f5edd27d1c345bdf308957e957becf","alg":"RS256","n":"67KjqmQYGq0MVtACVpeCmXminlQbDPGLmsZAUEwueHQnrt3WtvpDOm6AlaJMUnW-Hu55jjokalKeVjTKmgYGbqUzVDoMbPDaHekltdBTMGlOUFsP4UJSDrO4zdN-zo428TX2PnG2FCdVKGy4PE8ilHbWLcr871YjV51fw8CLDX9PZJNu861CF7V9iEJm6sSfQlmnhN8j3-WzVbPQNy1WsR7i9e9j63EqKt22Q9OXL-WAcKskoISmCNVRUAjU8YRVcgQJB-zQ34AQPlz0Op5O_QN_MedjaF8wLS-iv_zviS8cqPbxo6sLq6FNTltk_QkxeCeKKTQe_3kPYvQAdnl65Q","e":"AQAB"}`,
false, false,
}, },
{"good ES256", {
"good ES256",
"LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUJlMFRxbXJkSXBZWE03c3pSRERWYndXOS83RWJHVWhTdFFJalhsVHNXM1BvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFb0xaRDI2bEdYREhRQmhhZkdlbEVmRDdlNmYzaURjWVJPVjdUbFlIdHF1Y1BFL2hId2dmYQpNY3FBUEZsRmpueUpySXJhYTFlQ2xZRTJ6UktTQk5kNXBRPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=", "LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUJlMFRxbXJkSXBZWE03c3pSRERWYndXOS83RWJHVWhTdFFJalhsVHNXM1BvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFb0xaRDI2bEdYREhRQmhhZkdlbEVmRDdlNmYzaURjWVJPVjdUbFlIdHF1Y1BFL2hId2dmYQpNY3FBUEZsRmpueUpySXJhYTFlQ2xZRTJ6UktTQk5kNXBRPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=",
jose.ES256, jose.ES256,
`{"use":"sig","kty":"EC","kid":"d591aa6e01e57ea8b80f349dc5de8517aa7b1f12f77700d89cbdba83938c0c61","crv":"P-256","alg":"ES256","x":"oLZD26lGXDHQBhafGelEfD7e6f3iDcYROV7TlYHtquc","y":"DxP4R8IH2jHKgDxZRY58iayK2mtXgpWBNs0SkgTXeaU"}`, `{"use":"sig","kty":"EC","kid":"d591aa6e01e57ea8b80f349dc5de8517aa7b1f12f77700d89cbdba83938c0c61","crv":"P-256","alg":"ES256","x":"oLZD26lGXDHQBhafGelEfD7e6f3iDcYROV7TlYHtquc","y":"DxP4R8IH2jHKgDxZRY58iayK2mtXgpWBNs0SkgTXeaU"}`,
false, false,
}, },
{"good ed25519", {
"good ed25519",
"LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1DNENBUUF3QlFZREsyVndCQ0lFSUZiNDN6SkVqblMvOHdxZVMwRlhiNDNWdlV5ZmhRL3UvWGd3UVV2bDVnaloKLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo=", "LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1DNENBUUF3QlFZREsyVndCQ0lFSUZiNDN6SkVqblMvOHdxZVMwRlhiNDNWdlV5ZmhRL3UvWGd3UVV2bDVnaloKLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo=",
jose.EdDSA, jose.EdDSA,
`{"use":"sig","kty":"OKP","kid":"3aa847838906f3c930f55c2d5885943ac7bede8f780d388015575334f88e77ef","crv":"Ed25519","alg":"EdDSA","x":"xsg1A67wECXAmRnSib8lSsgatcNcYm7vvspQnocPQNc"}`, `{"use":"sig","kty":"OKP","kid":"3aa847838906f3c930f55c2d5885943ac7bede8f780d388015575334f88e77ef","crv":"Ed25519","alg":"EdDSA","x":"xsg1A67wECXAmRnSib8lSsgatcNcYm7vvspQnocPQNc"}`,
false, false,
}, },
{"bad key decode", {
"bad key decode",
"LS0t", "LS0t",
jose.RS256, jose.RS256,
`null`, `null`,

View file

@ -47,9 +47,9 @@ func GetCertPool(ca, caFile string) (*x509.CertPool, error) {
// Finally if there are no matching certificates one will be generated. // Finally if there are no matching certificates one will be generated.
func GetCertificateForDomain(certificates []tls.Certificate, domain string) (*tls.Certificate, error) { func GetCertificateForDomain(certificates []tls.Certificate, domain string) (*tls.Certificate, error) {
// first try a direct name match // first try a direct name match
for _, cert := range certificates { for i := range certificates {
if matchesDomain(&cert, domain) { if matchesDomain(&certificates[i], domain) {
return &cert, nil return &certificates[i], nil
} }
} }

View file

@ -103,7 +103,7 @@ func NewGRPCClientConn(opts *Options) (*grpc.ClientConn, error) {
return nil, err return nil, err
} }
cert := credentials.NewTLS(&tls.Config{RootCAs: rootCAs}) cert := credentials.NewTLS(&tls.Config{RootCAs: rootCAs, MinVersion: tls.VersionTLS12})
// override allowed certificate name string, typically used when doing behind ingress connection // override allowed certificate name string, typically used when doing behind ingress connection
if opts.OverrideCertificateName != "" { if opts.OverrideCertificateName != "" {

View file

@ -12,7 +12,6 @@ import (
) )
func Test_grpcTimeoutInterceptor(t *testing.T) { func Test_grpcTimeoutInterceptor(t *testing.T) {
mockInvoker := func(sleepTime time.Duration, wantFail bool) grpc.UnaryInvoker { mockInvoker := func(sleepTime time.Duration, wantFail bool) grpc.UnaryInvoker {
return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, opts ...grpc.CallOption) error { return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, opts ...grpc.CallOption) error {
time.Sleep(sleepTime) time.Sleep(sleepTime)
@ -37,7 +36,6 @@ func Test_grpcTimeoutInterceptor(t *testing.T) {
to(context.Background(), "test", nil, nil, nil, mockInvoker(timeOut*2, true)) to(context.Background(), "test", nil, nil, nil, mockInvoker(timeOut*2, true))
to(context.Background(), "test", nil, nil, nil, mockInvoker(timeOut/2, false)) to(context.Background(), "test", nil, nil, nil, mockInvoker(timeOut/2, false))
} }
func TestNewGRPC(t *testing.T) { func TestNewGRPC(t *testing.T) {
@ -73,7 +71,6 @@ func TestNewGRPC(t *testing.T) {
} }
if got != nil && got.Target() != tt.wantTarget { if got != nil && got.Target() != tt.wantTarget {
t.Errorf("New() target = %v expected %v", got.Target(), tt.wantTarget) t.Errorf("New() target = %v expected %v", got.Target(), tt.wantTarget)
} }
}) })
} }

View file

@ -124,7 +124,6 @@ func TestProxy_SignOut(t *testing.T) {
if status := w.Code; status != tt.wantStatus { if status := w.Code; status != tt.wantStatus {
t.Errorf("status code: got %v want %v", status, tt.wantStatus) t.Errorf("status code: got %v want %v", status, tt.wantStatus)
} }
}) })
} }
} }
@ -344,7 +343,6 @@ func TestProxy_ProgrammaticLogin(t *testing.T) {
t.Errorf("wrong body\n%s", diff) t.Errorf("wrong body\n%s", diff)
} }
} }
}) })
} }
} }
@ -386,9 +384,11 @@ func TestProxy_ProgrammaticCallback(t *testing.T) {
http.MethodGet, http.MethodGet,
"http://pomerium.io/", "http://pomerium.io/",
nil, nil,
map[string]string{urlutil.QueryIsProgrammatic: "true", map[string]string{
urlutil.QueryIsProgrammatic: "true",
urlutil.QueryCallbackURI: "ok", urlutil.QueryCallbackURI: "ok",
urlutil.QuerySessionEncrypted: goodEncryptionString}, urlutil.QuerySessionEncrypted: goodEncryptionString,
},
&mock.Encoder{MarshalResponse: []byte("x")}, &mock.Encoder{MarshalResponse: []byte("x")},
&mstore.Store{Session: &sessions.State{Expiry: jwt.NewNumericDate(time.Now().Add(10 * time.Minute))}}, &mstore.Store{Session: &sessions.State{Expiry: jwt.NewNumericDate(time.Now().Add(10 * time.Minute))}},
http.StatusFound, http.StatusFound,
@ -497,7 +497,6 @@ func TestProxy_ProgrammaticCallback(t *testing.T) {
} }
func TestProxy_jwt(t *testing.T) { func TestProxy_jwt(t *testing.T) {
// without downstream headers being set // without downstream headers being set
req, _ := http.NewRequest("GET", "https://www.example.com/.pomerium/jwt", nil) req, _ := http.NewRequest("GET", "https://www.example.com/.pomerium/jwt", nil)
w := httptest.NewRecorder() w := httptest.NewRecorder()

View file

@ -79,7 +79,8 @@ func newProxyStateFromConfig(cfg *config.Config) (*proxyState, error) {
state.sessionLoaders = []sessions.SessionLoader{ state.sessionLoaders = []sessions.SessionLoader{
state.sessionStore, state.sessionStore,
header.NewStore(state.encoder, httputil.AuthorizationTypePomerium), header.NewStore(state.encoder, httputil.AuthorizationTypePomerium),
queryparam.NewStore(state.encoder, "pomerium_session")} queryparam.NewStore(state.encoder, "pomerium_session"),
}
return state, nil return state, nil
} }