From de98e27c9eb0d4229b52a0ebb921a8d6c6ce56b8 Mon Sep 17 00:00:00 2001 From: alessandro-Doyensec Date: Fri, 28 Nov 2025 15:32:45 +0100 Subject: [PATCH 01/11] init --- .../gitbasicauth/codecatalyst/codecatalyst.go | 23 ++++++++ .../gitbasicauth/codecatalyst/detector.go | 52 +++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 veles/secrets/gitbasicauth/codecatalyst/codecatalyst.go create mode 100644 veles/secrets/gitbasicauth/codecatalyst/detector.go diff --git a/veles/secrets/gitbasicauth/codecatalyst/codecatalyst.go b/veles/secrets/gitbasicauth/codecatalyst/codecatalyst.go new file mode 100644 index 000000000..395849c2c --- /dev/null +++ b/veles/secrets/gitbasicauth/codecatalyst/codecatalyst.go @@ -0,0 +1,23 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package codecatalyst contains the logic to extract CodeCatalyst credentials. +package codecatalyst + +// Credentials contains basic auth credential for CodeCatalyst. +type Credentials struct { + FullURL string + Username string + Password string +} diff --git a/veles/secrets/gitbasicauth/codecatalyst/detector.go b/veles/secrets/gitbasicauth/codecatalyst/detector.go new file mode 100644 index 000000000..9ed9ee34b --- /dev/null +++ b/veles/secrets/gitbasicauth/codecatalyst/detector.go @@ -0,0 +1,52 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package codecatalyst + +import ( + "regexp" + + "github.com/google/osv-scalibr/veles" +) + +const ( + maxURLLength = 1_000 +) + +var ( + urlPattern = regexp.MustCompile(`\bhttps://([^:\s]+):([^\s@]+)@[^/]*codecatalyst\.aws/[^\s]*`) +) + +type detector struct{} + +func NewDetector() veles.Detector { + return &detector{} +} + +func (d *detector) MaxSecretLen() uint32 { + return maxURLLength +} + +func (d *detector) Detect(data []byte) ([]veles.Secret, []int) { + secrets, positions := []veles.Secret{}, []int{} + matches := urlPattern.FindAllSubmatchIndex(data, -1) + for _, m := range matches { + secrets = append(secrets, Credentials{ + FullURL: string(data[m[0]:m[1]]), + Username: string(data[m[2]:m[3]]), + Password: string(data[m[4]:m[5]]), + }) + } + return secrets, positions +} From 272502abaf37c76ffae0335d8e7c20e62932a884 Mon Sep 17 00:00:00 2001 From: alessandro-Doyensec Date: Fri, 28 Nov 2025 17:45:48 +0100 Subject: [PATCH 02/11] add: validator --- .../gitbasicauth/codecatalyst/codecatalyst.go | 2 +- .../gitbasicauth/codecatalyst/detector.go | 31 ++++++++-- .../gitbasicauth/codecatalyst/validator.go | 59 +++++++++++++++++++ veles/secrets/gitbasicauth/gitbasicauth.go | 55 +++++++++++++++++ 4 files changed, 142 insertions(+), 5 deletions(-) create mode 100644 veles/secrets/gitbasicauth/codecatalyst/validator.go create mode 100644 veles/secrets/gitbasicauth/gitbasicauth.go diff --git a/veles/secrets/gitbasicauth/codecatalyst/codecatalyst.go b/veles/secrets/gitbasicauth/codecatalyst/codecatalyst.go index 395849c2c..95ef77858 100644 --- a/veles/secrets/gitbasicauth/codecatalyst/codecatalyst.go +++ b/veles/secrets/gitbasicauth/codecatalyst/codecatalyst.go @@ -19,5 +19,5 @@ package codecatalyst type Credentials struct { FullURL string Username string - Password string + PAT string } diff --git a/veles/secrets/gitbasicauth/codecatalyst/detector.go b/veles/secrets/gitbasicauth/codecatalyst/detector.go index 9ed9ee34b..1fb157bd1 100644 --- a/veles/secrets/gitbasicauth/codecatalyst/detector.go +++ b/veles/secrets/gitbasicauth/codecatalyst/detector.go @@ -15,37 +15,60 @@ package codecatalyst import ( + "net/url" "regexp" "github.com/google/osv-scalibr/veles" ) const ( + // maxURLLength is an upper bound value for the length of a URL to be considered. + // This helps limit the buffer size required for scanning. maxURLLength = 1_000 ) var ( - urlPattern = regexp.MustCompile(`\bhttps://([^:\s]+):([^\s@]+)@[^/]*codecatalyst\.aws/[^\s]*`) + // urlPattern matches URLs containing basic authentication credentials. + urlPattern = regexp.MustCompile(`\bhttps://[^:\s]+:[^\s@]+@[^/]*codecatalyst\.aws/[^\s]*`) ) type detector struct{} +// NewDetector creates and returns a new instance of the CodeCatalyst secret detector. func NewDetector() veles.Detector { return &detector{} } +// MaxSecretLen returns the maximum expected length of the secret. func (d *detector) MaxSecretLen() uint32 { return maxURLLength } +// Detect scans the provided byte slice for AWS CodeCatalyst credentials. func (d *detector) Detect(data []byte) ([]veles.Secret, []int) { secrets, positions := []veles.Secret{}, []int{} matches := urlPattern.FindAllSubmatchIndex(data, -1) for _, m := range matches { + fullURL := data[m[0]:m[1]] + u, err := url.Parse(string(fullURL)) + if err != nil { + continue + } + if u.User == nil { + continue + } + username := u.User.Username() + if username == "" { + continue + } + password, ok := u.User.Password() + if !ok { + continue + } secrets = append(secrets, Credentials{ - FullURL: string(data[m[0]:m[1]]), - Username: string(data[m[2]:m[3]]), - Password: string(data[m[4]:m[5]]), + FullURL: u.String(), + Username: username, + PAT: password, }) } return secrets, positions diff --git a/veles/secrets/gitbasicauth/codecatalyst/validator.go b/veles/secrets/gitbasicauth/codecatalyst/validator.go new file mode 100644 index 000000000..ec929ab7a --- /dev/null +++ b/veles/secrets/gitbasicauth/codecatalyst/validator.go @@ -0,0 +1,59 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package codecatalyst + +import ( + "context" + "fmt" + "net/http" + "net/url" + "strings" + + "github.com/google/osv-scalibr/veles" + "github.com/google/osv-scalibr/veles/secrets/gitbasicauth" +) + +type validator struct { + cli *http.Client +} + +// SetHTTPClient sets the http.Client which the validator uses. +func (v *validator) SetHTTPClient(cli *http.Client) { + v.cli = cli +} + +// NewValidator creates a new Validator that validates Code Catalyst credentials +func NewValidator() veles.Validator[Credentials] { + return &validator{ + cli: http.DefaultClient, + } +} + +// Validate validates code AWS Code Catalyst Git Basic Auth credentials +func (v *validator) Validate(ctx context.Context, secret Credentials) (veles.ValidationStatus, error) { + u, err := url.Parse(secret.FullURL) + if err != nil { + return veles.ValidationFailed, fmt.Errorf("error parsing URL: %w", err) + } + + if !strings.HasSuffix(u.Host, ".codecatalyst.aws") { + return veles.ValidationFailed, fmt.Errorf("not a valid AWS Code Catalyst host %q", u.Host) + } + + return gitbasicauth.Validate( + ctx, v.cli, u, + gitbasicauth.Credentials{Username: secret.Username, Password: secret.PAT}, + ) +} diff --git a/veles/secrets/gitbasicauth/gitbasicauth.go b/veles/secrets/gitbasicauth/gitbasicauth.go new file mode 100644 index 000000000..d948f3826 --- /dev/null +++ b/veles/secrets/gitbasicauth/gitbasicauth.go @@ -0,0 +1,55 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package gitbasicauth contains common logic for Git basic auth. +package gitbasicauth + +import ( + "context" + "fmt" + "net/http" + "net/url" + + "github.com/google/osv-scalibr/veles" +) + +// Credentials contains git basic auth credentials. +type Credentials struct { + Username string + Password string +} + +// Validate validates git credential against the given repoUrl. +func Validate(ctx context.Context, cli *http.Client, repoUrl *url.URL, creds Credentials) (veles.ValidationStatus, error) { + u := repoUrl.JoinPath("info/refs") + u.RawQuery = "service=git-upload-pack" + + req, err := http.NewRequestWithContext(ctx, "GET", u.String(), nil) + if err != nil { + return veles.ValidationFailed, fmt.Errorf("error building request: %w", err) + } + req.SetBasicAuth(creds.Username, creds.Password) + + resp, err := cli.Do(req) + if err != nil { + return veles.ValidationFailed, fmt.Errorf("error executing request: %w", err) + } + defer resp.Body.Close() + + if resp.StatusCode == http.StatusOK { + return veles.ValidationValid, nil + } + + return veles.ValidationInvalid, nil +} From fc086ee2332161a6a251e2374478ee4b4691efb9 Mon Sep 17 00:00:00 2001 From: alessandro-Doyensec Date: Mon, 1 Dec 2025 16:31:31 +0100 Subject: [PATCH 03/11] add: tests --- .../gitbasicauth/codecatalyst/codecatalyst.go | 4 +- .../gitbasicauth/codecatalyst/detector.go | 26 ++-- .../codecatalyst/detector_test.go | 125 +++++++++++++++ .../gitbasicauth/codecatalyst/validator.go | 36 +++-- .../codecatalyst/validator_test.go | 143 ++++++++++++++++++ veles/secrets/gitbasicauth/gitbasicauth.go | 32 ++-- 6 files changed, 313 insertions(+), 53 deletions(-) create mode 100644 veles/secrets/gitbasicauth/codecatalyst/detector_test.go create mode 100644 veles/secrets/gitbasicauth/codecatalyst/validator_test.go diff --git a/veles/secrets/gitbasicauth/codecatalyst/codecatalyst.go b/veles/secrets/gitbasicauth/codecatalyst/codecatalyst.go index 95ef77858..2ba844c3b 100644 --- a/veles/secrets/gitbasicauth/codecatalyst/codecatalyst.go +++ b/veles/secrets/gitbasicauth/codecatalyst/codecatalyst.go @@ -17,7 +17,5 @@ package codecatalyst // Credentials contains basic auth credential for CodeCatalyst. type Credentials struct { - FullURL string - Username string - PAT string + FullURL string } diff --git a/veles/secrets/gitbasicauth/codecatalyst/detector.go b/veles/secrets/gitbasicauth/codecatalyst/detector.go index 1fb157bd1..402b50fb4 100644 --- a/veles/secrets/gitbasicauth/codecatalyst/detector.go +++ b/veles/secrets/gitbasicauth/codecatalyst/detector.go @@ -29,7 +29,7 @@ const ( var ( // urlPattern matches URLs containing basic authentication credentials. - urlPattern = regexp.MustCompile(`\bhttps://[^:\s]+:[^\s@]+@[^/]*codecatalyst\.aws/[^\s]*`) + urlPattern = regexp.MustCompile(`\bhttps://[^:\s]+:[^\s@]+@git\.[^/]*codecatalyst\.aws/[^\s]*`) ) type detector struct{} @@ -54,22 +54,18 @@ func (d *detector) Detect(data []byte) ([]veles.Secret, []int) { if err != nil { continue } - if u.User == nil { + if !hasValidCredentials(u) { continue } - username := u.User.Username() - if username == "" { - continue - } - password, ok := u.User.Password() - if !ok { - continue - } - secrets = append(secrets, Credentials{ - FullURL: u.String(), - Username: username, - PAT: password, - }) + secrets = append(secrets, Credentials{FullURL: u.String()}) } return secrets, positions } + +func hasValidCredentials(u *url.URL) bool { + if u.User == nil || u.User.Username() == "" { + return false + } + _, hasPassword := u.User.Password() + return hasPassword +} diff --git a/veles/secrets/gitbasicauth/codecatalyst/detector_test.go b/veles/secrets/gitbasicauth/codecatalyst/detector_test.go new file mode 100644 index 000000000..35dd800c8 --- /dev/null +++ b/veles/secrets/gitbasicauth/codecatalyst/detector_test.go @@ -0,0 +1,125 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package codecatalyst_test + +import ( + "strings" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/google/osv-scalibr/veles" + "github.com/google/osv-scalibr/veles/secrets/gitbasicauth/codecatalyst" +) + +const ( + testURL = `https://user:password@git.region.codecatalyst.aws/v1/space/project/repo` + anotherURL = `https://another:acsp03irh932r4@git.region.codecatalyst.aws/v1/space2/project/test-repo` +) + +// TestDetector_truePositives tests for cases where we know the Detector +// will find CodeCatalyst credentials. +func TestDetector_truePositives(t *testing.T) { + engine, err := veles.NewDetectionEngine([]veles.Detector{codecatalyst.NewDetector()}) + if err != nil { + t.Fatal(err) + } + cases := []struct { + name string + input string + want []veles.Secret + }{ + { + name: "simple_matching_string", + input: testURL, + want: []veles.Secret{ + codecatalyst.Credentials{FullURL: testURL}, + }, + }, + { + name: "git_config", + input: ` + [core] + repositoryformatversion = 0 + filemode = true + bare = false + logallrefupdates = true + ignorecase = true + precomposeunicode = true +[remote "origin"] + url = https://user:password@git.region.codecatalyst.aws/v1/space/project/repo + fetch = +refs/heads/*:refs/remotes/origin/* +[branch "main"] + remote = origin + merge = refs/heads/main +`, + want: []veles.Secret{ + codecatalyst.Credentials{FullURL: testURL}, + }, + }, + { + name: "multiple_distinct_matches", + input: testURL + "\n" + anotherURL, + want: []veles.Secret{ + codecatalyst.Credentials{FullURL: testURL}, + codecatalyst.Credentials{FullURL: anotherURL}, + }, + }, + } + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + got, err := engine.Detect(t.Context(), strings.NewReader(tc.input)) + if err != nil { + t.Errorf("Detect() error: %v, want nil", err) + } + if diff := cmp.Diff(tc.want, got, cmpopts.EquateEmpty()); diff != "" { + t.Errorf("Detect() diff (-want +got):\n%s", diff) + } + }) + } +} + +// TestDetector_trueNegatives tests for cases where we know the Detector +// will not find CodeCatalyst credentials. +func TestDetector_trueNegatives(t *testing.T) { + engine, err := veles.NewDetectionEngine([]veles.Detector{codecatalyst.NewDetector()}) + if err != nil { + t.Fatal(err) + } + cases := []struct { + name string + input string + want []veles.Secret + }{{ + name: "empty_input", + input: "", + }, { + name: "bad_host_name", + input: "https://user:password@github.com/project/repo", + }, { + name: "not_git_url", + input: `https://another:acsp03irh932r4@region.codecatalyst.aws/v1/space2/project/test-repo`, + }} + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + got, err := engine.Detect(t.Context(), strings.NewReader(tc.input)) + if err != nil { + t.Errorf("Detect() error: %v, want nil", err) + } + if diff := cmp.Diff(tc.want, got, cmpopts.EquateEmpty()); diff != "" { + t.Errorf("Detect() diff (-want +got):\n%s", diff) + } + }) + } +} diff --git a/veles/secrets/gitbasicauth/codecatalyst/validator.go b/veles/secrets/gitbasicauth/codecatalyst/validator.go index ec929ab7a..1927f2960 100644 --- a/veles/secrets/gitbasicauth/codecatalyst/validator.go +++ b/veles/secrets/gitbasicauth/codecatalyst/validator.go @@ -25,35 +25,47 @@ import ( "github.com/google/osv-scalibr/veles/secrets/gitbasicauth" ) -type validator struct { +// Validator validates CodeCatalyst credentials +type Validator struct { cli *http.Client } // SetHTTPClient sets the http.Client which the validator uses. -func (v *validator) SetHTTPClient(cli *http.Client) { +func (v *Validator) SetHTTPClient(cli *http.Client) { v.cli = cli } -// NewValidator creates a new Validator that validates Code Catalyst credentials -func NewValidator() veles.Validator[Credentials] { - return &validator{ +// NewValidator creates a new Validator that validates CodeCatalyst credentials +func NewValidator() *Validator { + return &Validator{ cli: http.DefaultClient, } } -// Validate validates code AWS Code Catalyst Git Basic Auth credentials -func (v *validator) Validate(ctx context.Context, secret Credentials) (veles.ValidationStatus, error) { +// Validate validates code AWS CodeCatalyst Git Basic Auth credentials. +func (v *Validator) Validate(ctx context.Context, secret Credentials) (veles.ValidationStatus, error) { u, err := url.Parse(secret.FullURL) if err != nil { return veles.ValidationFailed, fmt.Errorf("error parsing URL: %w", err) } + // redundant host validation kept intentionally as a security measure in case any regression + // is introduced in the detector. if !strings.HasSuffix(u.Host, ".codecatalyst.aws") { - return veles.ValidationFailed, fmt.Errorf("not a valid AWS Code Catalyst host %q", u.Host) + return veles.ValidationFailed, fmt.Errorf("not a valid AWS CodeCatalyst host %q", u.Host) } - return gitbasicauth.Validate( - ctx, v.cli, u, - gitbasicauth.Credentials{Username: secret.Username, Password: secret.PAT}, - ) + status, err := gitbasicauth.Info(ctx, v.cli, u) + if err != nil { + return veles.ValidationFailed, fmt.Errorf("failed to reach Git info endpoint: %w", err) + } + + // Credentials successfully authenticated and repository info retrieved. + if status == http.StatusOK { + return veles.ValidationValid, nil + } + + // Returns credentials invalid for every other state as the CodeCatalyst server always + // responds with either 200 or 400 status codes + return veles.ValidationInvalid, nil } diff --git a/veles/secrets/gitbasicauth/codecatalyst/validator_test.go b/veles/secrets/gitbasicauth/codecatalyst/validator_test.go new file mode 100644 index 000000000..316266a59 --- /dev/null +++ b/veles/secrets/gitbasicauth/codecatalyst/validator_test.go @@ -0,0 +1,143 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package codecatalyst_test + +import ( + "context" + "net/http" + "net/http/httptest" + "net/url" + "strings" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/google/osv-scalibr/veles" + "github.com/google/osv-scalibr/veles/secrets/gitbasicauth/codecatalyst" +) + +var ( + validatorTestURL = "https://user:pat@git.region.codecatalyst.aws/v1/space/project/repo" + validatorTestBadCredsURL = "https://user:bad_pat@git.region.codecatalyst.aws/v1/space/project/repo" + validatorTestBadRepoURL = "https://user:pat@git.region.codecatalyst.aws/v1/space/project/bad-repo" +) + +type redirectTransport struct { + url string +} + +func (t *redirectTransport) RoundTrip(req *http.Request) (*http.Response, error) { + if strings.HasSuffix(req.URL.Host, ".codecatalyst.aws") { + newURL, err := url.Parse(t.url) + if err != nil { + return nil, err + } + req.URL.Scheme = newURL.Scheme + req.URL.Host = newURL.Host + } + return http.DefaultTransport.RoundTrip(req) +} + +func mockCodeCatalystHandler(t *testing.T, status int) http.HandlerFunc { + t.Helper() + return func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodGet { + t.Errorf("r.Method = %s, want %s", r.Method, http.MethodGet) + } + auth := r.Header.Get("Authorization") + if !strings.HasPrefix(auth, "Basic") { + t.Errorf("should use basic auth") + } + if status == 200 { + w.WriteHeader(status) + return + } + w.WriteHeader(status) + _, _ = w.Write([]byte(` + The resource either does not exist, or you don’t have permission to access it. +`)) + } +} + +func TestValidator(t *testing.T) { + cancelledContext, cancel := context.WithCancel(t.Context()) + cancel() + + cases := []struct { + //nolint:containedctx + ctx context.Context + name string + url string + httpStatus int + want veles.ValidationStatus + wantErr error + }{ + { + name: "cancelled_context", + url: validatorTestURL, + want: veles.ValidationFailed, + ctx: cancelledContext, + httpStatus: http.StatusOK, + wantErr: cmpopts.AnyError, + }, + { + name: "valid_credentials", + url: validatorTestURL, + httpStatus: http.StatusOK, + want: veles.ValidationValid, + }, + { + name: "invalid_creds", + url: validatorTestBadCredsURL, + httpStatus: http.StatusBadRequest, + want: veles.ValidationInvalid, + }, + { + name: "bad_repository", + url: validatorTestBadRepoURL, + httpStatus: http.StatusBadRequest, + want: veles.ValidationInvalid, + }, + } + + for _, tt := range cases { + t.Run(tt.name, func(t *testing.T) { + if tt.ctx == nil { + tt.ctx = t.Context() + } + server := httptest.NewServer(mockCodeCatalystHandler(t, tt.httpStatus)) + defer server.Close() + + client := &http.Client{ + Transport: &redirectTransport{ + url: server.URL, + }, + } + + v := codecatalyst.NewValidator() + v.SetHTTPClient(client) + + got, err := v.Validate(tt.ctx, codecatalyst.Credentials{FullURL: tt.url}) + + if !cmp.Equal(tt.wantErr, err, cmpopts.EquateErrors()) { + t.Fatalf("Validate() error: %v, want %v", err, tt.wantErr) + } + + if diff := cmp.Diff(tt.want, got); diff != "" { + t.Errorf("v.Validate() returned diff (-want +got):\n%s", diff) + } + }) + } +} diff --git a/veles/secrets/gitbasicauth/gitbasicauth.go b/veles/secrets/gitbasicauth/gitbasicauth.go index d948f3826..ffa6cae81 100644 --- a/veles/secrets/gitbasicauth/gitbasicauth.go +++ b/veles/secrets/gitbasicauth/gitbasicauth.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package gitbasicauth contains common logic for Git basic auth. +// Package gitbasicauth contains common logic for Git Basic Auth plugins. package gitbasicauth import ( @@ -20,36 +20,22 @@ import ( "fmt" "net/http" "net/url" - - "github.com/google/osv-scalibr/veles" ) -// Credentials contains git basic auth credentials. -type Credentials struct { - Username string - Password string -} - -// Validate validates git credential against the given repoUrl. -func Validate(ctx context.Context, cli *http.Client, repoUrl *url.URL, creds Credentials) (veles.ValidationStatus, error) { - u := repoUrl.JoinPath("info/refs") +// Info performs the info/refs request for Git upload-pack service. +// It returns the HTTP status code and an optional error. +func Info(ctx context.Context, cli *http.Client, repoURL *url.URL) (int, error) { + u := repoURL.JoinPath("info/refs") u.RawQuery = "service=git-upload-pack" - - req, err := http.NewRequestWithContext(ctx, "GET", u.String(), nil) + req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil) if err != nil { - return veles.ValidationFailed, fmt.Errorf("error building request: %w", err) + return 0, fmt.Errorf("error building request: %w", err) } - req.SetBasicAuth(creds.Username, creds.Password) - resp, err := cli.Do(req) if err != nil { - return veles.ValidationFailed, fmt.Errorf("error executing request: %w", err) + return 0, fmt.Errorf("error executing request: %w", err) } defer resp.Body.Close() - if resp.StatusCode == http.StatusOK { - return veles.ValidationValid, nil - } - - return veles.ValidationInvalid, nil + return resp.StatusCode, nil } From 4c18a6604c383e2ed096eb1938caeff13f99b26f Mon Sep 17 00:00:00 2001 From: alessandro-Doyensec Date: Tue, 2 Dec 2025 19:44:39 +0100 Subject: [PATCH 04/11] add: register plugin --- extractor/filesystem/list/list.go | 2 + .../gitbasicauth/codecatalyst/codecatalyst.go | 48 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 extractor/filesystem/secrets/gitbasicauth/codecatalyst/codecatalyst.go diff --git a/extractor/filesystem/list/list.go b/extractor/filesystem/list/list.go index 25db3dacf..cdbb4f0c2 100644 --- a/extractor/filesystem/list/list.go +++ b/extractor/filesystem/list/list.go @@ -98,6 +98,7 @@ import ( "github.com/google/osv-scalibr/extractor/filesystem/sbom/spdx" "github.com/google/osv-scalibr/extractor/filesystem/secrets/awsaccesskey" "github.com/google/osv-scalibr/extractor/filesystem/secrets/convert" + "github.com/google/osv-scalibr/extractor/filesystem/secrets/gitbasicauth/codecatalyst" "github.com/google/osv-scalibr/extractor/filesystem/secrets/mariadb" "github.com/google/osv-scalibr/extractor/filesystem/secrets/mysqlmylogin" "github.com/google/osv-scalibr/extractor/filesystem/secrets/onepasswordconnecttoken" @@ -284,6 +285,7 @@ var ( onepasswordconnecttoken.Name: {noCFG(onepasswordconnecttoken.New)}, mariadb.Name: {noCFG(mariadb.NewDefault)}, awsaccesskey.Name: {noCFG(awsaccesskey.New)}, + codecatalyst.Name: {noCFG(codecatalyst.New)}, } // SecretDetectors for Detector interface. diff --git a/extractor/filesystem/secrets/gitbasicauth/codecatalyst/codecatalyst.go b/extractor/filesystem/secrets/gitbasicauth/codecatalyst/codecatalyst.go new file mode 100644 index 000000000..f9a4961e8 --- /dev/null +++ b/extractor/filesystem/secrets/gitbasicauth/codecatalyst/codecatalyst.go @@ -0,0 +1,48 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package codecatalyst extends the veles codecatalyst.Detector to search inside the git config and history files +package codecatalyst + +import ( + "path/filepath" + "strings" + + "github.com/google/osv-scalibr/extractor/filesystem" + "github.com/google/osv-scalibr/veles/secrets/gitbasicauth/codecatalyst" + + "github.com/google/osv-scalibr/extractor/filesystem/secrets/convert" +) + +const ( + // Name is the name of the extractor + Name = "secrets/codecatalystcredentials" + // Version is the version of the extractor + Version = 0 +) + +// New returns a filesystem.Extractor which extracts Amazon CodeCatalyst Credentials using the codecatalyst.Detector +func New() filesystem.Extractor { + return convert.FromVelesDetectorWithRequire( + codecatalyst.NewDetector(), Name, Version, FileRequired, + ) +} + +// FileRequired returns true if a file should be searched by the plugin. +func FileRequired(api filesystem.FileAPI) bool { + path := filepath.ToSlash(api.Path()) + return strings.HasSuffix(path, ".git/config") || + strings.HasSuffix(path, "_history") || + strings.HasSuffix(path, ".history.txt") +} From 99c9dc6ed122115858db1b3dfa7c7dde8532b48f Mon Sep 17 00:00:00 2001 From: alessandro-Doyensec Date: Wed, 3 Dec 2025 11:11:35 +0100 Subject: [PATCH 05/11] add: validato registration --- enricher/enricherlist/list.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/enricher/enricherlist/list.go b/enricher/enricherlist/list.go index 8c75f5e4c..ea41373ae 100644 --- a/enricher/enricherlist/list.go +++ b/enricher/enricherlist/list.go @@ -42,6 +42,7 @@ import ( "github.com/google/osv-scalibr/veles/secrets/gcpoauth2access" "github.com/google/osv-scalibr/veles/secrets/gcpsak" "github.com/google/osv-scalibr/veles/secrets/gcshmackey" + "github.com/google/osv-scalibr/veles/secrets/gitbasicauth/codecatalyst" "github.com/google/osv-scalibr/veles/secrets/github" "github.com/google/osv-scalibr/veles/secrets/gitlabpat" "github.com/google/osv-scalibr/veles/secrets/grokxaiapikey" @@ -118,6 +119,7 @@ var ( fromVeles(gcpoauth2access.NewValidator(), "secrets/gcpoauth2accesstokenvalidate", 0), fromVeles(gcshmackey.NewValidator(), "secrets/gcshmackeyvalidate", 0), fromVeles(awsaccesskey.NewValidator(), "secrets/awsaccesskeyvalidate", 0), + fromVeles(codecatalyst.NewValidator(), "secretsc/odecatalystcredentialsvalidate", 0), }) // SecretsEnrich lists enrichers that add data to detected secrets. From 6fe0f033bee3272548e9001613afdb09f1e16ca8 Mon Sep 17 00:00:00 2001 From: alessandro-Doyensec Date: Wed, 3 Dec 2025 11:17:37 +0100 Subject: [PATCH 06/11] add: proto and proto conversion rules --- binary/proto/scan_result.proto | 5 + .../scan_result_go_proto/scan_result.pb.go | 840 ++++++++++-------- binary/proto/secret.go | 17 + 3 files changed, 478 insertions(+), 384 deletions(-) diff --git a/binary/proto/scan_result.proto b/binary/proto/scan_result.proto index c5bdba7fb..4245ce908 100644 --- a/binary/proto/scan_result.proto +++ b/binary/proto/scan_result.proto @@ -720,6 +720,7 @@ message SecretData { VapidKey vapid_key = 49; AwsAccessKeyCredentials aws_access_key_credentials = 50; ReCaptchaKey re_captcha_key = 51; + CodeCatalystCredentials code_catalyst_credentials = 52; } message GCPSAK { @@ -994,6 +995,10 @@ message SecretData { message ReCaptchaKey{ string secret = 1; } + + message CodeCatalystCredentials{ + string url = 1; + } } message SecretStatus { diff --git a/binary/proto/scan_result_go_proto/scan_result.pb.go b/binary/proto/scan_result_go_proto/scan_result.pb.go index 41a1e5851..5065b60ea 100644 --- a/binary/proto/scan_result_go_proto/scan_result.pb.go +++ b/binary/proto/scan_result_go_proto/scan_result.pb.go @@ -15,7 +15,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.2 +// protoc-gen-go v1.35.1 // protoc v6.33.1 // source: proto/scan_result.proto @@ -5217,6 +5217,7 @@ type SecretData struct { // *SecretData_VapidKey_ // *SecretData_AwsAccessKeyCredentials_ // *SecretData_ReCaptchaKey_ + // *SecretData_CodeCatalystCredentials_ Secret isSecretData_Secret `protobuf_oneof:"secret"` } @@ -5607,6 +5608,13 @@ func (x *SecretData) GetReCaptchaKey() *SecretData_ReCaptchaKey { return nil } +func (x *SecretData) GetCodeCatalystCredentials() *SecretData_CodeCatalystCredentials { + if x, ok := x.GetSecret().(*SecretData_CodeCatalystCredentials_); ok { + return x.CodeCatalystCredentials + } + return nil +} + type isSecretData_Secret interface { isSecretData_Secret() } @@ -5811,6 +5819,10 @@ type SecretData_ReCaptchaKey_ struct { ReCaptchaKey *SecretData_ReCaptchaKey `protobuf:"bytes,51,opt,name=re_captcha_key,json=reCaptchaKey,proto3,oneof"` } +type SecretData_CodeCatalystCredentials_ struct { + CodeCatalystCredentials *SecretData_CodeCatalystCredentials `protobuf:"bytes,52,opt,name=code_catalyst_credentials,json=codeCatalystCredentials,proto3,oneof"` +} + func (*SecretData_Gcpsak) isSecretData_Secret() {} func (*SecretData_AnthropicWorkspaceApiKey) isSecretData_Secret() {} @@ -5911,6 +5923,8 @@ func (*SecretData_AwsAccessKeyCredentials_) isSecretData_Secret() {} func (*SecretData_ReCaptchaKey_) isSecretData_Secret() {} +func (*SecretData_CodeCatalystCredentials_) isSecretData_Secret() {} + type SecretStatus struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -9274,6 +9288,51 @@ func (x *SecretData_ReCaptchaKey) GetSecret() string { return "" } +type SecretData_CodeCatalystCredentials struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"` +} + +func (x *SecretData_CodeCatalystCredentials) Reset() { + *x = SecretData_CodeCatalystCredentials{} + mi := &file_proto_scan_result_proto_msgTypes[119] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SecretData_CodeCatalystCredentials) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SecretData_CodeCatalystCredentials) ProtoMessage() {} + +func (x *SecretData_CodeCatalystCredentials) ProtoReflect() protoreflect.Message { + mi := &file_proto_scan_result_proto_msgTypes[119] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SecretData_CodeCatalystCredentials.ProtoReflect.Descriptor instead. +func (*SecretData_CodeCatalystCredentials) Descriptor() ([]byte, []int) { + return file_proto_scan_result_proto_rawDescGZIP(), []int{56, 50} +} + +func (x *SecretData_CodeCatalystCredentials) GetUrl() string { + if x != nil { + return x.Url + } + return "" +} + var File_proto_scan_result_proto protoreflect.FileDescriptor var file_proto_scan_result_proto_rawDesc = []byte{ @@ -10150,7 +10209,7 @@ var file_proto_scan_result_proto_rawDesc = []byte{ 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2f, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x69, 0x62, 0x72, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x6c, 0x6f, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xc3, 0x42, 0x0a, 0x0a, 0x53, 0x65, 0x63, 0x72, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xdb, 0x43, 0x0a, 0x0a, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x44, 0x61, 0x74, 0x61, 0x12, 0x34, 0x0a, 0x06, 0x67, 0x63, 0x70, 0x73, 0x61, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x69, 0x62, 0x72, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x43, 0x50, 0x53, @@ -10446,369 +10505,379 @@ var file_proto_scan_result_proto_rawDesc = []byte{ 0x68, 0x61, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x33, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x69, 0x62, 0x72, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x43, 0x61, 0x70, 0x74, 0x63, 0x68, 0x61, 0x4b, 0x65, 0x79, 0x48, 0x00, - 0x52, 0x0c, 0x72, 0x65, 0x43, 0x61, 0x70, 0x74, 0x63, 0x68, 0x61, 0x4b, 0x65, 0x79, 0x1a, 0xb0, - 0x03, 0x0a, 0x06, 0x47, 0x43, 0x50, 0x53, 0x41, 0x4b, 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x72, 0x69, - 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0c, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, - 0x21, 0x0a, 0x0c, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x45, 0x6d, 0x61, - 0x69, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, - 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x74, 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, - 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, - 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, - 0x12, 0x19, 0x0a, 0x08, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x61, 0x75, 0x74, 0x68, 0x55, 0x72, 0x69, 0x12, 0x1b, 0x0a, 0x09, 0x74, - 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x55, 0x72, 0x69, 0x12, 0x3c, 0x0a, 0x1b, 0x61, 0x75, 0x74, 0x68, - 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x78, 0x35, 0x30, 0x39, 0x5f, 0x63, - 0x65, 0x72, 0x74, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x17, 0x61, - 0x75, 0x74, 0x68, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x58, 0x35, 0x30, 0x39, 0x43, - 0x65, 0x72, 0x74, 0x55, 0x72, 0x6c, 0x12, 0x2f, 0x0a, 0x14, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x5f, 0x78, 0x35, 0x30, 0x39, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x0a, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x58, 0x35, 0x30, 0x39, - 0x43, 0x65, 0x72, 0x74, 0x55, 0x72, 0x6c, 0x12, 0x27, 0x0a, 0x0f, 0x75, 0x6e, 0x69, 0x76, 0x65, - 0x72, 0x73, 0x65, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, - 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, - 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, - 0x79, 0x1a, 0x2c, 0x0a, 0x18, 0x41, 0x6e, 0x74, 0x68, 0x72, 0x6f, 0x70, 0x69, 0x63, 0x57, 0x6f, - 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, - 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x1a, - 0x28, 0x0a, 0x14, 0x41, 0x6e, 0x74, 0x68, 0x72, 0x6f, 0x70, 0x69, 0x63, 0x4d, 0x6f, 0x64, 0x65, - 0x6c, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x1a, 0x24, 0x0a, 0x10, 0x50, 0x65, 0x72, - 0x70, 0x6c, 0x65, 0x78, 0x69, 0x74, 0x79, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, - 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x1a, - 0x21, 0x0a, 0x0d, 0x47, 0x72, 0x6f, 0x6b, 0x58, 0x41, 0x49, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, + 0x52, 0x0c, 0x72, 0x65, 0x43, 0x61, 0x70, 0x74, 0x63, 0x68, 0x61, 0x4b, 0x65, 0x79, 0x12, 0x69, + 0x0a, 0x19, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x79, 0x73, 0x74, 0x5f, + 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x18, 0x34, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x2b, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x69, 0x62, 0x72, 0x2e, 0x53, 0x65, 0x63, 0x72, + 0x65, 0x74, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x6f, 0x64, 0x65, 0x43, 0x61, 0x74, 0x61, 0x6c, + 0x79, 0x73, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x48, 0x00, + 0x52, 0x17, 0x63, 0x6f, 0x64, 0x65, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x79, 0x73, 0x74, 0x43, 0x72, + 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x1a, 0xb0, 0x03, 0x0a, 0x06, 0x47, 0x43, + 0x50, 0x53, 0x41, 0x4b, 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, + 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x72, + 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1c, 0x0a, + 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, + 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x1b, + 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x61, + 0x75, 0x74, 0x68, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, + 0x75, 0x74, 0x68, 0x55, 0x72, 0x69, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, + 0x75, 0x72, 0x69, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x55, 0x72, 0x69, 0x12, 0x3c, 0x0a, 0x1b, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x5f, 0x78, 0x35, 0x30, 0x39, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x5f, 0x75, + 0x72, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x17, 0x61, 0x75, 0x74, 0x68, 0x50, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x58, 0x35, 0x30, 0x39, 0x43, 0x65, 0x72, 0x74, 0x55, 0x72, + 0x6c, 0x12, 0x2f, 0x0a, 0x14, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x78, 0x35, 0x30, 0x39, + 0x5f, 0x63, 0x65, 0x72, 0x74, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x11, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x58, 0x35, 0x30, 0x39, 0x43, 0x65, 0x72, 0x74, 0x55, + 0x72, 0x6c, 0x12, 0x27, 0x0a, 0x0f, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x5f, 0x64, + 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x75, 0x6e, 0x69, + 0x76, 0x65, 0x72, 0x73, 0x65, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x70, + 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x1a, 0x2c, 0x0a, 0x18, + 0x41, 0x6e, 0x74, 0x68, 0x72, 0x6f, 0x70, 0x69, 0x63, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x1a, 0x28, 0x0a, 0x14, 0x41, 0x6e, + 0x74, 0x68, 0x72, 0x6f, 0x70, 0x69, 0x63, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x41, 0x50, 0x49, 0x4b, + 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x1a, 0x24, 0x0a, 0x10, 0x50, 0x65, 0x72, 0x70, 0x6c, 0x65, 0x78, 0x69, + 0x74, 0x79, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x1a, 0x21, 0x0a, 0x0d, 0x47, 0x72, + 0x6f, 0x6b, 0x58, 0x41, 0x49, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x1a, 0x2b, 0x0a, + 0x17, 0x47, 0x72, 0x6f, 0x6b, 0x58, 0x41, 0x49, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x1a, 0x30, 0x0a, 0x1c, 0x41, 0x7a, + 0x75, 0x72, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x1a, 0x34, 0x0a, 0x0a, + 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x12, 0x10, 0x0a, 0x03, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x64, + 0x65, 0x72, 0x1a, 0x28, 0x0a, 0x10, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x1a, 0x8c, 0x01, 0x0a, + 0x06, 0x50, 0x67, 0x70, 0x61, 0x73, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, + 0x61, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, + 0x61, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x1a, 0x86, 0x01, 0x0a, 0x12, + 0x4d, 0x61, 0x72, 0x69, 0x61, 0x44, 0x42, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, + 0x6c, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, + 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x1a, + 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x2a, 0x0a, 0x12, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x49, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x1a, 0x20, 0x0a, 0x0c, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x49, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, - 0x65, 0x79, 0x1a, 0x2b, 0x0a, 0x17, 0x47, 0x72, 0x6f, 0x6b, 0x58, 0x41, 0x49, 0x4d, 0x61, 0x6e, - 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, - 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x1a, - 0x30, 0x0a, 0x1c, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x41, - 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x12, - 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, - 0x79, 0x1a, 0x34, 0x0a, 0x0a, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, - 0x14, 0x0a, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x03, 0x64, 0x65, 0x72, 0x1a, 0x28, 0x0a, 0x10, 0x41, 0x7a, 0x75, 0x72, 0x65, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, - 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x1a, 0x8c, 0x01, 0x0a, 0x06, 0x50, 0x67, 0x70, 0x61, 0x73, 0x73, 0x12, 0x1a, 0x0a, 0x08, - 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x1a, 0x0a, 0x08, - 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, - 0x1a, 0x86, 0x01, 0x0a, 0x12, 0x4d, 0x61, 0x72, 0x69, 0x61, 0x44, 0x42, 0x43, 0x72, 0x65, 0x64, - 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, - 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, - 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, - 0x73, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, - 0x18, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x2a, 0x0a, 0x12, 0x41, 0x7a, 0x75, - 0x72, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, - 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x1a, 0x20, 0x0a, 0x0c, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x49, 0x41, - 0x50, 0x49, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x1a, 0x3c, 0x0a, 0x0c, 0x44, 0x6f, 0x63, 0x6b, 0x65, - 0x72, 0x48, 0x75, 0x62, 0x50, 0x61, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x61, 0x74, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x70, 0x61, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, - 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, - 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x1a, 0x1d, 0x0a, 0x09, 0x47, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x50, + 0x65, 0x79, 0x1a, 0x3c, 0x0a, 0x0c, 0x44, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x48, 0x75, 0x62, 0x50, 0x61, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x70, 0x61, 0x74, 0x1a, 0x2a, 0x0a, 0x12, 0x53, 0x6c, 0x61, 0x63, 0x6b, 0x41, 0x70, 0x70, - 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, - 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, - 0x1a, 0x31, 0x0a, 0x19, 0x53, 0x6c, 0x61, 0x63, 0x6b, 0x41, 0x70, 0x70, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, - 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, - 0x6b, 0x65, 0x6e, 0x1a, 0x32, 0x0a, 0x1a, 0x53, 0x6c, 0x61, 0x63, 0x6b, 0x41, 0x70, 0x70, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x1a, 0x21, 0x0a, 0x0d, 0x50, 0x6f, 0x73, 0x74, 0x6d, - 0x61, 0x6e, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x1a, 0x30, 0x0a, 0x1c, 0x50, 0x6f, - 0x73, 0x74, 0x6d, 0x61, 0x6e, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x1a, 0x28, 0x0a, 0x14, - 0x44, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x4f, 0x63, 0x65, 0x61, 0x6e, 0x41, 0x50, 0x49, 0x54, - 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x1a, 0x28, 0x0a, 0x10, 0x43, 0x72, 0x61, 0x74, 0x65, 0x73, - 0x49, 0x4f, 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, - 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, - 0x1a, 0x2d, 0x0a, 0x15, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x41, 0x70, 0x70, 0x52, 0x65, 0x66, - 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, - 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x1a, - 0x34, 0x0a, 0x1c, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x41, 0x70, 0x70, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x54, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, - 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x1a, 0x38, 0x0a, 0x20, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x43, - 0x6c, 0x61, 0x73, 0x73, 0x69, 0x63, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, - 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x1a, - 0x3c, 0x0a, 0x24, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x46, 0x69, 0x6e, 0x65, 0x47, 0x72, 0x61, - 0x69, 0x6e, 0x65, 0x64, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x1a, 0x28, 0x0a, - 0x10, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x4f, 0x41, 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x1a, 0x32, 0x0a, 0x1a, 0x47, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x41, 0x70, 0x70, 0x55, 0x73, 0x65, 0x72, 0x54, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x03, 0x70, 0x61, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, + 0x1a, 0x1d, 0x0a, 0x09, 0x47, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x50, 0x61, 0x74, 0x12, 0x10, 0x0a, + 0x03, 0x70, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x70, 0x61, 0x74, 0x1a, + 0x2a, 0x0a, 0x12, 0x53, 0x6c, 0x61, 0x63, 0x6b, 0x41, 0x70, 0x70, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x1a, 0x24, 0x0a, 0x0c, 0x50, - 0x79, 0x50, 0x49, 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, - 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x1a, 0x26, 0x0a, 0x0a, 0x54, 0x69, 0x6e, 0x6b, 0x4b, 0x65, 0x79, 0x73, 0x65, 0x74, 0x12, - 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x1a, 0x2b, 0x0a, 0x13, 0x48, 0x61, 0x73, - 0x68, 0x69, 0x43, 0x6f, 0x72, 0x70, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x1a, 0x31, 0x0a, 0x19, 0x53, + 0x6c, 0x61, 0x63, 0x6b, 0x41, 0x70, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x1a, 0x32, + 0x0a, 0x1a, 0x53, 0x6c, 0x61, 0x63, 0x6b, 0x41, 0x70, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x1a, 0x21, 0x0a, 0x0d, 0x50, 0x6f, 0x73, 0x74, 0x6d, 0x61, 0x6e, 0x41, 0x50, 0x49, + 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x1a, 0x30, 0x0a, 0x1c, 0x50, 0x6f, 0x73, 0x74, 0x6d, 0x61, 0x6e, + 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x1a, 0x28, 0x0a, 0x14, 0x44, 0x69, 0x67, 0x69, 0x74, + 0x61, 0x6c, 0x4f, 0x63, 0x65, 0x61, 0x6e, 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x1a, 0x28, 0x0a, 0x10, 0x43, 0x72, 0x61, 0x74, 0x65, 0x73, 0x49, 0x4f, 0x41, 0x50, 0x49, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x1a, 0x2d, 0x0a, 0x15, 0x47, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x41, 0x70, 0x70, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x1a, 0x34, 0x0a, 0x1c, 0x47, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x41, 0x70, 0x70, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x1a, 0x38, 0x0a, 0x20, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x69, + 0x63, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x1a, 0x3c, 0x0a, 0x24, 0x47, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x46, 0x69, 0x6e, 0x65, 0x47, 0x72, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x50, + 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x1a, 0x28, 0x0a, 0x10, 0x47, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x4f, 0x41, 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x1a, 0x32, 0x0a, 0x1a, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x41, 0x70, 0x70, 0x55, + 0x73, 0x65, 0x72, 0x54, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x1a, 0x68, 0x0a, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x43, - 0x6f, 0x72, 0x70, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x41, 0x70, 0x70, 0x52, 0x6f, 0x6c, 0x65, 0x43, - 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x6f, - 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x6f, 0x6c, - 0x65, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x5f, 0x69, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x49, 0x64, - 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, - 0x1a, 0x1d, 0x0a, 0x09, 0x47, 0x43, 0x50, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, + 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x1a, 0x24, 0x0a, 0x0c, 0x50, 0x79, 0x50, 0x49, 0x41, 0x50, + 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x1a, 0x26, 0x0a, 0x0a, + 0x54, 0x69, 0x6e, 0x6b, 0x4b, 0x65, 0x79, 0x73, 0x65, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x1a, 0x2b, 0x0a, 0x13, 0x48, 0x61, 0x73, 0x68, 0x69, 0x43, 0x6f, 0x72, + 0x70, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x1a, 0x68, 0x0a, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x43, 0x6f, 0x72, 0x70, 0x56, 0x61, + 0x75, 0x6c, 0x74, 0x41, 0x70, 0x70, 0x52, 0x6f, 0x6c, 0x65, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x6f, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x1b, + 0x0a, 0x09, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x49, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x1a, 0x1d, 0x0a, 0x09, 0x47, + 0x43, 0x50, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x1a, 0x67, 0x0a, 0x11, 0x48, 0x75, + 0x67, 0x67, 0x69, 0x6e, 0x67, 0x66, 0x61, 0x63, 0x65, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x66, 0x69, 0x6e, 0x65, 0x5f, 0x67, 0x72, + 0x61, 0x69, 0x6e, 0x65, 0x64, 0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x10, 0x66, 0x69, 0x6e, 0x65, 0x47, 0x72, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x53, 0x63, + 0x6f, 0x70, 0x65, 0x1a, 0x65, 0x0a, 0x21, 0x48, 0x61, 0x73, 0x68, 0x69, 0x43, 0x6f, 0x72, 0x70, + 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x43, 0x72, 0x65, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, + 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x1a, 0xbd, 0x02, 0x0a, 0x1b, 0x48, + 0x61, 0x73, 0x68, 0x69, 0x43, 0x6f, 0x72, 0x70, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x50, 0x6c, 0x61, + 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x12, 0x27, 0x0a, 0x0f, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x6f, 0x72, 0x67, 0x61, 0x6e, + 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x69, 0x6e, + 0x63, 0x69, 0x70, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x70, + 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1d, + 0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1b, 0x0a, + 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x73, 0x1a, 0x23, 0x0a, 0x0f, 0x53, 0x74, + 0x72, 0x69, 0x70, 0x65, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x1a, - 0x67, 0x0a, 0x11, 0x48, 0x75, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x66, 0x61, 0x63, 0x65, 0x41, 0x50, - 0x49, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x66, 0x69, - 0x6e, 0x65, 0x5f, 0x67, 0x72, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65, - 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x66, 0x69, 0x6e, 0x65, 0x47, 0x72, 0x61, 0x69, - 0x6e, 0x65, 0x64, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x1a, 0x65, 0x0a, 0x21, 0x48, 0x61, 0x73, 0x68, - 0x69, 0x43, 0x6f, 0x72, 0x70, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, - 0x72, 0x6d, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x1b, 0x0a, - 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6c, - 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0c, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x1a, - 0xbd, 0x02, 0x0a, 0x1b, 0x48, 0x61, 0x73, 0x68, 0x69, 0x43, 0x6f, 0x72, 0x70, 0x43, 0x6c, 0x6f, - 0x75, 0x64, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, - 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, - 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1d, - 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, - 0x0c, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x49, 0x64, - 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, - 0x70, 0x61, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, - 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, - 0x72, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, - 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x45, 0x6d, 0x61, - 0x69, 0x6c, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x73, 0x18, - 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x73, 0x1a, - 0x23, 0x0a, 0x0f, 0x53, 0x74, 0x72, 0x69, 0x70, 0x65, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4b, - 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x1a, 0x27, 0x0a, 0x13, 0x53, 0x74, 0x72, 0x69, 0x70, 0x65, 0x52, 0x65, - 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x1a, 0x27, 0x0a, - 0x13, 0x53, 0x74, 0x72, 0x69, 0x70, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x53, 0x65, - 0x63, 0x72, 0x65, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x1a, 0x44, 0x0a, 0x1a, 0x47, 0x43, 0x50, 0x4f, 0x41, 0x75, - 0x74, 0x68, 0x32, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, - 0x69, 0x61, 0x6c, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x1a, 0x2c, 0x0a, 0x14, - 0x47, 0x43, 0x50, 0x4f, 0x41, 0x75, 0x74, 0x68, 0x32, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, - 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x1a, 0x41, 0x0a, 0x0a, 0x47, 0x43, - 0x53, 0x48, 0x6d, 0x61, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x1a, 0xa8, 0x01, - 0x0a, 0x13, 0x4d, 0x79, 0x73, 0x71, 0x6c, 0x4d, 0x79, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x53, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, - 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, - 0x70, 0x6f, 0x72, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, - 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x1a, 0x4a, 0x0a, 0x08, 0x56, 0x61, 0x70, 0x69, - 0x64, 0x4b, 0x65, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, - 0x62, 0x36, 0x34, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x76, 0x61, - 0x74, 0x65, 0x42, 0x36, 0x34, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, - 0x62, 0x36, 0x34, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x42, 0x36, 0x34, 0x1a, 0xb0, 0x02, 0x0a, 0x17, 0x4f, 0x6e, 0x65, 0x50, 0x61, 0x73, 0x73, - 0x77, 0x6f, 0x72, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, - 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x55, 0x75, 0x69, - 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x65, - 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x44, 0x61, - 0x74, 0x61, 0x12, 0x2a, 0x0a, 0x11, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x65, - 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x0e, - 0x0a, 0x02, 0x69, 0x76, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x76, 0x12, 0x22, - 0x0a, 0x0d, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x4b, 0x65, 0x79, - 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x72, 0x5f, 0x73, - 0x61, 0x6c, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x76, 0x65, 0x72, 0x69, 0x66, - 0x69, 0x65, 0x72, 0x53, 0x61, 0x6c, 0x74, 0x12, 0x2e, 0x0a, 0x13, 0x76, 0x65, 0x72, 0x69, 0x66, - 0x69, 0x65, 0x72, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x08, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x72, 0x4c, 0x6f, - 0x63, 0x61, 0x6c, 0x48, 0x61, 0x73, 0x68, 0x1a, 0x28, 0x0a, 0x14, 0x4f, 0x6e, 0x65, 0x50, 0x61, - 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x12, + 0x27, 0x0a, 0x13, 0x53, 0x74, 0x72, 0x69, 0x70, 0x65, 0x52, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, + 0x74, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x1a, 0x27, 0x0a, 0x13, 0x53, 0x74, 0x72, 0x69, + 0x70, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, - 0x79, 0x1a, 0x2b, 0x0a, 0x17, 0x4f, 0x6e, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x10, 0x0a, 0x03, - 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x1a, 0x2b, - 0x0a, 0x17, 0x4f, 0x6e, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x63, - 0x6f, 0x76, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x1a, 0x4e, 0x0a, 0x17, 0x41, - 0x77, 0x73, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x43, 0x72, 0x65, 0x64, 0x65, - 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x1a, 0x26, 0x0a, 0x0c, 0x52, - 0x65, 0x43, 0x61, 0x70, 0x74, 0x63, 0x68, 0x61, 0x4b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x73, - 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x63, - 0x72, 0x65, 0x74, 0x42, 0x08, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x22, 0xf8, 0x01, - 0x0a, 0x0c, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x3e, - 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, - 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x69, 0x62, 0x72, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x3d, - 0x0a, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x52, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x22, 0x69, 0x0a, - 0x10, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x45, 0x6e, 0x75, - 0x6d, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, - 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x01, 0x1a, - 0x02, 0x08, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x02, - 0x12, 0x09, 0x0a, 0x05, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x55, - 0x4e, 0x53, 0x55, 0x50, 0x50, 0x4f, 0x52, 0x54, 0x45, 0x44, 0x10, 0x04, 0x12, 0x0a, 0x0a, 0x06, - 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x05, 0x22, 0xc8, 0x02, 0x0a, 0x08, 0x4c, 0x6f, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2f, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x70, 0x61, 0x74, - 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x69, 0x62, - 0x72, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x70, 0x61, 0x74, 0x68, 0x48, 0x00, 0x52, 0x08, 0x66, 0x69, - 0x6c, 0x65, 0x70, 0x61, 0x74, 0x68, 0x12, 0x62, 0x0a, 0x1b, 0x66, 0x69, 0x6c, 0x65, 0x70, 0x61, - 0x74, 0x68, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x5f, 0x64, 0x65, - 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x73, 0x63, - 0x61, 0x6c, 0x69, 0x62, 0x72, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x70, 0x61, 0x74, 0x68, 0x57, 0x69, - 0x74, 0x68, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x48, 0x00, - 0x52, 0x18, 0x66, 0x69, 0x6c, 0x65, 0x70, 0x61, 0x74, 0x68, 0x57, 0x69, 0x74, 0x68, 0x4c, 0x61, - 0x79, 0x65, 0x72, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x51, 0x0a, 0x14, 0x65, 0x6e, - 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, - 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x69, - 0x62, 0x72, 0x2e, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x61, - 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x48, 0x00, 0x52, 0x13, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, - 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x48, 0x0a, - 0x11, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, - 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x69, - 0x62, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x6d, - 0x61, 0x6e, 0x64, 0x48, 0x00, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x42, 0x0a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x22, 0x1e, 0x0a, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x70, 0x61, 0x74, 0x68, 0x12, - 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, - 0x61, 0x74, 0x68, 0x22, 0x6a, 0x0a, 0x18, 0x46, 0x69, 0x6c, 0x65, 0x70, 0x61, 0x74, 0x68, 0x57, - 0x69, 0x74, 0x68, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, - 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, - 0x61, 0x74, 0x68, 0x12, 0x3a, 0x0a, 0x0d, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x74, - 0x61, 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x63, 0x61, - 0x6c, 0x69, 0x62, 0x72, 0x2e, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, - 0x73, 0x52, 0x0c, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, - 0x29, 0x0a, 0x13, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x61, - 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x2c, 0x0a, 0x10, 0x43, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x18, - 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x22, 0xb3, 0x02, 0x0a, 0x16, 0x43, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x3d, 0x0a, 0x0e, 0x6c, 0x61, 0x79, - 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x69, 0x62, 0x72, 0x2e, 0x4c, 0x61, 0x79, 0x65, - 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x0d, 0x6c, 0x61, 0x79, 0x65, 0x72, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x43, 0x0a, 0x11, 0x62, 0x61, 0x73, 0x65, - 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x03, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x69, 0x62, 0x72, 0x2e, 0x42, 0x61, - 0x73, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, 0x0f, 0x62, 0x61, - 0x73, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x12, 0x44, 0x0a, - 0x07, 0x6f, 0x73, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, - 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x69, 0x62, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x4f, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6f, 0x73, 0x49, - 0x6e, 0x66, 0x6f, 0x1a, 0x39, 0x0a, 0x0b, 0x4f, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x67, - 0x0a, 0x0e, 0x42, 0x61, 0x73, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, - 0x12, 0x3a, 0x0a, 0x0b, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x69, 0x62, 0x72, 0x2e, - 0x42, 0x61, 0x73, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, - 0x52, 0x0a, 0x62, 0x61, 0x73, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x12, 0x19, 0x0a, 0x08, - 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x22, 0x66, 0x0a, 0x10, 0x42, 0x61, 0x73, 0x65, 0x49, - 0x6d, 0x61, 0x67, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x72, - 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x72, - 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, - 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x6c, 0x75, 0x67, 0x69, - 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x22, - 0xb8, 0x01, 0x0a, 0x0d, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x69, 0x66, 0x66, 0x5f, - 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x69, 0x66, 0x66, 0x49, 0x64, - 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x63, - 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, - 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x73, 0x5f, 0x65, 0x6d, 0x70, 0x74, - 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x12, 0x28, 0x0a, 0x10, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x5f, 0x69, - 0x6e, 0x64, 0x65, 0x78, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x62, 0x61, 0x73, 0x65, - 0x49, 0x6d, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x2a, 0xf7, 0x01, 0x0a, 0x10, 0x56, - 0x65, 0x78, 0x4a, 0x75, 0x73, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x21, 0x0a, 0x1d, 0x56, 0x45, 0x58, 0x5f, 0x4a, 0x55, 0x53, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, - 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, - 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x43, 0x4f, 0x4d, 0x50, 0x4f, 0x4e, 0x45, 0x4e, 0x54, 0x5f, - 0x4e, 0x4f, 0x54, 0x5f, 0x50, 0x52, 0x45, 0x53, 0x45, 0x4e, 0x54, 0x10, 0x01, 0x12, 0x1f, 0x0a, - 0x1b, 0x56, 0x55, 0x4c, 0x4e, 0x45, 0x52, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x43, 0x4f, 0x44, 0x45, - 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x50, 0x52, 0x45, 0x53, 0x45, 0x4e, 0x54, 0x10, 0x02, 0x12, 0x27, - 0x0a, 0x23, 0x56, 0x55, 0x4c, 0x4e, 0x45, 0x52, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x43, 0x4f, 0x44, - 0x45, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x49, 0x4e, 0x5f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x45, - 0x5f, 0x50, 0x41, 0x54, 0x48, 0x10, 0x03, 0x12, 0x35, 0x0a, 0x31, 0x56, 0x55, 0x4c, 0x4e, 0x45, - 0x52, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x43, 0x41, 0x4e, 0x4e, 0x4f, - 0x54, 0x5f, 0x42, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x4f, 0x4c, 0x4c, 0x45, 0x44, 0x5f, - 0x42, 0x59, 0x5f, 0x41, 0x44, 0x56, 0x45, 0x52, 0x53, 0x41, 0x52, 0x59, 0x10, 0x04, 0x12, 0x24, - 0x0a, 0x20, 0x49, 0x4e, 0x4c, 0x49, 0x4e, 0x45, 0x5f, 0x4d, 0x49, 0x54, 0x49, 0x47, 0x41, 0x54, - 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x4c, 0x52, 0x45, 0x41, 0x44, 0x59, 0x5f, 0x45, 0x58, 0x49, 0x53, - 0x54, 0x53, 0x10, 0x05, 0x2a, 0x62, 0x0a, 0x0c, 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, - 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x18, 0x0a, 0x14, 0x53, 0x45, 0x56, 0x45, 0x52, 0x49, 0x54, 0x59, - 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0b, - 0x0a, 0x07, 0x4d, 0x49, 0x4e, 0x49, 0x4d, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x4c, - 0x4f, 0x57, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x4d, 0x45, 0x44, 0x49, 0x55, 0x4d, 0x10, 0x03, - 0x12, 0x08, 0x0a, 0x04, 0x48, 0x49, 0x47, 0x48, 0x10, 0x04, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x52, - 0x49, 0x54, 0x49, 0x43, 0x41, 0x4c, 0x10, 0x05, 0x2a, 0x47, 0x0a, 0x0d, 0x50, 0x61, 0x63, 0x6b, - 0x61, 0x67, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, - 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, - 0x5f, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x52, 0x59, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x4f, - 0x54, 0x48, 0x45, 0x52, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x4c, 0x4f, 0x43, 0x41, 0x4c, 0x10, - 0x03, 0x42, 0x3f, 0x50, 0x01, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x73, 0x63, 0x61, 0x6c, 0x69, 0x62, 0x72, - 0x2f, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x63, - 0x61, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x5f, 0x67, 0x6f, 0x5f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x79, 0x1a, 0x44, 0x0a, 0x1a, 0x47, 0x43, 0x50, 0x4f, 0x41, 0x75, 0x74, 0x68, 0x32, 0x43, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, + 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, + 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x1a, 0x2c, 0x0a, 0x14, 0x47, 0x43, 0x50, 0x4f, 0x41, + 0x75, 0x74, 0x68, 0x32, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, + 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x1a, 0x41, 0x0a, 0x0a, 0x47, 0x43, 0x53, 0x48, 0x6d, 0x61, 0x63, + 0x4b, 0x65, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x49, 0x64, + 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x1a, 0xa8, 0x01, 0x0a, 0x13, 0x4d, 0x79, 0x73, + 0x71, 0x6c, 0x4d, 0x79, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, + 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, + 0x6f, 0x72, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, + 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x63, + 0x6b, 0x65, 0x74, 0x1a, 0x4a, 0x0a, 0x08, 0x56, 0x61, 0x70, 0x69, 0x64, 0x4b, 0x65, 0x79, 0x12, + 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x62, 0x36, 0x34, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x42, 0x36, 0x34, + 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x62, 0x36, 0x34, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x42, 0x36, 0x34, 0x1a, + 0xb0, 0x02, 0x0a, 0x17, 0x4f, 0x6e, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x43, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x55, 0x75, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, + 0x74, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, + 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x12, 0x2a, 0x0a, + 0x11, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x5f, + 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x76, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x76, 0x12, 0x22, 0x0a, 0x0d, 0x75, 0x6e, 0x69, + 0x71, 0x75, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x23, 0x0a, + 0x0d, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x72, 0x5f, 0x73, 0x61, 0x6c, 0x74, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x72, 0x53, 0x61, + 0x6c, 0x74, 0x12, 0x2e, 0x0a, 0x13, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x72, 0x5f, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x11, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x72, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x48, 0x61, + 0x73, 0x68, 0x1a, 0x28, 0x0a, 0x14, 0x4f, 0x6e, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, + 0x64, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x1a, 0x2b, 0x0a, 0x17, + 0x4f, 0x6e, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x1a, 0x2b, 0x0a, 0x17, 0x4f, 0x6e, 0x65, + 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, + 0x43, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x1a, 0x4e, 0x0a, 0x17, 0x41, 0x77, 0x73, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, + 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x49, 0x64, 0x12, 0x16, + 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x1a, 0x26, 0x0a, 0x0c, 0x52, 0x65, 0x43, 0x61, 0x70, 0x74, + 0x63, 0x68, 0x61, 0x4b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x1a, 0x2b, + 0x0a, 0x17, 0x43, 0x6f, 0x64, 0x65, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x79, 0x73, 0x74, 0x43, 0x72, + 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x42, 0x08, 0x0a, 0x06, 0x73, + 0x65, 0x63, 0x72, 0x65, 0x74, 0x22, 0xf8, 0x01, 0x0a, 0x0c, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x3e, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x69, 0x62, 0x72, + 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x53, 0x65, + 0x63, 0x72, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x06, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x3d, 0x0a, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x64, 0x22, 0x69, 0x0a, 0x10, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x4e, 0x53, + 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x07, 0x55, 0x4e, + 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x01, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x49, + 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x56, 0x41, 0x4c, 0x49, + 0x44, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x55, 0x50, 0x50, 0x4f, 0x52, 0x54, + 0x45, 0x44, 0x10, 0x04, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x05, + 0x22, 0xc8, 0x02, 0x0a, 0x08, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2f, 0x0a, + 0x08, 0x66, 0x69, 0x6c, 0x65, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x11, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x69, 0x62, 0x72, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x70, 0x61, + 0x74, 0x68, 0x48, 0x00, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x70, 0x61, 0x74, 0x68, 0x12, 0x62, + 0x0a, 0x1b, 0x66, 0x69, 0x6c, 0x65, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, + 0x6c, 0x61, 0x79, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x69, 0x62, 0x72, 0x2e, 0x46, 0x69, + 0x6c, 0x65, 0x70, 0x61, 0x74, 0x68, 0x57, 0x69, 0x74, 0x68, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x44, + 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x48, 0x00, 0x52, 0x18, 0x66, 0x69, 0x6c, 0x65, 0x70, 0x61, + 0x74, 0x68, 0x57, 0x69, 0x74, 0x68, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x44, 0x65, 0x74, 0x61, 0x69, + 0x6c, 0x73, 0x12, 0x51, 0x0a, 0x14, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, + 0x74, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1c, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x69, 0x62, 0x72, 0x2e, 0x45, 0x6e, 0x76, 0x69, 0x72, + 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x48, 0x00, + 0x52, 0x13, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, + 0x69, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x48, 0x0a, 0x11, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x19, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x69, 0x62, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x48, 0x00, 0x52, 0x10, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x42, + 0x0a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x1e, 0x0a, 0x08, 0x46, + 0x69, 0x6c, 0x65, 0x70, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0x6a, 0x0a, 0x18, 0x46, + 0x69, 0x6c, 0x65, 0x70, 0x61, 0x74, 0x68, 0x57, 0x69, 0x74, 0x68, 0x4c, 0x61, 0x79, 0x65, 0x72, + 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x3a, 0x0a, 0x0d, 0x6c, + 0x61, 0x79, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x69, 0x62, 0x72, 0x2e, 0x4c, 0x61, 0x79, + 0x65, 0x72, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x0c, 0x6c, 0x61, 0x79, 0x65, 0x72, + 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x29, 0x0a, 0x13, 0x45, 0x6e, 0x76, 0x69, 0x72, + 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x22, 0x2c, 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x43, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, + 0x22, 0xb3, 0x02, 0x0a, 0x16, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6d, + 0x61, 0x67, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x12, 0x3d, 0x0a, 0x0e, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x63, 0x61, 0x6c, + 0x69, 0x62, 0x72, 0x2e, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x52, 0x0d, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x12, 0x43, 0x0a, 0x11, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x5f, 0x63, + 0x68, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x63, + 0x61, 0x6c, 0x69, 0x62, 0x72, 0x2e, 0x42, 0x61, 0x73, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x43, + 0x68, 0x61, 0x69, 0x6e, 0x52, 0x0f, 0x62, 0x61, 0x73, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x43, + 0x68, 0x61, 0x69, 0x6e, 0x73, 0x12, 0x44, 0x0a, 0x07, 0x6f, 0x73, 0x5f, 0x69, 0x6e, 0x66, 0x6f, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x69, 0x62, 0x72, + 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4f, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x06, 0x6f, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0x39, 0x0a, 0x0b, 0x4f, + 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x67, 0x0a, 0x0e, 0x42, 0x61, 0x73, 0x65, 0x49, 0x6d, + 0x61, 0x67, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x3a, 0x0a, 0x0b, 0x62, 0x61, 0x73, 0x65, + 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, + 0x73, 0x63, 0x61, 0x6c, 0x69, 0x62, 0x72, 0x2e, 0x42, 0x61, 0x73, 0x65, 0x49, 0x6d, 0x61, 0x67, + 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x0a, 0x62, 0x61, 0x73, 0x65, 0x49, 0x6d, + 0x61, 0x67, 0x65, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x22, + 0x66, 0x0a, 0x10, 0x42, 0x61, 0x73, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x44, 0x65, 0x74, 0x61, + 0x69, 0x6c, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x6f, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x12, + 0x16, 0x0a, 0x06, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x22, 0xb8, 0x01, 0x0a, 0x0d, 0x4c, 0x61, 0x79, 0x65, + 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, + 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, + 0x17, 0x0a, 0x07, 0x64, 0x69, 0x66, 0x66, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x64, 0x69, 0x66, 0x66, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x19, 0x0a, + 0x08, 0x69, 0x73, 0x5f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x07, 0x69, 0x73, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x28, 0x0a, 0x10, 0x62, 0x61, 0x73, 0x65, + 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x0e, 0x62, 0x61, 0x73, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x64, + 0x65, 0x78, 0x2a, 0xf7, 0x01, 0x0a, 0x10, 0x56, 0x65, 0x78, 0x4a, 0x75, 0x73, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x1d, 0x56, 0x45, 0x58, 0x5f, 0x4a, + 0x55, 0x53, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, + 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x43, 0x4f, + 0x4d, 0x50, 0x4f, 0x4e, 0x45, 0x4e, 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x50, 0x52, 0x45, 0x53, + 0x45, 0x4e, 0x54, 0x10, 0x01, 0x12, 0x1f, 0x0a, 0x1b, 0x56, 0x55, 0x4c, 0x4e, 0x45, 0x52, 0x41, + 0x42, 0x4c, 0x45, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x50, 0x52, 0x45, + 0x53, 0x45, 0x4e, 0x54, 0x10, 0x02, 0x12, 0x27, 0x0a, 0x23, 0x56, 0x55, 0x4c, 0x4e, 0x45, 0x52, + 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x49, 0x4e, + 0x5f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x45, 0x5f, 0x50, 0x41, 0x54, 0x48, 0x10, 0x03, 0x12, + 0x35, 0x0a, 0x31, 0x56, 0x55, 0x4c, 0x4e, 0x45, 0x52, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x43, 0x4f, + 0x44, 0x45, 0x5f, 0x43, 0x41, 0x4e, 0x4e, 0x4f, 0x54, 0x5f, 0x42, 0x45, 0x5f, 0x43, 0x4f, 0x4e, + 0x54, 0x52, 0x4f, 0x4c, 0x4c, 0x45, 0x44, 0x5f, 0x42, 0x59, 0x5f, 0x41, 0x44, 0x56, 0x45, 0x52, + 0x53, 0x41, 0x52, 0x59, 0x10, 0x04, 0x12, 0x24, 0x0a, 0x20, 0x49, 0x4e, 0x4c, 0x49, 0x4e, 0x45, + 0x5f, 0x4d, 0x49, 0x54, 0x49, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x4c, 0x52, 0x45, + 0x41, 0x44, 0x59, 0x5f, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x10, 0x05, 0x2a, 0x62, 0x0a, 0x0c, + 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x18, 0x0a, 0x14, + 0x53, 0x45, 0x56, 0x45, 0x52, 0x49, 0x54, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x4d, 0x49, 0x4e, 0x49, 0x4d, 0x41, + 0x4c, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x4c, 0x4f, 0x57, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, + 0x4d, 0x45, 0x44, 0x49, 0x55, 0x4d, 0x10, 0x03, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x49, 0x47, 0x48, + 0x10, 0x04, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x52, 0x49, 0x54, 0x49, 0x43, 0x41, 0x4c, 0x10, 0x05, + 0x2a, 0x47, 0x0a, 0x0d, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x13, + 0x0a, 0x0f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x52, + 0x59, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x4f, 0x54, 0x48, 0x45, 0x52, 0x10, 0x02, 0x12, 0x09, + 0x0a, 0x05, 0x4c, 0x4f, 0x43, 0x41, 0x4c, 0x10, 0x03, 0x42, 0x3f, 0x50, 0x01, 0x5a, 0x3b, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2f, 0x73, 0x63, 0x61, 0x6c, 0x69, 0x62, 0x72, 0x2f, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x63, 0x61, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x5f, 0x67, 0x6f, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( @@ -10824,7 +10893,7 @@ func file_proto_scan_result_proto_rawDescGZIP() []byte { } var file_proto_scan_result_proto_enumTypes = make([]protoimpl.EnumInfo, 5) -var file_proto_scan_result_proto_msgTypes = make([]protoimpl.MessageInfo, 120) +var file_proto_scan_result_proto_msgTypes = make([]protoimpl.MessageInfo, 121) var file_proto_scan_result_proto_goTypes = []any{ (VexJustification)(0), // 0: scalibr.VexJustification (SeverityEnum)(0), // 1: scalibr.SeverityEnum @@ -10950,12 +11019,13 @@ var file_proto_scan_result_proto_goTypes = []any{ (*SecretData_OnePasswordRecoveryCode)(nil), // 121: scalibr.SecretData.OnePasswordRecoveryCode (*SecretData_AwsAccessKeyCredentials)(nil), // 122: scalibr.SecretData.AwsAccessKeyCredentials (*SecretData_ReCaptchaKey)(nil), // 123: scalibr.SecretData.ReCaptchaKey - nil, // 124: scalibr.ContainerImageMetadata.OsInfoEntry - (*timestamppb.Timestamp)(nil), // 125: google.protobuf.Timestamp + (*SecretData_CodeCatalystCredentials)(nil), // 124: scalibr.SecretData.CodeCatalystCredentials + nil, // 125: scalibr.ContainerImageMetadata.OsInfoEntry + (*timestamppb.Timestamp)(nil), // 126: google.protobuf.Timestamp } var file_proto_scan_result_proto_depIdxs = []int32{ - 125, // 0: scalibr.ScanResult.start_time:type_name -> google.protobuf.Timestamp - 125, // 1: scalibr.ScanResult.end_time:type_name -> google.protobuf.Timestamp + 126, // 0: scalibr.ScanResult.start_time:type_name -> google.protobuf.Timestamp + 126, // 1: scalibr.ScanResult.end_time:type_name -> google.protobuf.Timestamp 7, // 2: scalibr.ScanResult.status:type_name -> scalibr.ScanStatus 8, // 3: scalibr.ScanResult.plugin_status:type_name -> scalibr.PluginStatus 6, // 4: scalibr.ScanResult.inventory:type_name -> scalibr.Inventory @@ -11019,8 +11089,8 @@ var file_proto_scan_result_proto_depIdxs = []int32{ 16, // 62: scalibr.SPDXPackageMetadata.purl:type_name -> scalibr.Purl 16, // 63: scalibr.CDXPackageMetadata.purl:type_name -> scalibr.Purl 73, // 64: scalibr.PodmanMetadata.exposed_ports:type_name -> scalibr.PodmanMetadata.ExposedPortsEntry - 125, // 65: scalibr.PodmanMetadata.started_time:type_name -> google.protobuf.Timestamp - 125, // 66: scalibr.PodmanMetadata.finished_time:type_name -> google.protobuf.Timestamp + 126, // 65: scalibr.PodmanMetadata.started_time:type_name -> google.protobuf.Timestamp + 126, // 66: scalibr.PodmanMetadata.finished_time:type_name -> google.protobuf.Timestamp 58, // 67: scalibr.DockerContainersMetadata.ports:type_name -> scalibr.DockerPort 61, // 68: scalibr.Secret.secret:type_name -> scalibr.SecretData 62, // 69: scalibr.Secret.status:type_name -> scalibr.SecretStatus @@ -11075,23 +11145,24 @@ var file_proto_scan_result_proto_depIdxs = []int32{ 117, // 118: scalibr.SecretData.vapid_key:type_name -> scalibr.SecretData.VapidKey 122, // 119: scalibr.SecretData.aws_access_key_credentials:type_name -> scalibr.SecretData.AwsAccessKeyCredentials 123, // 120: scalibr.SecretData.re_captcha_key:type_name -> scalibr.SecretData.ReCaptchaKey - 4, // 121: scalibr.SecretStatus.status:type_name -> scalibr.SecretStatus.SecretStatusEnum - 125, // 122: scalibr.SecretStatus.last_updated:type_name -> google.protobuf.Timestamp - 64, // 123: scalibr.Location.filepath:type_name -> scalibr.Filepath - 65, // 124: scalibr.Location.filepath_with_layer_details:type_name -> scalibr.FilepathWithLayerDetails - 66, // 125: scalibr.Location.environment_variable:type_name -> scalibr.EnvironmentVariable - 67, // 126: scalibr.Location.container_command:type_name -> scalibr.ContainerCommand - 12, // 127: scalibr.FilepathWithLayerDetails.layer_details:type_name -> scalibr.LayerDetails - 71, // 128: scalibr.ContainerImageMetadata.layer_metadata:type_name -> scalibr.LayerMetadata - 69, // 129: scalibr.ContainerImageMetadata.base_image_chains:type_name -> scalibr.BaseImageChain - 124, // 130: scalibr.ContainerImageMetadata.os_info:type_name -> scalibr.ContainerImageMetadata.OsInfoEntry - 70, // 131: scalibr.BaseImageChain.base_images:type_name -> scalibr.BaseImageDetails - 53, // 132: scalibr.PodmanMetadata.ExposedPortsEntry.value:type_name -> scalibr.Protocol - 133, // [133:133] is the sub-list for method output_type - 133, // [133:133] is the sub-list for method input_type - 133, // [133:133] is the sub-list for extension type_name - 133, // [133:133] is the sub-list for extension extendee - 0, // [0:133] is the sub-list for field type_name + 124, // 121: scalibr.SecretData.code_catalyst_credentials:type_name -> scalibr.SecretData.CodeCatalystCredentials + 4, // 122: scalibr.SecretStatus.status:type_name -> scalibr.SecretStatus.SecretStatusEnum + 126, // 123: scalibr.SecretStatus.last_updated:type_name -> google.protobuf.Timestamp + 64, // 124: scalibr.Location.filepath:type_name -> scalibr.Filepath + 65, // 125: scalibr.Location.filepath_with_layer_details:type_name -> scalibr.FilepathWithLayerDetails + 66, // 126: scalibr.Location.environment_variable:type_name -> scalibr.EnvironmentVariable + 67, // 127: scalibr.Location.container_command:type_name -> scalibr.ContainerCommand + 12, // 128: scalibr.FilepathWithLayerDetails.layer_details:type_name -> scalibr.LayerDetails + 71, // 129: scalibr.ContainerImageMetadata.layer_metadata:type_name -> scalibr.LayerMetadata + 69, // 130: scalibr.ContainerImageMetadata.base_image_chains:type_name -> scalibr.BaseImageChain + 125, // 131: scalibr.ContainerImageMetadata.os_info:type_name -> scalibr.ContainerImageMetadata.OsInfoEntry + 70, // 132: scalibr.BaseImageChain.base_images:type_name -> scalibr.BaseImageDetails + 53, // 133: scalibr.PodmanMetadata.ExposedPortsEntry.value:type_name -> scalibr.Protocol + 134, // [134:134] is the sub-list for method output_type + 134, // [134:134] is the sub-list for method input_type + 134, // [134:134] is the sub-list for extension type_name + 134, // [134:134] is the sub-list for extension extendee + 0, // [0:134] is the sub-list for field type_name } func init() { file_proto_scan_result_proto_init() } @@ -11192,6 +11263,7 @@ func file_proto_scan_result_proto_init() { (*SecretData_VapidKey_)(nil), (*SecretData_AwsAccessKeyCredentials_)(nil), (*SecretData_ReCaptchaKey_)(nil), + (*SecretData_CodeCatalystCredentials_)(nil), } file_proto_scan_result_proto_msgTypes[58].OneofWrappers = []any{ (*Location_Filepath)(nil), @@ -11205,7 +11277,7 @@ func file_proto_scan_result_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_proto_scan_result_proto_rawDesc, NumEnums: 5, - NumMessages: 120, + NumMessages: 121, NumExtensions: 0, NumServices: 0, }, diff --git a/binary/proto/secret.go b/binary/proto/secret.go index 857a01d9d..c22f0ea1d 100644 --- a/binary/proto/secret.go +++ b/binary/proto/secret.go @@ -38,6 +38,7 @@ import ( "github.com/google/osv-scalibr/veles/secrets/gcpoauth2client" velesgcpsak "github.com/google/osv-scalibr/veles/secrets/gcpsak" "github.com/google/osv-scalibr/veles/secrets/gcshmackey" + "github.com/google/osv-scalibr/veles/secrets/gitbasicauth/codecatalyst" velesgithub "github.com/google/osv-scalibr/veles/secrets/github" "github.com/google/osv-scalibr/veles/secrets/gitlabpat" velesgrokxaiapikey "github.com/google/osv-scalibr/veles/secrets/grokxaiapikey" @@ -215,11 +216,23 @@ func velesSecretToProto(s veles.Secret) (*spb.SecretData, error) { return vapidKeyToProto(t), nil case recaptchakey.Key: return reCaptchaKeyToProto(t), nil + case codecatalyst.Credentials: + return codeCatalystCredentialsToProto(t), nil default: return nil, fmt.Errorf("%w: %T", ErrUnsupportedSecretType, s) } } +func codeCatalystCredentialsToProto(s codecatalyst.Credentials) *spb.SecretData { + return &spb.SecretData{ + Secret: &spb.SecretData_CodeCatalystCredentials_{ + CodeCatalystCredentials: &spb.SecretData_CodeCatalystCredentials{ + Url: s.FullURL, + }, + }, + } +} + func awsAccessKeyCredentialToProto(s awsaccesskey.Credentials) *spb.SecretData { return &spb.SecretData{ Secret: &spb.SecretData_AwsAccessKeyCredentials_{ @@ -947,6 +960,10 @@ func velesSecretToStruct(s *spb.SecretData) (veles.Secret, error) { return recaptchakey.Key{ Secret: s.GetReCaptchaKey().GetSecret(), }, nil + case *spb.SecretData_CodeCatalystCredentials_: + return codecatalyst.Credentials{ + FullURL: s.GetCodeCatalystCredentials().GetUrl(), + }, nil default: return nil, fmt.Errorf("%w: %T", ErrUnsupportedSecretType, s.GetSecret()) } From 448310b512baa6173461eb916b088bae5ce9e583 Mon Sep 17 00:00:00 2001 From: alessandro-Doyensec Date: Wed, 3 Dec 2025 11:44:19 +0100 Subject: [PATCH 07/11] add: filesystem extractor --- .../gitbasicauth/codecatalyst/codecatalyst.go | 1 + .../codecatalyst/codecatalyst_test.go | 146 ++++++++++++++++++ .../codecatalyst/testdata/.zsh_history | 9 ++ .../gitbasicauth/codecatalyst/testdata/empty | 0 .../codecatalyst/testdata/git_config | 13 ++ .../codecatalyst/testdata/git_credentials | 2 + .../codecatalyst/testdata/random_content | 10 ++ 7 files changed, 181 insertions(+) create mode 100644 extractor/filesystem/secrets/gitbasicauth/codecatalyst/codecatalyst_test.go create mode 100644 extractor/filesystem/secrets/gitbasicauth/codecatalyst/testdata/.zsh_history create mode 100644 extractor/filesystem/secrets/gitbasicauth/codecatalyst/testdata/empty create mode 100644 extractor/filesystem/secrets/gitbasicauth/codecatalyst/testdata/git_config create mode 100644 extractor/filesystem/secrets/gitbasicauth/codecatalyst/testdata/git_credentials create mode 100644 extractor/filesystem/secrets/gitbasicauth/codecatalyst/testdata/random_content diff --git a/extractor/filesystem/secrets/gitbasicauth/codecatalyst/codecatalyst.go b/extractor/filesystem/secrets/gitbasicauth/codecatalyst/codecatalyst.go index f9a4961e8..cf911047b 100644 --- a/extractor/filesystem/secrets/gitbasicauth/codecatalyst/codecatalyst.go +++ b/extractor/filesystem/secrets/gitbasicauth/codecatalyst/codecatalyst.go @@ -43,6 +43,7 @@ func New() filesystem.Extractor { func FileRequired(api filesystem.FileAPI) bool { path := filepath.ToSlash(api.Path()) return strings.HasSuffix(path, ".git/config") || + strings.HasSuffix(path, ".git-credentials") || strings.HasSuffix(path, "_history") || strings.HasSuffix(path, ".history.txt") } diff --git a/extractor/filesystem/secrets/gitbasicauth/codecatalyst/codecatalyst_test.go b/extractor/filesystem/secrets/gitbasicauth/codecatalyst/codecatalyst_test.go new file mode 100644 index 000000000..8229f9a14 --- /dev/null +++ b/extractor/filesystem/secrets/gitbasicauth/codecatalyst/codecatalyst_test.go @@ -0,0 +1,146 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package codecatalyst_test + +import ( + "runtime" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/google/osv-scalibr/extractor/filesystem/secrets/gitbasicauth/codecatalyst" + "github.com/google/osv-scalibr/extractor/filesystem/simplefileapi" + "github.com/google/osv-scalibr/inventory" + "github.com/google/osv-scalibr/testing/extracttest" + codecatalystdetector "github.com/google/osv-scalibr/veles/secrets/gitbasicauth/codecatalyst" +) + +func TestExtractor_FileRequired(t *testing.T) { + tests := []struct { + inputPath string + want bool + isWindows bool + }{ + {inputPath: "", want: false}, + + // linux + {inputPath: `/Users/example-user/folder/.git/config`, want: true}, + {inputPath: `/Users/example-user/.git-credentials`, want: true}, + {inputPath: `/Users/example-user/.zsh_history`, want: true}, + {inputPath: `/Users/example-user/bad/path`, want: false}, + + // windows + {inputPath: `C:\Users\USERNAME\folder\.git\config`, isWindows: true, want: true}, + {inputPath: `C:\Users\YourUserName\AppData\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.tx`, isWindows: true, want: true}, + {inputPath: `C:\Users\YourUserName\.git-credentials`, isWindows: true, want: true}, + {inputPath: `C:\Users\USERNAME\another\bad\path`, isWindows: true, want: false}, + } + + for _, tt := range tests { + t.Run(tt.inputPath, func(t *testing.T) { + if tt.isWindows && runtime.GOOS != "windows" { + t.Skipf("Skipping test %q for %q", t.Name(), runtime.GOOS) + } + e := codecatalyst.New() + got := e.FileRequired(simplefileapi.New(tt.inputPath, nil)) + if got != tt.want { + t.Errorf("FileRequired(%s) got = %v, want %v", tt.inputPath, got, tt.want) + } + }) + } +} + +func TestExtractor_Extract(t *testing.T) { + tests := []*struct { + Name string + Path string + WantSecrets []*inventory.Secret + WantErr error + }{ + { + Name: "empty", + Path: "empty", + WantSecrets: nil, + }, + { + Name: "git_credentials", + Path: "git_credentials", + WantSecrets: []*inventory.Secret{ + { + Secret: codecatalystdetector.Credentials{ + FullURL: `https://user:password@git.region.codecatalyst.aws/v1/space/project/repo`, + }, + Location: "git_credentials", + }, + }, + }, + { + Name: "git_config", + Path: "git_config", + WantSecrets: []*inventory.Secret{ + { + Secret: codecatalystdetector.Credentials{ + FullURL: `https://user:password@git.region.codecatalyst.aws/v1/space/project/repo`, + }, + Location: "git_config", + }, + }, + }, + { + Name: "history_file", + Path: ".zsh_history", + WantSecrets: []*inventory.Secret{ + { + Secret: codecatalystdetector.Credentials{ + FullURL: `https://user:password@git.region.codecatalyst.aws/v1/space/project/test-repo`, + }, + Location: ".zsh_history", + }, + }, + }, + { + Name: "random_content", + Path: "random_content", + WantSecrets: nil, + }, + } + + for _, tt := range tests { + t.Run(tt.Name, func(t *testing.T) { + extr := codecatalyst.New() + + inputCfg := extracttest.ScanInputMockConfig{ + Path: tt.Path, + FakeScanRoot: "testdata", + } + + scanInput := extracttest.GenerateScanInputMock(t, inputCfg) + defer extracttest.CloseTestScanInput(t, scanInput) + + got, err := extr.Extract(t.Context(), &scanInput) + + if diff := cmp.Diff(tt.WantErr, err, cmpopts.EquateErrors()); diff != "" { + t.Errorf("%s.Extract(%q) error diff (-want +got):\n%s", extr.Name(), tt.Path, diff) + return + } + + wantInv := inventory.Inventory{Secrets: tt.WantSecrets} + opts := []cmp.Option{cmpopts.SortSlices(extracttest.PackageCmpLess), cmpopts.EquateEmpty()} + if diff := cmp.Diff(wantInv, got, opts...); diff != "" { + t.Errorf("%s.Extract(%q) diff (-want +got):\n%s", extr.Name(), tt.Path, diff) + } + }) + } +} diff --git a/extractor/filesystem/secrets/gitbasicauth/codecatalyst/testdata/.zsh_history b/extractor/filesystem/secrets/gitbasicauth/codecatalyst/testdata/.zsh_history new file mode 100644 index 000000000..16bd4bbf0 --- /dev/null +++ b/extractor/filesystem/secrets/gitbasicauth/codecatalyst/testdata/.zsh_history @@ -0,0 +1,9 @@ +: 1:0;cd /tmp +: 2:0;git clone https://user:password@git.region.codecatalyst.aws/v1/space/project/test-repo +: 3:0;cd test-repo +: 4:0;ls +: 5:0;cd .git +: 6:0;ls +: 7:0;cat config +: 8:0;cat .zsh_history +: 9:0;cat .zsh_history | tail -50 | pbcopy diff --git a/extractor/filesystem/secrets/gitbasicauth/codecatalyst/testdata/empty b/extractor/filesystem/secrets/gitbasicauth/codecatalyst/testdata/empty new file mode 100644 index 000000000..e69de29bb diff --git a/extractor/filesystem/secrets/gitbasicauth/codecatalyst/testdata/git_config b/extractor/filesystem/secrets/gitbasicauth/codecatalyst/testdata/git_config new file mode 100644 index 000000000..5dd6063db --- /dev/null +++ b/extractor/filesystem/secrets/gitbasicauth/codecatalyst/testdata/git_config @@ -0,0 +1,13 @@ +[core] + repositoryformatversion = 0 + filemode = true + bare = false + logallrefupdates = true + ignorecase = true + precomposeunicode = true +[remote "origin"] + url = https://user:password@git.region.codecatalyst.aws/v1/space/project/repo + fetch = +refs/heads/*:refs/remotes/origin/* +[branch "main"] + remote = origin + merge = refs/heads/main diff --git a/extractor/filesystem/secrets/gitbasicauth/codecatalyst/testdata/git_credentials b/extractor/filesystem/secrets/gitbasicauth/codecatalyst/testdata/git_credentials new file mode 100644 index 000000000..eda36613d --- /dev/null +++ b/extractor/filesystem/secrets/gitbasicauth/codecatalyst/testdata/git_credentials @@ -0,0 +1,2 @@ +https://user:password@git.region.codecatalyst.aws/v1/space/project/repo +https://anotheruser:password@github.com/user/repo diff --git a/extractor/filesystem/secrets/gitbasicauth/codecatalyst/testdata/random_content b/extractor/filesystem/secrets/gitbasicauth/codecatalyst/testdata/random_content new file mode 100644 index 000000000..e62a6bb7a --- /dev/null +++ b/extractor/filesystem/secrets/gitbasicauth/codecatalyst/testdata/random_content @@ -0,0 +1,10 @@ +localhost:5432:mydb:myuser:mypassword +hostname:1234:testdb:testuser:testpass123 +hostname:1234:testdb:testuser:passw*ord +# space inside one group (except password) +hostname:1234:testdb:testuser:passw ord +hostname:1234:db name:testuser:password +# this is a comment and should be ignored +*:*:db:admin:supersecret +# valid with escaped : +prod.example.com:5432:db:admin:pass\:word From 29d3453f6623326b3e59581279e01c2bf2d18f0c Mon Sep 17 00:00:00 2001 From: alessandro-Doyensec Date: Wed, 3 Dec 2025 12:16:12 +0100 Subject: [PATCH 08/11] add: supported invenotory types fix: validator name --- docs/supported_inventory_types.md | 1 + enricher/enricherlist/list.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/supported_inventory_types.md b/docs/supported_inventory_types.md index cbdfedc2a..4485cea51 100644 --- a/docs/supported_inventory_types.md +++ b/docs/supported_inventory_types.md @@ -112,6 +112,7 @@ See the docs on [how to add a new Extractor](/docs/new_extractor.md). | Type | Extractor Plugin | |---------------------------------------------|--------------------------------------| | AWS access key | `secrets/awsaccesskey` | +| Amazon CodeCatalyst credentials | `secrets/codecatalystcredentials` | | Anthropic API key | `secrets/anthropicapikey` | | Azure Token | `secrets/azuretoken` | | Crates.io API Token | `secrets/cratesioapitoken` | diff --git a/enricher/enricherlist/list.go b/enricher/enricherlist/list.go index ea41373ae..2395f2504 100644 --- a/enricher/enricherlist/list.go +++ b/enricher/enricherlist/list.go @@ -119,7 +119,7 @@ var ( fromVeles(gcpoauth2access.NewValidator(), "secrets/gcpoauth2accesstokenvalidate", 0), fromVeles(gcshmackey.NewValidator(), "secrets/gcshmackeyvalidate", 0), fromVeles(awsaccesskey.NewValidator(), "secrets/awsaccesskeyvalidate", 0), - fromVeles(codecatalyst.NewValidator(), "secretsc/odecatalystcredentialsvalidate", 0), + fromVeles(codecatalyst.NewValidator(), "secrets/codecatalystcredentialsvalidate", 0), }) // SecretsEnrich lists enrichers that add data to detected secrets. From c1abfc74e69dc52eb36e620367449eb939607714 Mon Sep 17 00:00:00 2001 From: alessandro-Doyensec Date: Wed, 3 Dec 2025 13:58:16 +0100 Subject: [PATCH 09/11] edit: remove redundant fileRequired condition --- .../secrets/gitbasicauth/codecatalyst/codecatalyst.go | 3 +-- .../secrets/gitbasicauth/codecatalyst/codecatalyst_test.go | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/extractor/filesystem/secrets/gitbasicauth/codecatalyst/codecatalyst.go b/extractor/filesystem/secrets/gitbasicauth/codecatalyst/codecatalyst.go index cf911047b..9ffe38c2c 100644 --- a/extractor/filesystem/secrets/gitbasicauth/codecatalyst/codecatalyst.go +++ b/extractor/filesystem/secrets/gitbasicauth/codecatalyst/codecatalyst.go @@ -44,6 +44,5 @@ func FileRequired(api filesystem.FileAPI) bool { path := filepath.ToSlash(api.Path()) return strings.HasSuffix(path, ".git/config") || strings.HasSuffix(path, ".git-credentials") || - strings.HasSuffix(path, "_history") || - strings.HasSuffix(path, ".history.txt") + strings.HasSuffix(path, "_history") } diff --git a/extractor/filesystem/secrets/gitbasicauth/codecatalyst/codecatalyst_test.go b/extractor/filesystem/secrets/gitbasicauth/codecatalyst/codecatalyst_test.go index 8229f9a14..241f4c20f 100644 --- a/extractor/filesystem/secrets/gitbasicauth/codecatalyst/codecatalyst_test.go +++ b/extractor/filesystem/secrets/gitbasicauth/codecatalyst/codecatalyst_test.go @@ -43,7 +43,6 @@ func TestExtractor_FileRequired(t *testing.T) { // windows {inputPath: `C:\Users\USERNAME\folder\.git\config`, isWindows: true, want: true}, - {inputPath: `C:\Users\YourUserName\AppData\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.tx`, isWindows: true, want: true}, {inputPath: `C:\Users\YourUserName\.git-credentials`, isWindows: true, want: true}, {inputPath: `C:\Users\USERNAME\another\bad\path`, isWindows: true, want: false}, } From 847f4afc60d395dd6d5c5038684040d9b17f07e0 Mon Sep 17 00:00:00 2001 From: alessandro-Doyensec Date: Mon, 8 Dec 2025 17:25:28 +0100 Subject: [PATCH 10/11] fix: resolve conversation edit: convert the detector to a simpletoken.detector --- .../gitbasicauth/codecatalyst/codecatalyst.go | 5 ++- .../gitbasicauth/codecatalyst/codecatalyst.go | 4 +- .../gitbasicauth/codecatalyst/detector.go | 39 +++++++------------ 3 files changed, 20 insertions(+), 28 deletions(-) diff --git a/extractor/filesystem/secrets/gitbasicauth/codecatalyst/codecatalyst.go b/extractor/filesystem/secrets/gitbasicauth/codecatalyst/codecatalyst.go index 9ffe38c2c..decc2bbb9 100644 --- a/extractor/filesystem/secrets/gitbasicauth/codecatalyst/codecatalyst.go +++ b/extractor/filesystem/secrets/gitbasicauth/codecatalyst/codecatalyst.go @@ -39,7 +39,10 @@ func New() filesystem.Extractor { ) } -// FileRequired returns true if a file should be searched by the plugin. +// FileRequired reports whether the plugin should scan the given file. +// +// The history.txt file is intentionally excluded because it is already +// processed by the main secrets extractor. func FileRequired(api filesystem.FileAPI) bool { path := filepath.ToSlash(api.Path()) return strings.HasSuffix(path, ".git/config") || diff --git a/veles/secrets/gitbasicauth/codecatalyst/codecatalyst.go b/veles/secrets/gitbasicauth/codecatalyst/codecatalyst.go index 2ba844c3b..42958dcf8 100644 --- a/veles/secrets/gitbasicauth/codecatalyst/codecatalyst.go +++ b/veles/secrets/gitbasicauth/codecatalyst/codecatalyst.go @@ -12,10 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package codecatalyst contains the logic to extract CodeCatalyst credentials. +// Package codecatalyst contains the logic to extract Amazon CodeCatalyst personal access tokens. package codecatalyst -// Credentials contains basic auth credential for CodeCatalyst. +// Credentials contains basic auth credential for Amazon CodeCatalyst. type Credentials struct { FullURL string } diff --git a/veles/secrets/gitbasicauth/codecatalyst/detector.go b/veles/secrets/gitbasicauth/codecatalyst/detector.go index 402b50fb4..62a965db8 100644 --- a/veles/secrets/gitbasicauth/codecatalyst/detector.go +++ b/veles/secrets/gitbasicauth/codecatalyst/detector.go @@ -19,6 +19,7 @@ import ( "regexp" "github.com/google/osv-scalibr/veles" + "github.com/google/osv-scalibr/veles/secrets/common/simpletoken" ) const ( @@ -32,34 +33,22 @@ var ( urlPattern = regexp.MustCompile(`\bhttps://[^:\s]+:[^\s@]+@git\.[^/]*codecatalyst\.aws/[^\s]*`) ) -type detector struct{} - // NewDetector creates and returns a new instance of the CodeCatalyst secret detector. func NewDetector() veles.Detector { - return &detector{} -} - -// MaxSecretLen returns the maximum expected length of the secret. -func (d *detector) MaxSecretLen() uint32 { - return maxURLLength -} - -// Detect scans the provided byte slice for AWS CodeCatalyst credentials. -func (d *detector) Detect(data []byte) ([]veles.Secret, []int) { - secrets, positions := []veles.Secret{}, []int{} - matches := urlPattern.FindAllSubmatchIndex(data, -1) - for _, m := range matches { - fullURL := data[m[0]:m[1]] - u, err := url.Parse(string(fullURL)) - if err != nil { - continue - } - if !hasValidCredentials(u) { - continue - } - secrets = append(secrets, Credentials{FullURL: u.String()}) + return simpletoken.Detector{ + MaxLen: maxURLLength, + Re: urlPattern, + FromMatch: func(b []byte) (veles.Secret, bool) { + u, err := url.Parse(string(b)) + if err != nil { + return nil, false + } + if !hasValidCredentials(u) { + return nil, false + } + return Credentials{FullURL: u.String()}, true + }, } - return secrets, positions } func hasValidCredentials(u *url.URL) bool { From fe9c4619e66339a573ff307ef0aaed95333f3987 Mon Sep 17 00:00:00 2001 From: alessandro-Doyensec Date: Mon, 8 Dec 2025 17:42:23 +0100 Subject: [PATCH 11/11] edit: use simplevalidate.Validator --- .../gitbasicauth/codecatalyst/validator.go | 62 ++++++------------- .../codecatalyst/validator_test.go | 2 +- veles/secrets/gitbasicauth/gitbasicauth.go | 20 +----- 3 files changed, 23 insertions(+), 61 deletions(-) diff --git a/veles/secrets/gitbasicauth/codecatalyst/validator.go b/veles/secrets/gitbasicauth/codecatalyst/validator.go index 1927f2960..3a902a5a8 100644 --- a/veles/secrets/gitbasicauth/codecatalyst/validator.go +++ b/veles/secrets/gitbasicauth/codecatalyst/validator.go @@ -15,57 +15,33 @@ package codecatalyst import ( - "context" "fmt" "net/http" "net/url" "strings" - "github.com/google/osv-scalibr/veles" + "github.com/google/osv-scalibr/veles/secrets/common/simplevalidate" "github.com/google/osv-scalibr/veles/secrets/gitbasicauth" ) -// Validator validates CodeCatalyst credentials -type Validator struct { - cli *http.Client -} - -// SetHTTPClient sets the http.Client which the validator uses. -func (v *Validator) SetHTTPClient(cli *http.Client) { - v.cli = cli -} - // NewValidator creates a new Validator that validates CodeCatalyst credentials -func NewValidator() *Validator { - return &Validator{ - cli: http.DefaultClient, - } -} - -// Validate validates code AWS CodeCatalyst Git Basic Auth credentials. -func (v *Validator) Validate(ctx context.Context, secret Credentials) (veles.ValidationStatus, error) { - u, err := url.Parse(secret.FullURL) - if err != nil { - return veles.ValidationFailed, fmt.Errorf("error parsing URL: %w", err) +func NewValidator() *simplevalidate.Validator[Credentials] { + return &simplevalidate.Validator[Credentials]{ + EndpointFunc: func(c Credentials) (string, error) { + u, err := url.Parse(c.FullURL) + if err != nil { + return "", fmt.Errorf("error parsing URL: %w", err) + } + + // redundant host validation kept intentionally as a security measure in case any regression + // is introduced in the detector. + if !strings.HasSuffix(u.Host, ".codecatalyst.aws") { + return "", fmt.Errorf("not a valid AWS CodeCatalyst host %q", u.Host) + } + return gitbasicauth.Info(u).String(), nil + }, + HTTPMethod: http.MethodGet, + ValidResponseCodes: []int{http.StatusOK}, + InvalidResponseCodes: []int{http.StatusBadRequest}, } - - // redundant host validation kept intentionally as a security measure in case any regression - // is introduced in the detector. - if !strings.HasSuffix(u.Host, ".codecatalyst.aws") { - return veles.ValidationFailed, fmt.Errorf("not a valid AWS CodeCatalyst host %q", u.Host) - } - - status, err := gitbasicauth.Info(ctx, v.cli, u) - if err != nil { - return veles.ValidationFailed, fmt.Errorf("failed to reach Git info endpoint: %w", err) - } - - // Credentials successfully authenticated and repository info retrieved. - if status == http.StatusOK { - return veles.ValidationValid, nil - } - - // Returns credentials invalid for every other state as the CodeCatalyst server always - // responds with either 200 or 400 status codes - return veles.ValidationInvalid, nil } diff --git a/veles/secrets/gitbasicauth/codecatalyst/validator_test.go b/veles/secrets/gitbasicauth/codecatalyst/validator_test.go index 316266a59..fdc369593 100644 --- a/veles/secrets/gitbasicauth/codecatalyst/validator_test.go +++ b/veles/secrets/gitbasicauth/codecatalyst/validator_test.go @@ -127,7 +127,7 @@ func TestValidator(t *testing.T) { } v := codecatalyst.NewValidator() - v.SetHTTPClient(client) + v.HTTPC = client got, err := v.Validate(tt.ctx, codecatalyst.Credentials{FullURL: tt.url}) diff --git a/veles/secrets/gitbasicauth/gitbasicauth.go b/veles/secrets/gitbasicauth/gitbasicauth.go index ffa6cae81..4eff76f82 100644 --- a/veles/secrets/gitbasicauth/gitbasicauth.go +++ b/veles/secrets/gitbasicauth/gitbasicauth.go @@ -16,26 +16,12 @@ package gitbasicauth import ( - "context" - "fmt" - "net/http" "net/url" ) -// Info performs the info/refs request for Git upload-pack service. -// It returns the HTTP status code and an optional error. -func Info(ctx context.Context, cli *http.Client, repoURL *url.URL) (int, error) { +// Info returns the URL for the Git info/refs endpoint with service=git-upload-pack. +func Info(repoURL *url.URL) *url.URL { u := repoURL.JoinPath("info/refs") u.RawQuery = "service=git-upload-pack" - req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil) - if err != nil { - return 0, fmt.Errorf("error building request: %w", err) - } - resp, err := cli.Do(req) - if err != nil { - return 0, fmt.Errorf("error executing request: %w", err) - } - defer resp.Body.Close() - - return resp.StatusCode, nil + return u }