From 463872c35bb1086c2e22b5127ac7895dbaae3a68 Mon Sep 17 00:00:00 2001 From: Mike Cohen Date: Wed, 7 Sep 2022 09:30:44 +1000 Subject: [PATCH] Sync 0.6.6 branch to master (#2054) * [Snyk] Upgrade ace-builds from 1.9.3 to 1.9.5 (#2037) fix: upgrade ace-builds from 1.9.3 to 1.9.5 Snyk has created this PR to upgrade ace-builds from 1.9.3 to 1.9.5. See this package in npm: https://www.npmjs.com/package/ace-builds See this project in Snyk: https://app.snyk.io/org/scudette/project/76f4d127-566b-42ef-86f4-bdcbc92b90b4?utm_source=github&utm_medium=referral&page=upgrade-pr * Added Send to CyberChef context menu on table cells. (#2039) * Made context menus settable in the config file (#2040) Added more context targets: - VirusTotal - Google - CyberChef * Updated themes for context menu (#2041) Added "Clipboard" target * Added org_delete() function to remove orgs. (#2042) * Org manager maintains services lifetime (#2045) * Pass org ids in href parameters (#2047) Usually OrgId is passed in headers but we do have some href links so we need to also support passing the org id in query parameters. * collect each query's status separately (#2049) When dealing with multiple queries per collection it is important to keep stats on each query separately to get more accurate picture of what happened. For example one artifact may collect successfuly and another may fail. This change also fixes a bug where the execution duration was sometimes counted twice for queries that failed because they send an error as well as a completion message. * Split server sanity checks into root org and other orgs (#2052) The sanity checker ensured the server is running in a sane state. It also starts things like initial server artifacts etc. This PR split sanity checks to run on the root org (i.e. once when the server is started) and on each org. For example the initial server artifacts are only run on the root org and not on other orgs. Added org rm command * Fixed CSS for column selector ui (#2053) * Prepare for 0.6.6 release Co-authored-by: Snyk bot --- Makefile | 3 + accessors/file_store/fixtures/TestGlob.golden | 4 - accessors/file_store/fs.go | 77 - accessors/file_store/fs_test.go | 75 - acls/roles.go | 3 +- api/api.go | 4 +- api/assets.go | 1 + api/auth.go | 7 +- api/authenticators/orgs.go | 37 +- api/download.go | 100 +- api/proto/api.pb.gw.go | 28 +- api/proto/csv.pb.go | 55 +- api/proto/csv.proto | 4 + api/proto/users.pb.go | 679 ++++--- api/proto/users.proto | 9 +- api/proxy.go | 57 +- api/upload.go | 71 +- api/users.go | 2 +- artifacts/definitions/Demo/Plugins/GUI.yaml | 8 +- .../definitions/MacOS/Forensics/FSEvents.yaml | 94 + .../Server/Import/PreviousReleases.yaml | 3 +- .../Windows/Carving/CobaltStrike.yaml | 62 +- artifacts/definitions/Windows/NTFS/MFT.yaml | 50 +- .../testdata/files/fs_events_00000000007cff3d | Bin 0 -> 70 bytes .../testdata/server/testcases/cobalt.in.yaml | 3 +- .../testdata/server/testcases/cobalt.out.yaml | 4 +- .../testdata/server/testcases/macos.in.yaml | 3 + .../testdata/server/testcases/macos.out.yaml | 7 + .../testdata/server/testcases/orgs.in.yaml | 3 + .../testdata/server/testcases/orgs.out.yaml | 39 +- bin/config.go | 7 +- bin/frontend.go | 2 + bin/orgs.go | 43 + config/proto/config.pb.go | 1662 +++++++++-------- config/proto/config.proto | 23 +- constants/constants.go | 2 +- crypto/proto/jobs.pb.go | 293 +-- crypto/proto/jobs.proto | 3 + datastore/filebased.go | 10 +- datastore/memcache_file.go | 102 +- datastore/readonly.go | 4 +- datastore/remote.go | 4 +- docs/references/vql.yaml | 11 +- flows/artifacts.go | 25 +- flows/artifacts_test.go | 10 +- flows/collection_context.go | 87 + flows/proto/artifact_collector.pb.go | 377 ++-- flows/proto/artifact_collector.proto | 23 +- gui/velociraptor/package-lock.json | 65 +- gui/velociraptor/package.json | 5 +- gui/velociraptor/public/index.html | 1 + gui/velociraptor/src/App.js | 3 +- .../src/components/core/api-service.js | 23 +- .../src/components/core/keyboard-help.js | 4 +- .../src/components/core/paged-table.js | 13 +- gui/velociraptor/src/components/core/table.js | 16 +- .../src/components/events/timeline-viewer.js | 7 +- .../src/components/flows/flow-uploads.js | 9 +- .../src/components/flows/new-collection.js | 6 +- gui/velociraptor/src/components/forms/form.js | 1 + .../src/components/forms/forms.css | 24 + .../src/components/forms/upload.js | 2 +- .../src/components/sidebar/navigator.css | 5 + .../src/components/sidebar/navigator.js | 27 + .../src/components/users/user-label.js | 5 +- .../src/components/utils/context.css | 14 + .../src/components/utils/context.js | 144 ++ .../src/components/utils/value.js | 21 +- .../src/components/vfs/file-stats.js | 6 +- gui/velociraptor/src/css/_variables.css | 12 +- gui/velociraptor/src/css/index.css | 12 +- gui/velociraptor/src/themes/coolgray-dark.css | 24 +- .../src/themes/github-dimmed-dark.css | 41 +- gui/velociraptor/src/themes/pink-light.css | 17 +- gui/velociraptor/src/themes/veloci-dark.css | 25 +- gui/velociraptor/src/themes/veloci-light.css | 2 + gui/velociraptor/template.go | 18 +- gui/velociraptor/yarn.lock | 172 +- magefile.go | 10 + responder/responder.go | 12 + server/comms.go | 48 +- server/server_test.go | 6 +- services/frontend/frontend.go | 2 +- services/inventory/inventory.go | 24 +- services/launcher/flows.go | 20 +- services/launcher/launcher.go | 1 + services/notebook/notebook.go | 5 +- services/orgs.go | 5 + services/orgs/delete.go | 102 + services/orgs/orgs.go | 81 +- services/orgs/services.go | 180 +- services/orgs/tests.go | 3 +- services/sanity/sanity.go | 38 +- services/sanity/server_artifacts.go | 1 + services/server_artifacts/logger.go | 6 + services/spec.go | 6 +- services/users.go | 2 + services/users/delete.go | 50 + services/users/grpc.go | 3 +- services/users/links.go | 50 + services/users/users.go | 24 +- utils/orgs.go | 17 + vql/parsers/event_logs/watcher.go | 5 +- vql/readers/paged_reader_test.go | 7 +- vql/server/orgs/create.go | 5 + vql/server/orgs/delete.go | 78 + vql/server/users/delete.go | 29 +- vql/server/users/users.go | 3 +- 108 files changed, 3469 insertions(+), 2258 deletions(-) delete mode 100644 accessors/file_store/fixtures/TestGlob.golden delete mode 100644 accessors/file_store/fs.go delete mode 100644 accessors/file_store/fs_test.go create mode 100644 artifacts/definitions/MacOS/Forensics/FSEvents.yaml create mode 100644 artifacts/testdata/files/fs_events_00000000007cff3d create mode 100644 flows/collection_context.go create mode 100644 gui/velociraptor/src/components/forms/forms.css create mode 100644 gui/velociraptor/src/components/utils/context.css create mode 100644 gui/velociraptor/src/components/utils/context.js create mode 100644 services/orgs/delete.go create mode 100644 services/users/delete.go create mode 100644 services/users/links.go create mode 100644 vql/server/orgs/delete.go diff --git a/Makefile b/Makefile index 2cf65111bf..98d7ddbedc 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,9 @@ all: go run make.go -v autoDev +assets: + go run make.go -v assets + auto: go run make.go -v auto diff --git a/accessors/file_store/fixtures/TestGlob.golden b/accessors/file_store/fixtures/TestGlob.golden deleted file mode 100644 index 607ac8e3dc..0000000000 --- a/accessors/file_store/fixtures/TestGlob.golden +++ /dev/null @@ -1,4 +0,0 @@ -[ - "fs:/subdir", - "fs:/subdir/Foo.json" -] \ No newline at end of file diff --git a/accessors/file_store/fs.go b/accessors/file_store/fs.go deleted file mode 100644 index eac9f89933..0000000000 --- a/accessors/file_store/fs.go +++ /dev/null @@ -1,77 +0,0 @@ -package file_store - -import ( - "net/http" - "os" - "strings" - - config_proto "www.velocidex.com/golang/velociraptor/config/proto" - "www.velocidex.com/golang/velociraptor/file_store/api" - "www.velocidex.com/golang/velociraptor/file_store/path_specs" - "www.velocidex.com/golang/velociraptor/utils" -) - -type HTTPFileAdapter struct { - api.FileReader - file_store api.FileStore - - filename api.FSPathSpec -} - -func (self *HTTPFileAdapter) Stat() (os.FileInfo, error) { - stat, err := self.FileReader.Stat() - return stat, err -} - -func (self HTTPFileAdapter) Readdir(count int) ([]os.FileInfo, error) { - children, err := self.file_store.ListDirectory(self.filename) - if err != nil { - return nil, err - } - result := make([]os.FileInfo, 0, len(children)) - for _, i := range children { - result = append(result, i) - } - - return result, nil -} - -// Implementation of http.FileSystem -type FileSystem struct { - config_obj *config_proto.Config - file_store api.FileStore - - // The required prefix of the filesystem. - prefix string -} - -func (self FileSystem) Open(path string) (http.File, error) { - if !strings.HasPrefix(path, self.prefix) { - return nil, os.ErrNotExist - } - - components := path_specs.NewUnsafeFilestorePath( - utils.SplitComponents(path)...). - SetType(api.PATH_TYPE_FILESTORE_ANY) - fd, err := self.file_store.ReadFile(components) - if err != nil { - return nil, os.ErrNotExist - } - - return &HTTPFileAdapter{ - FileReader: fd, - file_store: self.file_store, - filename: components, - }, nil -} - -func NewFileSystem( - config_obj *config_proto.Config, - file_store api.FileStore, - prefix string) *FileSystem { - return &FileSystem{ - config_obj: config_obj, - file_store: file_store, - prefix: prefix, - } -} diff --git a/accessors/file_store/fs_test.go b/accessors/file_store/fs_test.go deleted file mode 100644 index e3773389b2..0000000000 --- a/accessors/file_store/fs_test.go +++ /dev/null @@ -1,75 +0,0 @@ -package file_store_test - -import ( - "io/ioutil" - "testing" - - "github.com/sebdah/goldie" - "github.com/stretchr/testify/suite" - "www.velocidex.com/golang/velociraptor/file_store/api" - "www.velocidex.com/golang/velociraptor/file_store/path_specs" - "www.velocidex.com/golang/velociraptor/file_store/test_utils" - "www.velocidex.com/golang/velociraptor/glob" - "www.velocidex.com/golang/velociraptor/json" - "www.velocidex.com/golang/velociraptor/vtesting/assert" - - _ "www.velocidex.com/golang/velociraptor/accessors/file_store" - file_store_accessor "www.velocidex.com/golang/velociraptor/accessors/file_store" - file_store_api "www.velocidex.com/golang/velociraptor/file_store" - _ "www.velocidex.com/golang/velociraptor/result_sets/timed" - vql_subsystem "www.velocidex.com/golang/velociraptor/vql" -) - -type FileStoreAccessorTestSuite struct { - test_utils.TestSuite -} - -func (self *FileStoreAccessorTestSuite) createFilestoreContents() { - file_store_factory := file_store_api.GetFileStore(self.ConfigObj) - path_spec := path_specs.NewSafeFilestorePath("subdir", "Foo"). - SetType(api.PATH_TYPE_FILESTORE_JSON) - fd, err := file_store_factory.WriteFile(path_spec) - assert.NoError(self.T(), err) - fd.Write([]byte("hello world")) - fd.Close() -} - -func (self *FileStoreAccessorTestSuite) TestGlob() { - self.createFilestoreContents() - - fs_accessor := file_store_accessor.NewFileStoreFileSystemAccessor(self.ConfigObj) - - globber := glob.NewGlobber() - - glob_expr, err := fs_accessor.ParsePath("/**") - assert.NoError(self.T(), err) - - root_path, err := fs_accessor.ParsePath("fs:/") - assert.NoError(self.T(), err) - - err = globber.Add(glob_expr) - assert.NoError(self.T(), err) - var returned []string - - scope := vql_subsystem.MakeScope() - output_chan := globber.ExpandWithContext( - self.Ctx, scope, self.ConfigObj, - root_path, fs_accessor) - for row := range output_chan { - returned = append(returned, row.FullPath()) - if !row.IsDir() { - fd, err := fs_accessor.OpenWithOSPath(row.OSPath()) - assert.NoError(self.T(), err) - data, err := ioutil.ReadAll(fd) - assert.NoError(self.T(), err) - assert.Equal(self.T(), "hello world", string(data)) - } - } - - assert.Equal(self.T(), 2, len(returned)) - goldie.Assert(self.T(), "TestGlob", json.MustMarshalIndent(returned)) -} - -func TestFileStoreAccessor(t *testing.T) { - suite.Run(t, &FileStoreAccessorTestSuite{}) -} diff --git a/acls/roles.go b/acls/roles.go index 199d1052b5..4af5f08840 100644 --- a/acls/roles.go +++ b/acls/roles.go @@ -6,6 +6,7 @@ import ( acl_proto "www.velocidex.com/golang/velociraptor/acls/proto" config_proto "www.velocidex.com/golang/velociraptor/config/proto" + "www.velocidex.com/golang/velociraptor/utils" ) func ValidateRole(role string) bool { @@ -97,7 +98,7 @@ func GetRolePermissions( // An administrator for the root org is allowed to // manipulate orgs. - if config_obj != nil && config_obj.OrgId == "" { + if config_obj != nil && utils.IsRootOrg(config_obj.OrgId) { result.OrgAdmin = true } diff --git a/api/api.go b/api/api.go index f0651f43fb..5b3a9810bd 100644 --- a/api/api.go +++ b/api/api.go @@ -56,6 +56,7 @@ import ( "www.velocidex.com/golang/velociraptor/paths" "www.velocidex.com/golang/velociraptor/server" "www.velocidex.com/golang/velociraptor/services" + "www.velocidex.com/golang/velociraptor/utils" vql_subsystem "www.velocidex.com/golang/velociraptor/vql" "www.velocidex.com/golang/velociraptor/vql/acl_managers" "www.velocidex.com/golang/vfilter" @@ -433,7 +434,7 @@ func (self *ApiServer) GetUserUITraits( result.Orgs = user_info.Orgs for _, item := range result.Orgs { - if item.Id == "" { + if utils.IsRootOrg(item.Id) { item.Name = "" item.Id = "root" } @@ -449,6 +450,7 @@ func (self *ApiServer) GetUserUITraits( result.InterfaceTraits.DefaultPassword = user_options.DefaultPassword result.InterfaceTraits.DefaultDownloadsLock = user_options.DefaultDownloadsLock result.InterfaceTraits.Customizations = user_options.Customizations + result.InterfaceTraits.Links = user_options.Links } return result, nil diff --git a/api/assets.go b/api/assets.go index d440d35d91..3a16c4619c 100644 --- a/api/assets.go +++ b/api/assets.go @@ -89,6 +89,7 @@ func GetTemplateHandler( BasePath: base, Heading: "Heading", UserTheme: user_options.Theme, + OrgId: user_options.Org, } err = tmpl.Execute(w, args) if err != nil { diff --git a/api/auth.go b/api/auth.go index 455dea5811..19c4342197 100644 --- a/api/auth.go +++ b/api/auth.go @@ -30,12 +30,7 @@ func NewDefaultUserObject(config_obj *config_proto.Config) *api_proto.ApiUser { if config_obj.GUI != nil { result.InterfaceTraits = &api_proto.ApiUserInterfaceTraits{ - Links: []*api_proto.UILink{}, - } - - for _, link := range config_obj.GUI.Links { - result.InterfaceTraits.Links = append(result.InterfaceTraits.Links, - &api_proto.UILink{Text: link.Text, Url: link.Url}) + Links: config_obj.GUI.Links, } } diff --git a/api/authenticators/orgs.go b/api/authenticators/orgs.go index 78fcedc5e7..fe9b468885 100644 --- a/api/authenticators/orgs.go +++ b/api/authenticators/orgs.go @@ -3,23 +3,44 @@ package authenticators import ( "errors" "net/http" + "net/url" "www.velocidex.com/golang/velociraptor/acls" api_proto "www.velocidex.com/golang/velociraptor/api/proto" "www.velocidex.com/golang/velociraptor/services" ) -func CheckOrgAccess(r *http.Request, user_record *api_proto.VelociraptorUser) error { +func GetOrgIdFromRequest(r *http.Request) string { + // Now we have to determine which org the user wants to use. First + // let's check if the user specified an org in the header. + org_id := r.Header.Get("Grpc-Metadata-Orgid") + if org_id != "" { + return org_id + } - // Now we have to determine which org the user wants to - // use. First let's check if the user specified an org in the - // header. - org_id := "root" - current_orgid_array := r.Header.Get("Grpc-Metadata-Orgid") - if len(current_orgid_array) == 1 { - org_id = string(current_orgid_array[0]) + // Maybe the org id is specified in the URL itself. We allow + // the org id to be specified as a query string in order to + // support plain href links. However ultimately the GRPC + // gateway needs to check the org id in a header - so if an + // org is specified using a query string and NOT specified + // using a header, we set the header from it for further + // checks by the GRPC layer (in services/users/grpc.go) + q, err := url.ParseQuery(r.URL.RawQuery) + if err == nil { + org_id = q.Get("org_id") + if org_id != "" { + r.Header.Set("Grpc-Metadata-Orgid", org_id) + return org_id + } } + org_id = "root" + r.Header.Set("Grpc-Metadata-Orgid", org_id) + return org_id +} + +func CheckOrgAccess(r *http.Request, user_record *api_proto.VelociraptorUser) error { + org_id := GetOrgIdFromRequest(r) err := _checkOrgAccess(r, org_id, user_record) if err == nil { return nil diff --git a/api/download.go b/api/download.go index 577ca120aa..880aff10aa 100644 --- a/api/download.go +++ b/api/download.go @@ -42,6 +42,7 @@ import ( "github.com/sirupsen/logrus" context "golang.org/x/net/context" actions_proto "www.velocidex.com/golang/velociraptor/actions/proto" + "www.velocidex.com/golang/velociraptor/api/authenticators" api_proto "www.velocidex.com/golang/velociraptor/api/proto" config_proto "www.velocidex.com/golang/velociraptor/config/proto" "www.velocidex.com/golang/velociraptor/datastore" @@ -81,14 +82,14 @@ type vfsFileDownloadRequest struct { Offset int64 `schema:"offset"` Length int `schema:"length"` Encoding string `schema:"encoding"` + OrgId string `schema:"org_id"` } // URL format: /api/v1/DownloadVFSFile // This URL allows the caller to download **any** member of the // filestore (providing they have at least read permissions). -func vfsFileDownloadHandler( - config_obj *config_proto.Config) http.Handler { +func vfsFileDownloadHandler() http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { request := vfsFileDownloadRequest{} decoder := schema.NewDecoder() @@ -98,6 +99,22 @@ func vfsFileDownloadHandler( return } + org_id := request.OrgId + if org_id == "" { + org_id = authenticators.GetOrgIdFromRequest(r) + } + org_manager, err := services.GetOrgManager() + if err != nil { + returnError(w, 404, err.Error()) + return + } + + org_config_obj, err := org_manager.GetOrgConfig(org_id) + if err != nil { + returnError(w, 404, err.Error()) + return + } + var path_spec api.FSPathSpec client_path_manager := paths.NewClientPathManager(request.ClientId) @@ -111,7 +128,7 @@ func vfsFileDownloadHandler( } } else { - db, err := datastore.GetDB(config_obj) + db, err := datastore.GetDB(org_config_obj) if err != nil { returnError(w, 404, err.Error()) return @@ -121,7 +138,7 @@ func vfsFileDownloadHandler( request.Components) download_info := &flows_proto.VFSDownloadInfo{} - err = db.GetSubject(config_obj, info_path_spec, download_info) + err = db.GetSubject(org_config_obj, info_path_spec, download_info) if err != nil { returnError(w, 404, err.Error()) return @@ -132,7 +149,7 @@ func vfsFileDownloadHandler( } - file, err := file_store.GetFileStore(config_obj).ReadFile(path_spec) + file, err := file_store.GetFileStore(org_config_obj).ReadFile(path_spec) if err != nil { returnError(w, 404, err.Error()) return @@ -146,7 +163,7 @@ func vfsFileDownloadHandler( var reader_at io.ReaderAt = &utils.ReaderAtter{Reader: file} - index, err := getIndex(config_obj, path_spec) + index, err := getIndex(org_config_obj, path_spec) // If the file is sparse, we use the sparse reader. if err == nil && len(index.Ranges) > 0 { @@ -269,8 +286,53 @@ func getTransformer( return func(row *ordereddict.Dict) *ordereddict.Dict { return row } } +func downloadFileStore(prefix []string) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + path_spec := paths.FSPathSpecFromClientPath(r.URL.Path) + components := path_spec.Components() + + // make sure the prefix is correct + for i, p := range prefix { + if len(components) <= i || p != components[i] { + returnError(w, 404, "Not Found") + return + } + } + + org_id := authenticators.GetOrgIdFromRequest(r) + org_manager, err := services.GetOrgManager() + if err != nil { + returnError(w, 404, err.Error()) + return + } + + org_config_obj, err := org_manager.GetOrgConfig(org_id) + if err != nil { + returnError(w, 404, err.Error()) + return + } + + file_store_factory := file_store.GetFileStore(org_config_obj) + fd, err := file_store_factory.ReadFile(path_spec) + if err != nil { + returnError(w, 404, err.Error()) + return + } + + // From here on we already sent the headers and we can + // not really report an error to the client. + w.Header().Set("Content-Disposition", "attachment; filename="+ + url.PathEscape(path_spec.Base())+api.GetExtensionForFilestore(path_spec)) + + w.Header().Set("Content-Type", "binary/octet-stream") + w.WriteHeader(200) + + utils.Copy(r.Context(), w, fd) + }) +} + // Download the table as specified by the v1/GetTable API. -func downloadTable(config_obj *config_proto.Config) http.Handler { +func downloadTable() http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { request := &api_proto.GetTableRequest{} decoder := schema.NewDecoder() @@ -281,15 +343,27 @@ func downloadTable(config_obj *config_proto.Config) http.Handler { return } + org_manager, err := services.GetOrgManager() + if err != nil { + returnError(w, 404, err.Error()) + return + } + + org_config_obj, err := org_manager.GetOrgConfig(request.OrgId) + if err != nil { + returnError(w, 404, err.Error()) + return + } + row_chan, closer, log_path, err := getRows( - r.Context(), config_obj, request) + r.Context(), org_config_obj, request) if err != nil { returnError(w, 400, "Invalid request") return } defer closer() - transform := getTransformer(r.Context(), config_obj, request) + transform := getTransformer(r.Context(), org_config_obj, request) download_name := request.DownloadFilename if download_name == "" { @@ -297,7 +371,7 @@ func downloadTable(config_obj *config_proto.Config) http.Handler { } // Log an audit event. - userinfo := GetUserInfo(r.Context(), config_obj) + userinfo := GetUserInfo(r.Context(), org_config_obj) // This should never happen! if userinfo.Name == "" { @@ -317,7 +391,7 @@ func downloadTable(config_obj *config_proto.Config) http.Handler { w.Header().Set("Content-Type", "binary/octet-stream") w.WriteHeader(200) - logger := logging.GetLogger(config_obj, &logging.Audit) + logger := logging.GetLogger(org_config_obj, &logging.Audit) logger.WithFields(logrus.Fields{ "user": userinfo.Name, "request": request, @@ -326,7 +400,7 @@ func downloadTable(config_obj *config_proto.Config) http.Handler { scope := vql_subsystem.MakeScope() csv_writer := csv.GetCSVAppender( - config_obj, scope, w, true /* write_headers */) + org_config_obj, scope, w, true /* write_headers */) for row := range row_chan { csv_writer.Write( filterColumns(request.Columns, transform(row))) @@ -346,7 +420,7 @@ func downloadTable(config_obj *config_proto.Config) http.Handler { w.Header().Set("Content-Type", "binary/octet-stream") w.WriteHeader(200) - logger := logging.GetLogger(config_obj, &logging.Audit) + logger := logging.GetLogger(org_config_obj, &logging.Audit) logger.WithFields(logrus.Fields{ "user": userinfo.Name, "request": request, diff --git a/api/proto/api.pb.gw.go b/api/proto/api.pb.gw.go index b8db0f2d01..c8c42f1043 100644 --- a/api/proto/api.pb.gw.go +++ b/api/proto/api.pb.gw.go @@ -22,8 +22,8 @@ import ( "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" "google.golang.org/protobuf/proto" - proto_2 "www.velocidex.com/golang/velociraptor/artifacts/proto" - proto_1 "www.velocidex.com/golang/velociraptor/flows/proto" + proto_3 "www.velocidex.com/golang/velociraptor/artifacts/proto" + proto_4 "www.velocidex.com/golang/velociraptor/flows/proto" ) // Suppress "imported and not used" errors @@ -1051,7 +1051,7 @@ func local_request_API_GetTable_0(ctx context.Context, marshaler runtime.Marshal } func request_API_CollectArtifact_0(ctx context.Context, marshaler runtime.Marshaler, client APIClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq proto_1.ArtifactCollectorArgs + var protoReq proto_4.ArtifactCollectorArgs var metadata runtime.ServerMetadata newReader, berr := utilities.IOReaderFactory(req.Body) @@ -1068,7 +1068,7 @@ func request_API_CollectArtifact_0(ctx context.Context, marshaler runtime.Marsha } func local_request_API_CollectArtifact_0(ctx context.Context, marshaler runtime.Marshaler, server APIServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq proto_1.ArtifactCollectorArgs + var protoReq proto_4.ArtifactCollectorArgs var metadata runtime.ServerMetadata newReader, berr := utilities.IOReaderFactory(req.Body) @@ -1351,7 +1351,7 @@ var ( ) func request_API_GetToolInfo_0(ctx context.Context, marshaler runtime.Marshaler, client APIClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq proto_2.Tool + var protoReq proto_3.Tool var metadata runtime.ServerMetadata if err := req.ParseForm(); err != nil { @@ -1367,7 +1367,7 @@ func request_API_GetToolInfo_0(ctx context.Context, marshaler runtime.Marshaler, } func local_request_API_GetToolInfo_0(ctx context.Context, marshaler runtime.Marshaler, server APIServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq proto_2.Tool + var protoReq proto_3.Tool var metadata runtime.ServerMetadata if err := req.ParseForm(); err != nil { @@ -1383,7 +1383,7 @@ func local_request_API_GetToolInfo_0(ctx context.Context, marshaler runtime.Mars } func request_API_SetToolInfo_0(ctx context.Context, marshaler runtime.Marshaler, client APIClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq proto_2.Tool + var protoReq proto_3.Tool var metadata runtime.ServerMetadata newReader, berr := utilities.IOReaderFactory(req.Body) @@ -1400,7 +1400,7 @@ func request_API_SetToolInfo_0(ctx context.Context, marshaler runtime.Marshaler, } func local_request_API_SetToolInfo_0(ctx context.Context, marshaler runtime.Marshaler, server APIServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq proto_2.Tool + var protoReq proto_3.Tool var metadata runtime.ServerMetadata newReader, berr := utilities.IOReaderFactory(req.Body) @@ -1469,7 +1469,7 @@ func local_request_API_GetServerMonitoringState_0(ctx context.Context, marshaler } func request_API_SetServerMonitoringState_0(ctx context.Context, marshaler runtime.Marshaler, client APIClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq proto_1.ArtifactCollectorArgs + var protoReq proto_4.ArtifactCollectorArgs var metadata runtime.ServerMetadata newReader, berr := utilities.IOReaderFactory(req.Body) @@ -1486,7 +1486,7 @@ func request_API_SetServerMonitoringState_0(ctx context.Context, marshaler runti } func local_request_API_SetServerMonitoringState_0(ctx context.Context, marshaler runtime.Marshaler, server APIServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq proto_1.ArtifactCollectorArgs + var protoReq proto_4.ArtifactCollectorArgs var metadata runtime.ServerMetadata newReader, berr := utilities.IOReaderFactory(req.Body) @@ -1507,7 +1507,7 @@ var ( ) func request_API_GetClientMonitoringState_0(ctx context.Context, marshaler runtime.Marshaler, client APIClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq proto_1.GetClientMonitoringStateRequest + var protoReq proto_4.GetClientMonitoringStateRequest var metadata runtime.ServerMetadata if err := req.ParseForm(); err != nil { @@ -1523,7 +1523,7 @@ func request_API_GetClientMonitoringState_0(ctx context.Context, marshaler runti } func local_request_API_GetClientMonitoringState_0(ctx context.Context, marshaler runtime.Marshaler, server APIServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq proto_1.GetClientMonitoringStateRequest + var protoReq proto_4.GetClientMonitoringStateRequest var metadata runtime.ServerMetadata if err := req.ParseForm(); err != nil { @@ -1539,7 +1539,7 @@ func local_request_API_GetClientMonitoringState_0(ctx context.Context, marshaler } func request_API_SetClientMonitoringState_0(ctx context.Context, marshaler runtime.Marshaler, client APIClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq proto_1.ClientEventTable + var protoReq proto_4.ClientEventTable var metadata runtime.ServerMetadata newReader, berr := utilities.IOReaderFactory(req.Body) @@ -1556,7 +1556,7 @@ func request_API_SetClientMonitoringState_0(ctx context.Context, marshaler runti } func local_request_API_SetClientMonitoringState_0(ctx context.Context, marshaler runtime.Marshaler, server APIServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq proto_1.ClientEventTable + var protoReq proto_4.ClientEventTable var metadata runtime.ServerMetadata newReader, berr := utilities.IOReaderFactory(req.Body) diff --git a/api/proto/csv.pb.go b/api/proto/csv.pb.go index 8de661a4bc..0126dd9c94 100644 --- a/api/proto/csv.pb.go +++ b/api/proto/csv.pb.go @@ -64,6 +64,9 @@ type GetTableRequest struct { SortDirection bool `protobuf:"varint,20,opt,name=sort_direction,json=sortDirection,proto3" json:"sort_direction,omitempty"` FilterColumn string `protobuf:"bytes,21,opt,name=filter_column,json=filterColumn,proto3" json:"filter_column,omitempty"` FilterRegex string `protobuf:"bytes,22,opt,name=filter_regex,json=filterRegex,proto3" json:"filter_regex,omitempty"` + // The org id may be specified in the query string - The protobuf + // is normally parsed from the query string directly. + OrgId string `protobuf:"bytes,23,opt,name=org_id,json=orgId,proto3" json:"org_id,omitempty"` } func (x *GetTableRequest) Reset() { @@ -245,6 +248,13 @@ func (x *GetTableRequest) GetFilterRegex() string { return "" } +func (x *GetTableRequest) GetOrgId() string { + if x != nil { + return x.OrgId + } + return "" +} + type Row struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -386,7 +396,7 @@ var file_csv_proto_rawDesc = []byte{ 0x74, 0x6f, 0x1a, 0x14, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x65, 0x6d, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, - 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x95, 0x05, 0x0a, 0x0f, 0x47, 0x65, 0x74, + 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xac, 0x05, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x72, 0x6f, 0x77, 0x18, 0x03, 0x20, @@ -428,27 +438,28 @@ var file_csv_proto_rawDesc = []byte{ 0x0c, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x16, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x65, 0x67, 0x65, 0x78, - 0x22, 0x19, 0x0a, 0x03, 0x52, 0x6f, 0x77, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x22, 0xf0, 0x01, 0x0a, 0x10, - 0x47, 0x65, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x2d, 0x0a, 0x07, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x09, 0x42, 0x13, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x0d, 0x12, 0x0b, 0x54, 0x68, 0x65, 0x20, 0x63, - 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x52, 0x07, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x12, - 0x1e, 0x0a, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x12, - 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x52, 0x6f, 0x77, 0x73, 0x12, 0x34, - 0x0a, 0x0c, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x04, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6c, - 0x75, 0x6d, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, - 0x79, 0x70, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, - 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, - 0x69, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x42, 0x31, - 0x5a, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x64, 0x65, 0x78, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x76, 0x65, 0x6c, 0x6f, 0x63, - 0x69, 0x72, 0x61, 0x70, 0x74, 0x6f, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x17, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x6f, 0x72, 0x67, 0x49, 0x64, 0x22, 0x19, 0x0a, 0x03, 0x52, 0x6f, 0x77, 0x12, 0x12, + 0x0a, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x63, 0x65, + 0x6c, 0x6c, 0x22, 0xf0, 0x01, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x07, 0x63, 0x6f, 0x6c, 0x75, 0x6d, + 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x42, 0x13, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x0d, + 0x12, 0x0b, 0x54, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x52, 0x07, 0x63, + 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x12, 0x1e, 0x0a, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x6f, 0x77, + 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, + 0x72, 0x6f, 0x77, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x6f, 0x74, 0x61, + 0x6c, 0x52, 0x6f, 0x77, 0x73, 0x12, 0x34, 0x0a, 0x0c, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, + 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x73, + 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x65, 0x6e, + 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x65, 0x6e, + 0x64, 0x54, 0x69, 0x6d, 0x65, 0x42, 0x31, 0x5a, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x6c, + 0x6f, 0x63, 0x69, 0x64, 0x65, 0x78, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, + 0x67, 0x2f, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x72, 0x61, 0x70, 0x74, 0x6f, 0x72, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/proto/csv.proto b/api/proto/csv.proto index d8874a333e..72eb858c8f 100644 --- a/api/proto/csv.proto +++ b/api/proto/csv.proto @@ -58,6 +58,10 @@ message GetTableRequest { bool sort_direction = 20; string filter_column = 21; string filter_regex = 22; + + // The org id may be specified in the query string - The protobuf + // is normally parsed from the query string directly. + string org_id = 23; } message Row { diff --git a/api/proto/users.pb.go b/api/proto/users.pb.go index a4191cf6c9..ab93e3c79e 100644 --- a/api/proto/users.pb.go +++ b/api/proto/users.pb.go @@ -12,7 +12,8 @@ import ( reflect "reflect" sync "sync" proto "www.velocidex.com/golang/velociraptor/acls/proto" - proto1 "www.velocidex.com/golang/velociraptor/flows/proto" + proto1 "www.velocidex.com/golang/velociraptor/config/proto" + proto2 "www.velocidex.com/golang/velociraptor/flows/proto" _ "www.velocidex.com/golang/velociraptor/proto" ) @@ -69,7 +70,7 @@ func (x ApiUser_UserType) Number() protoreflect.EnumNumber { // Deprecated: Use ApiUser_UserType.Descriptor instead. func (ApiUser_UserType) EnumDescriptor() ([]byte, []int) { - return file_users_proto_rawDescGZIP(), []int{4, 0} + return file_users_proto_rawDescGZIP(), []int{3, 0} } type UserNotification_Type int32 @@ -160,7 +161,7 @@ func (x UserNotification_Type) Number() protoreflect.EnumNumber { // Deprecated: Use UserNotification_Type.Descriptor instead. func (UserNotification_Type) EnumDescriptor() ([]byte, []int) { - return file_users_proto_rawDescGZIP(), []int{6, 0} + return file_users_proto_rawDescGZIP(), []int{5, 0} } type UserNotification_State int32 @@ -209,7 +210,7 @@ func (x UserNotification_State) Number() protoreflect.EnumNumber { // Deprecated: Use UserNotification_State.Descriptor instead. func (UserNotification_State) EnumDescriptor() ([]byte, []int) { - return file_users_proto_rawDescGZIP(), []int{6, 1} + return file_users_proto_rawDescGZIP(), []int{5, 1} } type Org struct { @@ -397,61 +398,6 @@ func (x *VelociraptorUser) GetCurrentOrg() string { return "" } -type UILink struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Text string `protobuf:"bytes,1,opt,name=text,proto3" json:"text,omitempty"` - Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"` -} - -func (x *UILink) Reset() { - *x = UILink{} - if protoimpl.UnsafeEnabled { - mi := &file_users_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *UILink) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UILink) ProtoMessage() {} - -func (x *UILink) ProtoReflect() protoreflect.Message { - mi := &file_users_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UILink.ProtoReflect.Descriptor instead. -func (*UILink) Descriptor() ([]byte, []int) { - return file_users_proto_rawDescGZIP(), []int{2} -} - -func (x *UILink) GetText() string { - if x != nil { - return x.Text - } - return "" -} - -func (x *UILink) GetUrl() string { - if x != nil { - return x.Url - } - return "" -} - // These traits are used to control the GUI App. Many of these fields // are constructed from the VelociraptorUser, the config file, the // GUIOptions etc. @@ -465,9 +411,9 @@ type ApiUserInterfaceTraits struct { Lang string `protobuf:"bytes,22,opt,name=lang,proto3" json:"lang,omitempty"` // Set if the authenticator is password less (e.g. OAuth, SAML // etc) - PasswordLess bool `protobuf:"varint,25,opt,name=password_less,json=passwordLess,proto3" json:"password_less,omitempty"` - Picture string `protobuf:"bytes,20,opt,name=picture,proto3" json:"picture,omitempty"` - Links []*UILink `protobuf:"bytes,21,rep,name=links,proto3" json:"links,omitempty"` + PasswordLess bool `protobuf:"varint,25,opt,name=password_less,json=passwordLess,proto3" json:"password_less,omitempty"` + Picture string `protobuf:"bytes,20,opt,name=picture,proto3" json:"picture,omitempty"` + Links []*proto1.GUILink `protobuf:"bytes,21,rep,name=links,proto3" json:"links,omitempty"` // Get the user's preferred theme. Theme string `protobuf:"bytes,2,opt,name=theme,proto3" json:"theme,omitempty"` Timezone string `protobuf:"bytes,23,opt,name=timezone,proto3" json:"timezone,omitempty"` @@ -485,7 +431,7 @@ type ApiUserInterfaceTraits struct { func (x *ApiUserInterfaceTraits) Reset() { *x = ApiUserInterfaceTraits{} if protoimpl.UnsafeEnabled { - mi := &file_users_proto_msgTypes[3] + mi := &file_users_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -498,7 +444,7 @@ func (x *ApiUserInterfaceTraits) String() string { func (*ApiUserInterfaceTraits) ProtoMessage() {} func (x *ApiUserInterfaceTraits) ProtoReflect() protoreflect.Message { - mi := &file_users_proto_msgTypes[3] + mi := &file_users_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -511,7 +457,7 @@ func (x *ApiUserInterfaceTraits) ProtoReflect() protoreflect.Message { // Deprecated: Use ApiUserInterfaceTraits.ProtoReflect.Descriptor instead. func (*ApiUserInterfaceTraits) Descriptor() ([]byte, []int) { - return file_users_proto_rawDescGZIP(), []int{3} + return file_users_proto_rawDescGZIP(), []int{2} } func (x *ApiUserInterfaceTraits) GetPermissions() *proto.ApiClientACL { @@ -549,7 +495,7 @@ func (x *ApiUserInterfaceTraits) GetPicture() string { return "" } -func (x *ApiUserInterfaceTraits) GetLinks() []*UILink { +func (x *ApiUserInterfaceTraits) GetLinks() []*proto1.GUILink { if x != nil { return x.Links } @@ -621,7 +567,7 @@ type ApiUser struct { func (x *ApiUser) Reset() { *x = ApiUser{} if protoimpl.UnsafeEnabled { - mi := &file_users_proto_msgTypes[4] + mi := &file_users_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -634,7 +580,7 @@ func (x *ApiUser) String() string { func (*ApiUser) ProtoMessage() {} func (x *ApiUser) ProtoReflect() protoreflect.Message { - mi := &file_users_proto_msgTypes[4] + mi := &file_users_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -647,7 +593,7 @@ func (x *ApiUser) ProtoReflect() protoreflect.Message { // Deprecated: Use ApiUser.ProtoReflect.Descriptor instead. func (*ApiUser) Descriptor() ([]byte, []int) { - return file_users_proto_rawDescGZIP(), []int{4} + return file_users_proto_rawDescGZIP(), []int{3} } func (x *ApiUser) GetUsername() string { @@ -689,7 +635,7 @@ type UserNotificationCount struct { func (x *UserNotificationCount) Reset() { *x = UserNotificationCount{} if protoimpl.UnsafeEnabled { - mi := &file_users_proto_msgTypes[5] + mi := &file_users_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -702,7 +648,7 @@ func (x *UserNotificationCount) String() string { func (*UserNotificationCount) ProtoMessage() {} func (x *UserNotificationCount) ProtoReflect() protoreflect.Message { - mi := &file_users_proto_msgTypes[5] + mi := &file_users_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -715,7 +661,7 @@ func (x *UserNotificationCount) ProtoReflect() protoreflect.Message { // Deprecated: Use UserNotificationCount.ProtoReflect.Descriptor instead. func (*UserNotificationCount) Descriptor() ([]byte, []int) { - return file_users_proto_rawDescGZIP(), []int{5} + return file_users_proto_rawDescGZIP(), []int{4} } func (x *UserNotificationCount) GetCount() uint64 { @@ -740,7 +686,7 @@ type UserNotification struct { func (x *UserNotification) Reset() { *x = UserNotification{} if protoimpl.UnsafeEnabled { - mi := &file_users_proto_msgTypes[6] + mi := &file_users_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -753,7 +699,7 @@ func (x *UserNotification) String() string { func (*UserNotification) ProtoMessage() {} func (x *UserNotification) ProtoReflect() protoreflect.Message { - mi := &file_users_proto_msgTypes[6] + mi := &file_users_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -766,7 +712,7 @@ func (x *UserNotification) ProtoReflect() protoreflect.Message { // Deprecated: Use UserNotification.ProtoReflect.Descriptor instead. func (*UserNotification) Descriptor() ([]byte, []int) { - return file_users_proto_rawDescGZIP(), []int{6} + return file_users_proto_rawDescGZIP(), []int{5} } func (x *UserNotification) GetUsername() string { @@ -815,7 +761,7 @@ type GetUserNotificationsResponse struct { func (x *GetUserNotificationsResponse) Reset() { *x = GetUserNotificationsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_users_proto_msgTypes[7] + mi := &file_users_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -828,7 +774,7 @@ func (x *GetUserNotificationsResponse) String() string { func (*GetUserNotificationsResponse) ProtoMessage() {} func (x *GetUserNotificationsResponse) ProtoReflect() protoreflect.Message { - mi := &file_users_proto_msgTypes[7] + mi := &file_users_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -841,7 +787,7 @@ func (x *GetUserNotificationsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetUserNotificationsResponse.ProtoReflect.Descriptor instead. func (*GetUserNotificationsResponse) Descriptor() ([]byte, []int) { - return file_users_proto_rawDescGZIP(), []int{7} + return file_users_proto_rawDescGZIP(), []int{6} } func (x *GetUserNotificationsResponse) GetItems() []*UserNotification { @@ -862,7 +808,7 @@ type GetUserNotificationsRequest struct { func (x *GetUserNotificationsRequest) Reset() { *x = GetUserNotificationsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_users_proto_msgTypes[8] + mi := &file_users_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -875,7 +821,7 @@ func (x *GetUserNotificationsRequest) String() string { func (*GetUserNotificationsRequest) ProtoMessage() {} func (x *GetUserNotificationsRequest) ProtoReflect() protoreflect.Message { - mi := &file_users_proto_msgTypes[8] + mi := &file_users_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -888,7 +834,7 @@ func (x *GetUserNotificationsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetUserNotificationsRequest.ProtoReflect.Descriptor instead. func (*GetUserNotificationsRequest) Descriptor() ([]byte, []int) { - return file_users_proto_rawDescGZIP(), []int{8} + return file_users_proto_rawDescGZIP(), []int{7} } func (x *GetUserNotificationsRequest) GetClearPending() bool { @@ -910,7 +856,7 @@ type GUICustomizations struct { func (x *GUICustomizations) Reset() { *x = GUICustomizations{} if protoimpl.UnsafeEnabled { - mi := &file_users_proto_msgTypes[9] + mi := &file_users_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -923,7 +869,7 @@ func (x *GUICustomizations) String() string { func (*GUICustomizations) ProtoMessage() {} func (x *GUICustomizations) ProtoReflect() protoreflect.Message { - mi := &file_users_proto_msgTypes[9] + mi := &file_users_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -936,7 +882,7 @@ func (x *GUICustomizations) ProtoReflect() protoreflect.Message { // Deprecated: Use GUICustomizations.ProtoReflect.Descriptor instead. func (*GUICustomizations) Descriptor() ([]byte, []int) { - return file_users_proto_rawDescGZIP(), []int{9} + return file_users_proto_rawDescGZIP(), []int{8} } func (x *GUICustomizations) GetDisableServerEvents() bool { @@ -962,12 +908,13 @@ type SetGUIOptionsRequest struct { // Current org id Org string `protobuf:"bytes,7,opt,name=org,proto3" json:"org,omitempty"` Customizations *GUICustomizations `protobuf:"bytes,8,opt,name=customizations,proto3" json:"customizations,omitempty"` + Links []*proto1.GUILink `protobuf:"bytes,9,rep,name=links,proto3" json:"links,omitempty"` } func (x *SetGUIOptionsRequest) Reset() { *x = SetGUIOptionsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_users_proto_msgTypes[10] + mi := &file_users_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -980,7 +927,7 @@ func (x *SetGUIOptionsRequest) String() string { func (*SetGUIOptionsRequest) ProtoMessage() {} func (x *SetGUIOptionsRequest) ProtoReflect() protoreflect.Message { - mi := &file_users_proto_msgTypes[10] + mi := &file_users_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -993,7 +940,7 @@ func (x *SetGUIOptionsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SetGUIOptionsRequest.ProtoReflect.Descriptor instead. func (*SetGUIOptionsRequest) Descriptor() ([]byte, []int) { - return file_users_proto_rawDescGZIP(), []int{10} + return file_users_proto_rawDescGZIP(), []int{9} } func (x *SetGUIOptionsRequest) GetTheme() string { @@ -1052,6 +999,13 @@ func (x *SetGUIOptionsRequest) GetCustomizations() *GUICustomizations { return nil } +func (x *SetGUIOptionsRequest) GetLinks() []*proto1.GUILink { + if x != nil { + return x.Links + } + return nil +} + type Users struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1063,7 +1017,7 @@ type Users struct { func (x *Users) Reset() { *x = Users{} if protoimpl.UnsafeEnabled { - mi := &file_users_proto_msgTypes[11] + mi := &file_users_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1076,7 +1030,7 @@ func (x *Users) String() string { func (*Users) ProtoMessage() {} func (x *Users) ProtoReflect() protoreflect.Message { - mi := &file_users_proto_msgTypes[11] + mi := &file_users_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1089,7 +1043,7 @@ func (x *Users) ProtoReflect() protoreflect.Message { // Deprecated: Use Users.ProtoReflect.Descriptor instead. func (*Users) Descriptor() ([]byte, []int) { - return file_users_proto_rawDescGZIP(), []int{11} + return file_users_proto_rawDescGZIP(), []int{10} } func (x *Users) GetUsers() []*VelociraptorUser { @@ -1110,7 +1064,7 @@ type SetPasswordRequest struct { func (x *SetPasswordRequest) Reset() { *x = SetPasswordRequest{} if protoimpl.UnsafeEnabled { - mi := &file_users_proto_msgTypes[12] + mi := &file_users_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1123,7 +1077,7 @@ func (x *SetPasswordRequest) String() string { func (*SetPasswordRequest) ProtoMessage() {} func (x *SetPasswordRequest) ProtoReflect() protoreflect.Message { - mi := &file_users_proto_msgTypes[12] + mi := &file_users_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1136,7 +1090,7 @@ func (x *SetPasswordRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SetPasswordRequest.ProtoReflect.Descriptor instead. func (*SetPasswordRequest) Descriptor() ([]byte, []int) { - return file_users_proto_rawDescGZIP(), []int{12} + return file_users_proto_rawDescGZIP(), []int{11} } func (x *SetPasswordRequest) GetPassword() string { @@ -1154,14 +1108,14 @@ type Favorite struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` - Spec []*proto1.ArtifactSpec `protobuf:"bytes,3,rep,name=spec,proto3" json:"spec,omitempty"` + Spec []*proto2.ArtifactSpec `protobuf:"bytes,3,rep,name=spec,proto3" json:"spec,omitempty"` Type string `protobuf:"bytes,4,opt,name=type,proto3" json:"type,omitempty"` } func (x *Favorite) Reset() { *x = Favorite{} if protoimpl.UnsafeEnabled { - mi := &file_users_proto_msgTypes[13] + mi := &file_users_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1174,7 +1128,7 @@ func (x *Favorite) String() string { func (*Favorite) ProtoMessage() {} func (x *Favorite) ProtoReflect() protoreflect.Message { - mi := &file_users_proto_msgTypes[13] + mi := &file_users_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1187,7 +1141,7 @@ func (x *Favorite) ProtoReflect() protoreflect.Message { // Deprecated: Use Favorite.ProtoReflect.Descriptor instead. func (*Favorite) Descriptor() ([]byte, []int) { - return file_users_proto_rawDescGZIP(), []int{13} + return file_users_proto_rawDescGZIP(), []int{12} } func (x *Favorite) GetName() string { @@ -1204,7 +1158,7 @@ func (x *Favorite) GetDescription() string { return "" } -func (x *Favorite) GetSpec() []*proto1.ArtifactSpec { +func (x *Favorite) GetSpec() []*proto2.ArtifactSpec { if x != nil { return x.Spec } @@ -1229,7 +1183,7 @@ type Favorites struct { func (x *Favorites) Reset() { *x = Favorites{} if protoimpl.UnsafeEnabled { - mi := &file_users_proto_msgTypes[14] + mi := &file_users_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1242,7 +1196,7 @@ func (x *Favorites) String() string { func (*Favorites) ProtoMessage() {} func (x *Favorites) ProtoReflect() protoreflect.Message { - mi := &file_users_proto_msgTypes[14] + mi := &file_users_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1255,7 +1209,7 @@ func (x *Favorites) ProtoReflect() protoreflect.Message { // Deprecated: Use Favorites.ProtoReflect.Descriptor instead. func (*Favorites) Descriptor() ([]byte, []int) { - return file_users_proto_rawDescGZIP(), []int{14} + return file_users_proto_rawDescGZIP(), []int{13} } func (x *Favorites) GetItems() []*Favorite { @@ -1272,222 +1226,224 @@ var file_users_proto_rawDesc = []byte{ 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x65, 0x6d, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x61, 0x63, 0x6c, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x61, 0x63, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x1a, 0x24, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x61, 0x72, - 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x29, 0x0a, 0x03, 0x4f, 0x72, 0x67, 0x12, 0x12, 0x0a, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, - 0x64, 0x22, 0xba, 0x04, 0x0a, 0x10, 0x56, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x72, 0x61, 0x70, 0x74, - 0x6f, 0x72, 0x55, 0x73, 0x65, 0x72, 0x12, 0x28, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x14, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x0e, 0x12, 0x0c, 0x54, 0x68, - 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x49, 0x0a, 0x0d, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x68, 0x61, 0x73, - 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x24, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x1e, 0x12, - 0x1c, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x68, 0x61, 0x73, 0x68, 0x20, 0x6f, 0x66, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x2e, 0x52, 0x0c, 0x70, - 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x48, 0x61, 0x73, 0x68, 0x12, 0x23, 0x0a, 0x0d, 0x70, - 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x73, 0x61, 0x6c, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x0c, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x53, 0x61, 0x6c, 0x74, - 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x69, 0x63, 0x74, 0x75, 0x72, - 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, - 0x12, 0x25, 0x0a, 0x0e, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x65, 0x6d, 0x61, - 0x69, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, - 0x65, 0x64, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x72, 0x0a, 0x09, 0x72, 0x65, 0x61, 0x64, 0x5f, - 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x42, 0x55, 0xe2, 0xfc, 0xe3, 0xc4, - 0x01, 0x4f, 0x12, 0x4d, 0x41, 0x20, 0x72, 0x65, 0x61, 0x64, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, - 0x75, 0x73, 0x65, 0x72, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x75, 0x73, 0x65, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x47, 0x55, 0x49, 0x20, 0x62, 0x75, 0x74, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, - 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x6c, 0x61, 0x75, 0x6e, 0x63, - 0x68, 0x20, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x20, 0x6f, 0x72, 0x20, 0x68, 0x75, 0x6e, 0x74, 0x73, - 0x2e, 0x52, 0x08, 0x72, 0x65, 0x61, 0x64, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x49, 0x0a, 0x06, 0x6c, - 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x42, 0x31, 0xe2, 0xfc, 0xe3, - 0xc4, 0x01, 0x2b, 0x12, 0x29, 0x49, 0x66, 0x20, 0x73, 0x65, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x75, 0x73, 0x65, 0x72, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x6f, - 0x77, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x6c, 0x6f, 0x67, 0x20, 0x69, 0x6e, 0x2e, 0x52, 0x06, - 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x12, 0x35, 0x0a, 0x0b, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x70, 0x69, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x41, 0x43, 0x4c, - 0x52, 0x0b, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1e, 0x0a, - 0x04, 0x6f, 0x72, 0x67, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x4f, 0x72, 0x67, 0x52, 0x04, 0x6f, 0x72, 0x67, 0x73, 0x12, 0x1f, 0x0a, - 0x0b, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x6f, 0x72, 0x67, 0x18, 0x0c, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0a, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x4f, 0x72, 0x67, 0x22, 0x2e, - 0x0a, 0x06, 0x55, 0x49, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x65, 0x78, 0x74, 0x12, 0x10, 0x0a, 0x03, - 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x83, - 0x04, 0x0a, 0x16, 0x41, 0x70, 0x69, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x54, 0x72, 0x61, 0x69, 0x74, 0x73, 0x12, 0x35, 0x0a, 0x0b, 0x50, 0x65, 0x72, - 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x70, 0x69, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x41, 0x43, 0x4c, 0x52, 0x0b, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, - 0x12, 0x40, 0x0a, 0x0e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x47, 0x55, 0x49, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x52, 0x0e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x18, 0x16, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, - 0x72, 0x64, 0x5f, 0x6c, 0x65, 0x73, 0x73, 0x18, 0x19, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x70, - 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x4c, 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x70, - 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x69, - 0x63, 0x74, 0x75, 0x72, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x15, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x55, 0x49, 0x4c, - 0x69, 0x6e, 0x6b, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x68, - 0x65, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x68, 0x65, 0x6d, 0x65, - 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x17, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x12, 0x29, 0x0a, 0x10, - 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x50, - 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x34, 0x0a, 0x16, 0x64, 0x65, 0x66, 0x61, 0x75, - 0x6c, 0x74, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x5f, 0x6c, 0x6f, 0x63, - 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, - 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x4c, 0x6f, 0x63, 0x6b, 0x12, 0x1f, 0x0a, - 0x0b, 0x75, 0x69, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0a, 0x75, 0x69, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x10, - 0x0a, 0x03, 0x6f, 0x72, 0x67, 0x18, 0x18, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6f, 0x72, 0x67, - 0x12, 0x32, 0x0a, 0x15, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x13, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x73, 0x22, 0xfb, 0x02, 0x0a, 0x07, 0x41, 0x70, 0x69, 0x55, 0x73, 0x65, 0x72, - 0x12, 0x39, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x1d, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x17, 0x12, 0x15, 0x54, 0x68, 0x65, 0x20, - 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, - 0x2e, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x91, 0x01, 0x0a, 0x10, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x74, 0x72, 0x61, 0x69, 0x74, 0x73, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, - 0x70, 0x69, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x54, - 0x72, 0x61, 0x69, 0x74, 0x73, 0x42, 0x47, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x41, 0x12, 0x3f, 0x55, - 0x73, 0x65, 0x72, 0x27, 0x73, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x20, - 0x74, 0x72, 0x61, 0x69, 0x74, 0x73, 0x20, 0x28, 0x77, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, - 0x79, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x61, 0x6e, 0x27, 0x74, 0x20, - 0x64, 0x6f, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x55, 0x49, 0x29, 0x2e, 0x52, 0x0f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x54, 0x72, 0x61, 0x69, 0x74, 0x73, 0x12, - 0x34, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x70, 0x69, 0x55, 0x73, - 0x65, 0x72, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x75, 0x73, 0x65, - 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1e, 0x0a, 0x04, 0x6f, 0x72, 0x67, 0x73, 0x18, 0x0b, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4f, 0x72, 0x67, 0x52, - 0x04, 0x6f, 0x72, 0x67, 0x73, 0x22, 0x4b, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x12, 0x0a, 0x0e, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4e, - 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x54, 0x59, - 0x50, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x4e, 0x44, 0x41, 0x52, 0x44, 0x10, 0x01, 0x12, 0x13, 0x0a, - 0x0f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x44, 0x4d, 0x49, 0x4e, - 0x10, 0x02, 0x22, 0x2d, 0x0a, 0x15, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x22, 0xfa, 0x06, 0x0a, 0x10, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x49, 0x0a, 0x11, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x10, 0x6e, 0x6f, 0x74, - 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x33, 0x0a, - 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x12, 0x31, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x04, 0x42, 0x13, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x0d, 0x0a, 0x0b, 0x52, - 0x44, 0x46, 0x44, 0x61, 0x74, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, - 0xb8, 0x04, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x55, 0x4e, 0x53, 0x45, 0x54, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x52, 0x4f, 0x47, - 0x41, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x22, 0x0a, 0x1e, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, - 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x52, 0x4f, 0x56, 0x41, 0x4c, 0x5f, 0x52, - 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x20, 0x0a, 0x1c, 0x54, 0x59, - 0x50, 0x45, 0x5f, 0x48, 0x55, 0x4e, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x52, 0x4f, 0x56, 0x41, 0x4c, - 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x45, 0x44, 0x10, 0x03, 0x12, 0x24, 0x0a, 0x20, - 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x52, 0x4f, 0x4e, 0x5f, 0x4a, 0x4f, 0x42, 0x5f, 0x41, 0x50, - 0x50, 0x52, 0x4f, 0x56, 0x41, 0x4c, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x45, 0x44, - 0x10, 0x04, 0x12, 0x20, 0x0a, 0x1c, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, - 0x54, 0x5f, 0x41, 0x50, 0x50, 0x52, 0x4f, 0x56, 0x41, 0x4c, 0x5f, 0x47, 0x52, 0x41, 0x4e, 0x54, - 0x45, 0x44, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x48, 0x55, 0x4e, - 0x54, 0x5f, 0x41, 0x50, 0x50, 0x52, 0x4f, 0x56, 0x41, 0x4c, 0x5f, 0x47, 0x52, 0x41, 0x4e, 0x54, - 0x45, 0x44, 0x10, 0x06, 0x12, 0x22, 0x0a, 0x1e, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x52, 0x4f, - 0x4e, 0x5f, 0x4a, 0x4f, 0x42, 0x5f, 0x41, 0x50, 0x50, 0x52, 0x4f, 0x56, 0x41, 0x4c, 0x5f, 0x47, - 0x52, 0x41, 0x4e, 0x54, 0x45, 0x44, 0x10, 0x07, 0x12, 0x1b, 0x0a, 0x17, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x56, 0x46, 0x53, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x45, 0x43, - 0x54, 0x45, 0x44, 0x10, 0x08, 0x12, 0x23, 0x0a, 0x1f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x56, 0x46, - 0x53, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x45, 0x43, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x09, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x59, - 0x50, 0x45, 0x5f, 0x48, 0x55, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x4f, 0x50, 0x50, 0x45, 0x44, 0x10, - 0x0a, 0x12, 0x1f, 0x0a, 0x1b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x5f, 0x41, - 0x52, 0x43, 0x48, 0x49, 0x56, 0x45, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x45, 0x44, - 0x10, 0x0b, 0x12, 0x27, 0x0a, 0x23, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x5f, - 0x41, 0x52, 0x43, 0x48, 0x49, 0x56, 0x45, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, - 0x4f, 0x4e, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x0c, 0x12, 0x1b, 0x0a, 0x17, 0x54, - 0x59, 0x50, 0x45, 0x5f, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x52, 0x55, 0x4e, 0x5f, 0x43, 0x4f, 0x4d, - 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x0d, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x52, 0x55, 0x4e, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, - 0x10, 0x0e, 0x12, 0x25, 0x0a, 0x21, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x56, 0x46, 0x53, 0x5f, 0x4c, - 0x49, 0x53, 0x54, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x4f, 0x52, 0x59, 0x5f, 0x43, 0x4f, - 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x0f, 0x12, 0x2f, 0x0a, 0x2b, 0x54, 0x59, 0x50, - 0x45, 0x5f, 0x56, 0x46, 0x53, 0x5f, 0x52, 0x45, 0x43, 0x55, 0x52, 0x53, 0x49, 0x56, 0x45, 0x5f, - 0x4c, 0x49, 0x53, 0x54, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x4f, 0x52, 0x59, 0x5f, 0x43, - 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x10, 0x22, 0x42, 0x0a, 0x05, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, - 0x45, 0x54, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x50, 0x45, - 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x54, 0x41, 0x54, 0x45, - 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x22, 0x4d, - 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, - 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x71, 0x0a, - 0x1b, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x52, 0x0a, 0x0d, - 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x08, 0x42, 0x2d, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x27, 0x12, 0x25, 0x49, 0x66, 0x20, - 0x73, 0x65, 0x74, 0x2c, 0x20, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x73, 0x20, 0x70, 0x65, 0x6e, 0x64, - 0x69, 0x6e, 0x67, 0x20, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x2e, 0x52, 0x0c, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, - 0x22, 0x47, 0x0a, 0x11, 0x47, 0x55, 0x49, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x69, 0x7a, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, - 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0xab, 0x02, 0x0a, 0x14, 0x53, 0x65, - 0x74, 0x47, 0x55, 0x49, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x68, 0x65, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x74, 0x68, 0x65, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x69, 0x6d, 0x65, - 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x69, 0x6d, 0x65, - 0x7a, 0x6f, 0x6e, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x29, 0x0a, 0x10, 0x64, 0x65, 0x66, 0x61, + 0x1a, 0x19, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x24, 0x66, 0x6c, 0x6f, + 0x77, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, + 0x74, 0x5f, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x22, 0x29, 0x0a, 0x03, 0x4f, 0x72, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0xba, 0x04, 0x0a, + 0x10, 0x56, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x72, 0x61, 0x70, 0x74, 0x6f, 0x72, 0x55, 0x73, 0x65, + 0x72, 0x12, 0x28, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x14, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x0e, 0x12, 0x0c, 0x54, 0x68, 0x65, 0x20, 0x75, 0x73, 0x65, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x49, 0x0a, 0x0d, 0x70, + 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x42, 0x24, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x1e, 0x12, 0x1c, 0x53, 0x48, 0x41, 0x32, + 0x35, 0x36, 0x20, 0x68, 0x61, 0x73, 0x68, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, + 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x2e, 0x52, 0x0c, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, + 0x72, 0x64, 0x48, 0x61, 0x73, 0x68, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, + 0x72, 0x64, 0x5f, 0x73, 0x61, 0x6c, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x70, + 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x53, 0x61, 0x6c, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, + 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, + 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x70, 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x76, + 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0d, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x45, 0x6d, 0x61, + 0x69, 0x6c, 0x12, 0x72, 0x0a, 0x09, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x08, 0x42, 0x55, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x4f, 0x12, 0x4d, 0x41, + 0x20, 0x72, 0x65, 0x61, 0x64, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, + 0x63, 0x61, 0x6e, 0x20, 0x75, 0x73, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x47, 0x55, 0x49, 0x20, + 0x62, 0x75, 0x74, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x77, + 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x6c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x20, 0x66, 0x6c, 0x6f, + 0x77, 0x73, 0x20, 0x6f, 0x72, 0x20, 0x68, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x52, 0x08, 0x72, 0x65, + 0x61, 0x64, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x49, 0x0a, 0x06, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x42, 0x31, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x2b, 0x12, 0x29, + 0x49, 0x66, 0x20, 0x73, 0x65, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, + 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x20, 0x74, + 0x6f, 0x20, 0x6c, 0x6f, 0x67, 0x20, 0x69, 0x6e, 0x2e, 0x52, 0x06, 0x6c, 0x6f, 0x63, 0x6b, 0x65, + 0x64, 0x12, 0x35, 0x0a, 0x0b, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, + 0x70, 0x69, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x41, 0x43, 0x4c, 0x52, 0x0b, 0x50, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1e, 0x0a, 0x04, 0x6f, 0x72, 0x67, 0x73, + 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4f, + 0x72, 0x67, 0x52, 0x04, 0x6f, 0x72, 0x67, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x75, 0x72, 0x72, + 0x65, 0x6e, 0x74, 0x5f, 0x6f, 0x72, 0x67, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, + 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x4f, 0x72, 0x67, 0x22, 0x84, 0x04, 0x0a, 0x16, 0x41, 0x70, + 0x69, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x54, 0x72, + 0x61, 0x69, 0x74, 0x73, 0x12, 0x35, 0x0a, 0x0b, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x41, 0x70, 0x69, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x41, 0x43, 0x4c, 0x52, 0x0b, + 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x40, 0x0a, 0x0e, 0x63, + 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0a, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x55, 0x49, 0x43, + 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0e, 0x63, + 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x12, 0x0a, + 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x18, 0x16, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x61, 0x6e, + 0x67, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x6c, 0x65, + 0x73, 0x73, 0x18, 0x19, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, + 0x72, 0x64, 0x4c, 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x69, 0x63, 0x74, 0x75, 0x72, + 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, + 0x12, 0x24, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x15, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x55, 0x49, 0x4c, 0x69, 0x6e, 0x6b, 0x52, + 0x05, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x68, 0x65, 0x6d, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x68, 0x65, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, + 0x74, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x17, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x74, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x34, 0x0a, 0x16, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x5f, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x44, 0x6f, 0x77, 0x6e, - 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x4c, 0x6f, 0x63, 0x6b, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x6f, 0x72, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x6f, 0x72, 0x67, 0x12, 0x40, 0x0a, 0x0e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x69, - 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x55, 0x49, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x69, - 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x69, - 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x36, 0x0a, 0x05, 0x55, 0x73, 0x65, 0x72, 0x73, - 0x12, 0x2d, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x72, 0x61, - 0x70, 0x74, 0x6f, 0x72, 0x55, 0x73, 0x65, 0x72, 0x52, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x22, - 0x30, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, - 0x64, 0x22, 0x7d, 0x0a, 0x08, 0x46, 0x61, 0x76, 0x6f, 0x72, 0x69, 0x74, 0x65, 0x12, 0x12, 0x0a, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x03, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, - 0x63, 0x74, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x12, 0x0a, 0x04, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x22, 0x32, 0x0a, 0x09, 0x46, 0x61, 0x76, 0x6f, 0x72, 0x69, 0x74, 0x65, 0x73, 0x12, 0x25, 0x0a, - 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x61, 0x76, 0x6f, 0x72, 0x69, 0x74, 0x65, 0x52, 0x05, 0x69, - 0x74, 0x65, 0x6d, 0x73, 0x42, 0x31, 0x5a, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x6c, 0x6f, - 0x63, 0x69, 0x64, 0x65, 0x78, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, - 0x2f, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x72, 0x61, 0x70, 0x74, 0x6f, 0x72, 0x2f, 0x61, 0x70, - 0x69, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x4c, 0x6f, 0x63, 0x6b, 0x12, 0x1f, 0x0a, 0x0b, 0x75, 0x69, 0x5f, + 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x75, 0x69, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x6f, 0x72, + 0x67, 0x18, 0x18, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6f, 0x72, 0x67, 0x12, 0x32, 0x0a, 0x15, + 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x64, 0x69, 0x73, + 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, + 0x22, 0xfb, 0x02, 0x0a, 0x07, 0x41, 0x70, 0x69, 0x55, 0x73, 0x65, 0x72, 0x12, 0x39, 0x0a, 0x08, + 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x1d, + 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x17, 0x12, 0x15, 0x54, 0x68, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x52, 0x08, 0x75, + 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x91, 0x01, 0x0a, 0x10, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x74, 0x72, 0x61, 0x69, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x70, 0x69, 0x55, 0x73, + 0x65, 0x72, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x54, 0x72, 0x61, 0x69, 0x74, + 0x73, 0x42, 0x47, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x41, 0x12, 0x3f, 0x55, 0x73, 0x65, 0x72, 0x27, + 0x73, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x20, 0x74, 0x72, 0x61, 0x69, + 0x74, 0x73, 0x20, 0x28, 0x77, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x79, 0x20, 0x63, 0x61, + 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x61, 0x6e, 0x27, 0x74, 0x20, 0x64, 0x6f, 0x20, 0x69, + 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x55, 0x49, 0x29, 0x2e, 0x52, 0x0f, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x66, 0x61, 0x63, 0x65, 0x54, 0x72, 0x61, 0x69, 0x74, 0x73, 0x12, 0x34, 0x0a, 0x09, 0x75, + 0x73, 0x65, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x70, 0x69, 0x55, 0x73, 0x65, 0x72, 0x2e, 0x55, + 0x73, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x1e, 0x0a, 0x04, 0x6f, 0x72, 0x67, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x0a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4f, 0x72, 0x67, 0x52, 0x04, 0x6f, 0x72, 0x67, + 0x73, 0x22, 0x4b, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, + 0x0e, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x10, + 0x00, 0x12, 0x16, 0x0a, 0x12, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, + 0x54, 0x41, 0x4e, 0x44, 0x41, 0x52, 0x44, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x55, 0x53, 0x45, + 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x10, 0x02, 0x22, 0x2d, + 0x0a, 0x15, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xfa, 0x06, + 0x0a, 0x10, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x49, + 0x0a, 0x11, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x10, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x33, 0x0a, 0x05, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x31, + 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x04, 0x42, 0x13, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x0d, 0x0a, 0x0b, 0x52, 0x44, 0x46, 0x44, 0x61, + 0x74, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xb8, 0x04, 0x0a, 0x04, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, + 0x45, 0x54, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x4c, 0x49, + 0x45, 0x4e, 0x54, 0x5f, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x52, 0x4f, 0x47, 0x41, 0x54, 0x45, 0x44, + 0x10, 0x01, 0x12, 0x22, 0x0a, 0x1e, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, + 0x54, 0x5f, 0x41, 0x50, 0x50, 0x52, 0x4f, 0x56, 0x41, 0x4c, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, + 0x53, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x20, 0x0a, 0x1c, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x48, + 0x55, 0x4e, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x52, 0x4f, 0x56, 0x41, 0x4c, 0x5f, 0x52, 0x45, 0x51, + 0x55, 0x45, 0x53, 0x54, 0x45, 0x44, 0x10, 0x03, 0x12, 0x24, 0x0a, 0x20, 0x54, 0x59, 0x50, 0x45, + 0x5f, 0x43, 0x52, 0x4f, 0x4e, 0x5f, 0x4a, 0x4f, 0x42, 0x5f, 0x41, 0x50, 0x50, 0x52, 0x4f, 0x56, + 0x41, 0x4c, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x45, 0x44, 0x10, 0x04, 0x12, 0x20, + 0x0a, 0x1c, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x41, 0x50, + 0x50, 0x52, 0x4f, 0x56, 0x41, 0x4c, 0x5f, 0x47, 0x52, 0x41, 0x4e, 0x54, 0x45, 0x44, 0x10, 0x05, + 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x48, 0x55, 0x4e, 0x54, 0x5f, 0x41, 0x50, + 0x50, 0x52, 0x4f, 0x56, 0x41, 0x4c, 0x5f, 0x47, 0x52, 0x41, 0x4e, 0x54, 0x45, 0x44, 0x10, 0x06, + 0x12, 0x22, 0x0a, 0x1e, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x52, 0x4f, 0x4e, 0x5f, 0x4a, 0x4f, + 0x42, 0x5f, 0x41, 0x50, 0x50, 0x52, 0x4f, 0x56, 0x41, 0x4c, 0x5f, 0x47, 0x52, 0x41, 0x4e, 0x54, + 0x45, 0x44, 0x10, 0x07, 0x12, 0x1b, 0x0a, 0x17, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x56, 0x46, 0x53, + 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, + 0x08, 0x12, 0x23, 0x0a, 0x1f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x56, 0x46, 0x53, 0x5f, 0x46, 0x49, + 0x4c, 0x45, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x46, 0x41, + 0x49, 0x4c, 0x45, 0x44, 0x10, 0x09, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x48, + 0x55, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x4f, 0x50, 0x50, 0x45, 0x44, 0x10, 0x0a, 0x12, 0x1f, 0x0a, + 0x1b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x5f, 0x41, 0x52, 0x43, 0x48, 0x49, + 0x56, 0x45, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x45, 0x44, 0x10, 0x0b, 0x12, 0x27, + 0x0a, 0x23, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x5f, 0x41, 0x52, 0x43, 0x48, + 0x49, 0x56, 0x45, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x46, + 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x0c, 0x12, 0x1b, 0x0a, 0x17, 0x54, 0x59, 0x50, 0x45, 0x5f, + 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x52, 0x55, 0x4e, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, + 0x45, 0x44, 0x10, 0x0d, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x4c, 0x4f, + 0x57, 0x5f, 0x52, 0x55, 0x4e, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x0e, 0x12, 0x25, + 0x0a, 0x21, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x56, 0x46, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x5f, + 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x4f, 0x52, 0x59, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, + 0x54, 0x45, 0x44, 0x10, 0x0f, 0x12, 0x2f, 0x0a, 0x2b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x56, 0x46, + 0x53, 0x5f, 0x52, 0x45, 0x43, 0x55, 0x52, 0x53, 0x49, 0x56, 0x45, 0x5f, 0x4c, 0x49, 0x53, 0x54, + 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x4f, 0x52, 0x59, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, + 0x45, 0x54, 0x45, 0x44, 0x10, 0x10, 0x22, 0x42, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, + 0x0f, 0x0a, 0x0b, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x45, 0x54, 0x10, 0x00, + 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, + 0x47, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x4e, 0x4f, 0x54, + 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x22, 0x4d, 0x0a, 0x1c, 0x47, 0x65, + 0x74, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x05, 0x69, 0x74, + 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x71, 0x0a, 0x1b, 0x47, 0x65, 0x74, + 0x55, 0x73, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x52, 0x0a, 0x0d, 0x63, 0x6c, 0x65, 0x61, + 0x72, 0x5f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x42, + 0x2d, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x27, 0x12, 0x25, 0x49, 0x66, 0x20, 0x73, 0x65, 0x74, 0x2c, + 0x20, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x73, 0x20, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, + 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x52, 0x0c, + 0x63, 0x6c, 0x65, 0x61, 0x72, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x22, 0x47, 0x0a, 0x11, + 0x47, 0x55, 0x49, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x32, 0x0a, 0x15, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x13, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0xd1, 0x02, 0x0a, 0x14, 0x53, 0x65, 0x74, 0x47, 0x55, 0x49, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, + 0x0a, 0x05, 0x74, 0x68, 0x65, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, + 0x68, 0x65, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, + 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x29, 0x0a, 0x10, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, + 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, + 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, + 0x34, 0x0a, 0x16, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, + 0x6f, 0x61, 0x64, 0x73, 0x5f, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x14, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, + 0x73, 0x4c, 0x6f, 0x63, 0x6b, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, + 0x10, 0x0a, 0x03, 0x6f, 0x72, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6f, 0x72, + 0x67, 0x12, 0x40, 0x0a, 0x0e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x69, 0x7a, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x47, 0x55, 0x49, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x69, 0x7a, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x0e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x69, 0x7a, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x12, 0x24, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x09, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x55, 0x49, 0x4c, 0x69, + 0x6e, 0x6b, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x22, 0x36, 0x0a, 0x05, 0x55, 0x73, 0x65, + 0x72, 0x73, 0x12, 0x2d, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x65, 0x6c, 0x6f, 0x63, 0x69, + 0x72, 0x61, 0x70, 0x74, 0x6f, 0x72, 0x55, 0x73, 0x65, 0x72, 0x52, 0x05, 0x75, 0x73, 0x65, 0x72, + 0x73, 0x22, 0x30, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, + 0x6f, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, + 0x6f, 0x72, 0x64, 0x22, 0x7d, 0x0a, 0x08, 0x46, 0x61, 0x76, 0x6f, 0x72, 0x69, 0x74, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x03, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, + 0x66, 0x61, 0x63, 0x74, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x12, + 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x22, 0x32, 0x0a, 0x09, 0x46, 0x61, 0x76, 0x6f, 0x72, 0x69, 0x74, 0x65, 0x73, 0x12, + 0x25, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x61, 0x76, 0x6f, 0x72, 0x69, 0x74, 0x65, 0x52, + 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x42, 0x31, 0x5a, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, + 0x6c, 0x6f, 0x63, 0x69, 0x64, 0x65, 0x78, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, + 0x6e, 0x67, 0x2f, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x72, 0x61, 0x70, 0x74, 0x6f, 0x72, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( @@ -1503,50 +1459,51 @@ func file_users_proto_rawDescGZIP() []byte { } var file_users_proto_enumTypes = make([]protoimpl.EnumInfo, 3) -var file_users_proto_msgTypes = make([]protoimpl.MessageInfo, 15) +var file_users_proto_msgTypes = make([]protoimpl.MessageInfo, 14) var file_users_proto_goTypes = []interface{}{ (ApiUser_UserType)(0), // 0: proto.ApiUser.UserType (UserNotification_Type)(0), // 1: proto.UserNotification.Type (UserNotification_State)(0), // 2: proto.UserNotification.State (*Org)(nil), // 3: proto.Org (*VelociraptorUser)(nil), // 4: proto.VelociraptorUser - (*UILink)(nil), // 5: proto.UILink - (*ApiUserInterfaceTraits)(nil), // 6: proto.ApiUserInterfaceTraits - (*ApiUser)(nil), // 7: proto.ApiUser - (*UserNotificationCount)(nil), // 8: proto.UserNotificationCount - (*UserNotification)(nil), // 9: proto.UserNotification - (*GetUserNotificationsResponse)(nil), // 10: proto.GetUserNotificationsResponse - (*GetUserNotificationsRequest)(nil), // 11: proto.GetUserNotificationsRequest - (*GUICustomizations)(nil), // 12: proto.GUICustomizations - (*SetGUIOptionsRequest)(nil), // 13: proto.SetGUIOptionsRequest - (*Users)(nil), // 14: proto.Users - (*SetPasswordRequest)(nil), // 15: proto.SetPasswordRequest - (*Favorite)(nil), // 16: proto.Favorite - (*Favorites)(nil), // 17: proto.Favorites - (*proto.ApiClientACL)(nil), // 18: proto.ApiClientACL - (*proto1.ArtifactSpec)(nil), // 19: proto.ArtifactSpec + (*ApiUserInterfaceTraits)(nil), // 5: proto.ApiUserInterfaceTraits + (*ApiUser)(nil), // 6: proto.ApiUser + (*UserNotificationCount)(nil), // 7: proto.UserNotificationCount + (*UserNotification)(nil), // 8: proto.UserNotification + (*GetUserNotificationsResponse)(nil), // 9: proto.GetUserNotificationsResponse + (*GetUserNotificationsRequest)(nil), // 10: proto.GetUserNotificationsRequest + (*GUICustomizations)(nil), // 11: proto.GUICustomizations + (*SetGUIOptionsRequest)(nil), // 12: proto.SetGUIOptionsRequest + (*Users)(nil), // 13: proto.Users + (*SetPasswordRequest)(nil), // 14: proto.SetPasswordRequest + (*Favorite)(nil), // 15: proto.Favorite + (*Favorites)(nil), // 16: proto.Favorites + (*proto.ApiClientACL)(nil), // 17: proto.ApiClientACL + (*proto1.GUILink)(nil), // 18: proto.GUILink + (*proto2.ArtifactSpec)(nil), // 19: proto.ArtifactSpec } var file_users_proto_depIdxs = []int32{ - 18, // 0: proto.VelociraptorUser.Permissions:type_name -> proto.ApiClientACL + 17, // 0: proto.VelociraptorUser.Permissions:type_name -> proto.ApiClientACL 3, // 1: proto.VelociraptorUser.orgs:type_name -> proto.Org - 18, // 2: proto.ApiUserInterfaceTraits.Permissions:type_name -> proto.ApiClientACL - 12, // 3: proto.ApiUserInterfaceTraits.customizations:type_name -> proto.GUICustomizations - 5, // 4: proto.ApiUserInterfaceTraits.links:type_name -> proto.UILink - 6, // 5: proto.ApiUser.interface_traits:type_name -> proto.ApiUserInterfaceTraits + 17, // 2: proto.ApiUserInterfaceTraits.Permissions:type_name -> proto.ApiClientACL + 11, // 3: proto.ApiUserInterfaceTraits.customizations:type_name -> proto.GUICustomizations + 18, // 4: proto.ApiUserInterfaceTraits.links:type_name -> proto.GUILink + 5, // 5: proto.ApiUser.interface_traits:type_name -> proto.ApiUserInterfaceTraits 0, // 6: proto.ApiUser.user_type:type_name -> proto.ApiUser.UserType 3, // 7: proto.ApiUser.orgs:type_name -> proto.Org 1, // 8: proto.UserNotification.notification_type:type_name -> proto.UserNotification.Type 2, // 9: proto.UserNotification.state:type_name -> proto.UserNotification.State - 9, // 10: proto.GetUserNotificationsResponse.items:type_name -> proto.UserNotification - 12, // 11: proto.SetGUIOptionsRequest.customizations:type_name -> proto.GUICustomizations - 4, // 12: proto.Users.users:type_name -> proto.VelociraptorUser - 19, // 13: proto.Favorite.spec:type_name -> proto.ArtifactSpec - 16, // 14: proto.Favorites.items:type_name -> proto.Favorite - 15, // [15:15] is the sub-list for method output_type - 15, // [15:15] is the sub-list for method input_type - 15, // [15:15] is the sub-list for extension type_name - 15, // [15:15] is the sub-list for extension extendee - 0, // [0:15] is the sub-list for field type_name + 8, // 10: proto.GetUserNotificationsResponse.items:type_name -> proto.UserNotification + 11, // 11: proto.SetGUIOptionsRequest.customizations:type_name -> proto.GUICustomizations + 18, // 12: proto.SetGUIOptionsRequest.links:type_name -> proto.GUILink + 4, // 13: proto.Users.users:type_name -> proto.VelociraptorUser + 19, // 14: proto.Favorite.spec:type_name -> proto.ArtifactSpec + 15, // 15: proto.Favorites.items:type_name -> proto.Favorite + 16, // [16:16] is the sub-list for method output_type + 16, // [16:16] is the sub-list for method input_type + 16, // [16:16] is the sub-list for extension type_name + 16, // [16:16] is the sub-list for extension extendee + 0, // [0:16] is the sub-list for field type_name } func init() { file_users_proto_init() } @@ -1580,18 +1537,6 @@ func file_users_proto_init() { } } file_users_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UILink); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_users_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ApiUserInterfaceTraits); i { case 0: return &v.state @@ -1603,7 +1548,7 @@ func file_users_proto_init() { return nil } } - file_users_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_users_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ApiUser); i { case 0: return &v.state @@ -1615,7 +1560,7 @@ func file_users_proto_init() { return nil } } - file_users_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + file_users_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UserNotificationCount); i { case 0: return &v.state @@ -1627,7 +1572,7 @@ func file_users_proto_init() { return nil } } - file_users_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + file_users_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UserNotification); i { case 0: return &v.state @@ -1639,7 +1584,7 @@ func file_users_proto_init() { return nil } } - file_users_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + file_users_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetUserNotificationsResponse); i { case 0: return &v.state @@ -1651,7 +1596,7 @@ func file_users_proto_init() { return nil } } - file_users_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + file_users_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetUserNotificationsRequest); i { case 0: return &v.state @@ -1663,7 +1608,7 @@ func file_users_proto_init() { return nil } } - file_users_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + file_users_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GUICustomizations); i { case 0: return &v.state @@ -1675,7 +1620,7 @@ func file_users_proto_init() { return nil } } - file_users_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + file_users_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SetGUIOptionsRequest); i { case 0: return &v.state @@ -1687,7 +1632,7 @@ func file_users_proto_init() { return nil } } - file_users_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + file_users_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Users); i { case 0: return &v.state @@ -1699,7 +1644,7 @@ func file_users_proto_init() { return nil } } - file_users_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + file_users_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SetPasswordRequest); i { case 0: return &v.state @@ -1711,7 +1656,7 @@ func file_users_proto_init() { return nil } } - file_users_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + file_users_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Favorite); i { case 0: return &v.state @@ -1723,7 +1668,7 @@ func file_users_proto_init() { return nil } } - file_users_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + file_users_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Favorites); i { case 0: return &v.state @@ -1742,7 +1687,7 @@ func file_users_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_users_proto_rawDesc, NumEnums: 3, - NumMessages: 15, + NumMessages: 14, NumExtensions: 0, NumServices: 0, }, diff --git a/api/proto/users.proto b/api/proto/users.proto index 8d9f5e0606..9c1e91c27e 100644 --- a/api/proto/users.proto +++ b/api/proto/users.proto @@ -2,6 +2,7 @@ syntax = "proto3"; import "proto/semantic.proto"; import "acls/proto/acl.proto"; +import "config/proto/config.proto"; import "flows/proto/artifact_collector.proto"; package proto; @@ -45,10 +46,6 @@ message VelociraptorUser { string current_org = 12; } -message UILink { - string text = 1; - string url = 2; -} // These traits are used to control the GUI App. Many of these fields // are constructed from the VelociraptorUser, the config file, the @@ -64,7 +61,7 @@ message ApiUserInterfaceTraits { bool password_less = 25; string picture = 20; - repeated UILink links = 21; + repeated GUILink links = 21; // Get the user's preferred theme. string theme = 2; @@ -181,6 +178,8 @@ message SetGUIOptionsRequest { string org = 7; GUICustomizations customizations = 8; + + repeated GUILink links = 9; } message Users { diff --git a/api/proxy.go b/api/proxy.go index 48f8d34d2c..1853cdd745 100644 --- a/api/proxy.go +++ b/api/proxy.go @@ -23,7 +23,6 @@ import ( "net/http" "net/http/httputil" "net/url" - "strings" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" errors "github.com/pkg/errors" @@ -32,13 +31,11 @@ import ( "google.golang.org/grpc/credentials" "google.golang.org/grpc/metadata" "google.golang.org/protobuf/encoding/protojson" - file_store_accessor "www.velocidex.com/golang/velociraptor/accessors/file_store" "www.velocidex.com/golang/velociraptor/api/authenticators" api_proto "www.velocidex.com/golang/velociraptor/api/proto" config_proto "www.velocidex.com/golang/velociraptor/config/proto" "www.velocidex.com/golang/velociraptor/constants" crypto_utils "www.velocidex.com/golang/velociraptor/crypto/utils" - file_store "www.velocidex.com/golang/velociraptor/file_store" "www.velocidex.com/golang/velociraptor/grpc_client" "www.velocidex.com/golang/velociraptor/logging" ) @@ -141,56 +138,40 @@ func PrepareGUIMux( auther.AuthenticateUserHandler(h))) mux.Handle(base+"/api/v1/DownloadTable", csrfProtect(config_obj, - auther.AuthenticateUserHandler( - downloadTable(config_obj)))) + auther.AuthenticateUserHandler(downloadTable()))) mux.Handle(base+"/api/v1/DownloadVFSFile", csrfProtect(config_obj, - auther.AuthenticateUserHandler( - vfsFileDownloadHandler(config_obj)))) + auther.AuthenticateUserHandler(vfsFileDownloadHandler()))) mux.Handle(base+"/api/v1/UploadTool", csrfProtect(config_obj, - auther.AuthenticateUserHandler( - toolUploadHandler(config_obj)))) + auther.AuthenticateUserHandler(toolUploadHandler()))) mux.Handle(base+"/api/v1/UploadFormFile", csrfProtect(config_obj, - auther.AuthenticateUserHandler( - formUploadHandler(config_obj)))) + auther.AuthenticateUserHandler(formUploadHandler()))) // Serve prepared zip files. mux.Handle(base+"/downloads/", csrfProtect(config_obj, auther.AuthenticateUserHandler( - http.StripPrefix(base, forceMime(http.FileServer( - file_store_accessor.NewFileSystem( - config_obj, - file_store.GetFileStore(config_obj), - "/downloads/"))))))) + http.StripPrefix(base, + downloadFileStore([]string{"downloads"}))))) // Serve notebook items mux.Handle(base+"/notebooks/", csrfProtect(config_obj, auther.AuthenticateUserHandler( - http.StripPrefix(base, forceMime(http.FileServer( - file_store_accessor.NewFileSystem( - config_obj, - file_store.GetFileStore(config_obj), - "/notebooks/"))))))) + http.StripPrefix(base, + downloadFileStore([]string{"notebooks"}))))) // Serve files from hunt notebooks mux.Handle(base+"/hunts/", csrfProtect(config_obj, auther.AuthenticateUserHandler( - http.StripPrefix(base, forceMime(http.FileServer( - file_store_accessor.NewFileSystem( - config_obj, - file_store.GetFileStore(config_obj), - "/hunts/"))))))) + http.StripPrefix(base, + downloadFileStore([]string{"hunts"}))))) // Serve files from client notebooks mux.Handle(base+"/clients/", csrfProtect(config_obj, auther.AuthenticateUserHandler( - http.StripPrefix(base, forceMime(http.FileServer( - file_store_accessor.NewFileSystem( - config_obj, - file_store.GetFileStore(config_obj), - "/clients/"))))))) + http.StripPrefix(base, + downloadFileStore([]string{"clients"}))))) // Assets etc do not need auth. install_static_assets(config_obj, mux) @@ -309,17 +290,3 @@ func GetAPIHandler( return reverse_proxy_mux, nil } - -// Force mime type to binary stream. -func forceMime(parent http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // Prevent directory listings. - if strings.HasSuffix(r.URL.Path, "/") { - http.NotFound(w, r) - return - } - - w.Header().Set("Content-Type", "binary/octet-stream") - parent.ServeHTTP(w, r) - }) -} diff --git a/api/upload.go b/api/upload.go index 1517883885..6bd50eab0a 100644 --- a/api/upload.go +++ b/api/upload.go @@ -9,9 +9,9 @@ import ( "path" "www.velocidex.com/golang/velociraptor/acls" + "www.velocidex.com/golang/velociraptor/api/authenticators" api_proto "www.velocidex.com/golang/velociraptor/api/proto" artifacts_proto "www.velocidex.com/golang/velociraptor/artifacts/proto" - config_proto "www.velocidex.com/golang/velociraptor/config/proto" file_store "www.velocidex.com/golang/velociraptor/file_store" "www.velocidex.com/golang/velociraptor/json" "www.velocidex.com/golang/velociraptor/logging" @@ -19,13 +19,25 @@ import ( "www.velocidex.com/golang/velociraptor/services" ) -func toolUploadHandler( - config_obj *config_proto.Config) http.Handler { +func toolUploadHandler() http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + org_id := authenticators.GetOrgIdFromRequest(r) + org_manager, err := services.GetOrgManager() + if err != nil { + returnError(w, http.StatusUnauthorized, err.Error()) + return + } + + org_config_obj, err := org_manager.GetOrgConfig(org_id) + if err != nil { + returnError(w, http.StatusUnauthorized, err.Error()) + return + } + // Check for acls - userinfo := GetUserInfo(r.Context(), config_obj) + userinfo := GetUserInfo(r.Context(), org_config_obj) permissions := acls.ARTIFACT_WRITER - perm, err := acls.CheckAccess(config_obj, userinfo.Name, permissions) + perm, err := acls.CheckAccess(org_config_obj, userinfo.Name, permissions) if !perm || err != nil { returnError(w, http.StatusUnauthorized, "User is not allowed to upload tools.") @@ -67,8 +79,19 @@ func toolUploadHandler( tool.Filename = path.Base(handler.Filename) tool.ServeLocally = true - file_store_factory := file_store.GetFileStore(config_obj) - path_manager := paths.NewInventoryPathManager(config_obj, tool) + // All tools are stored at the global public directory which is + // mapped to a http static handler. The downloaded URL is + // regardless of org - however each org has a different download + // name. We need to write the tool on the root org's public + // directory. + root_org_config, err := org_manager.GetOrgConfig(services.ROOT_ORG_ID) + if err != nil { + returnError(w, 404, err.Error()) + } + + file_store_factory := file_store.GetFileStore(root_org_config) + path_manager := paths.NewInventoryPathManager(org_config_obj, tool) + writer, err := file_store_factory.WriteFile(path_manager.Path()) if err != nil { returnError(w, http.StatusInternalServerError, @@ -95,14 +118,14 @@ func toolUploadHandler( tool.Hash = hex.EncodeToString(sha_sum.Sum(nil)) - inventory, err := services.GetInventory(config_obj) + inventory, err := services.GetInventory(org_config_obj) if err != nil { returnError(w, http.StatusInternalServerError, fmt.Sprintf("Error: %v", err)) return } - err = inventory.AddTool(config_obj, tool, + err = inventory.AddTool(org_config_obj, tool, services.ToolOptions{ AdminOverride: true, }) @@ -114,7 +137,7 @@ func toolUploadHandler( // Now materialize the tool tool, err = inventory.GetToolInfo( - r.Context(), config_obj, tool.Name) + r.Context(), org_config_obj, tool.Name) if err != nil { returnError(w, http.StatusInternalServerError, fmt.Sprintf("Error: %v", err)) @@ -124,19 +147,31 @@ func toolUploadHandler( serialized, _ := json.Marshal(tool) _, err = w.Write(serialized) if err != nil { - logger := logging.GetLogger(config_obj, &logging.GUIComponent) + logger := logging.GetLogger(org_config_obj, &logging.GUIComponent) logger.Error("toolUploadHandler: %v", err) } }) } -func formUploadHandler( - config_obj *config_proto.Config) http.Handler { +func formUploadHandler() http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + org_id := authenticators.GetOrgIdFromRequest(r) + org_manager, err := services.GetOrgManager() + if err != nil { + returnError(w, http.StatusUnauthorized, err.Error()) + return + } + + org_config_obj, err := org_manager.GetOrgConfig(org_id) + if err != nil { + returnError(w, http.StatusUnauthorized, err.Error()) + return + } + // Check for acls - userinfo := GetUserInfo(r.Context(), config_obj) + userinfo := GetUserInfo(r.Context(), org_config_obj) permissions := acls.COLLECT_CLIENT - perm, err := acls.CheckAccess(config_obj, userinfo.Name, permissions) + perm, err := acls.CheckAccess(org_config_obj, userinfo.Name, permissions) if !perm || err != nil { returnError(w, http.StatusUnauthorized, "User is not allowed to upload files for forms.") @@ -177,9 +212,9 @@ func formUploadHandler( form_desc.Filename = path.Base(handler.Filename) - file_store_factory := file_store.GetFileStore(config_obj) + file_store_factory := file_store.GetFileStore(org_config_obj) path_manager := paths.NewFormUploadPathManager( - config_obj, form_desc.Filename) + org_config_obj, form_desc.Filename) form_desc.Url = path_manager.URL() @@ -208,7 +243,7 @@ func formUploadHandler( serialized, _ := json.Marshal(form_desc) _, err = w.Write(serialized) if err != nil { - logger := logging.GetLogger(config_obj, &logging.GUIComponent) + logger := logging.GetLogger(org_config_obj, &logging.GUIComponent) logger.Error("toolUploadHandler: %v", err) } }) diff --git a/api/users.go b/api/users.go index 9117a5b956..b07a0e5937 100644 --- a/api/users.go +++ b/api/users.go @@ -39,7 +39,7 @@ func (self *ApiServer) SetPassword( return nil, err } - org_config_obj, err := org_manager.GetOrgConfig("root") + org_config_obj, err := org_manager.GetOrgConfig(services.ROOT_ORG_ID) if err != nil { return nil, err } diff --git a/artifacts/definitions/Demo/Plugins/GUI.yaml b/artifacts/definitions/Demo/Plugins/GUI.yaml index 45393e130b..71a766c6a8 100644 --- a/artifacts/definitions/Demo/Plugins/GUI.yaml +++ b/artifacts/definitions/Demo/Plugins/GUI.yaml @@ -262,7 +262,9 @@ sources: /* ## Adding timelines - Add a timeline from this time series data + Add a timeline from this time series data. (This only works + for root org because it relies on server health events). + */ SELECT timestamp(epoch=_ts) AS Timestamp, CPUPercent FROM monitoring( @@ -325,9 +327,11 @@ sources: These apply to notebooks automatically without needing to define them again. + Hash column should right click to VT + */ LET ColumnTypes = dict(`StartDate`='timestamp') - SELECT Hex, StartDate + SELECT Hex, StartDate, hash(accessor="data", path="Hello") AS Hash FROM source() diff --git a/artifacts/definitions/MacOS/Forensics/FSEvents.yaml b/artifacts/definitions/MacOS/Forensics/FSEvents.yaml new file mode 100644 index 0000000000..25d2ede67f --- /dev/null +++ b/artifacts/definitions/MacOS/Forensics/FSEvents.yaml @@ -0,0 +1,94 @@ +name: MacOS.Forensics.FSEvents +description: | + This artifact parses the FSEvents log files. + +reference: +- https://www.osdfcon.org/presentations/2017/Ibrahim-Understanding-MacOS-File-Ststem-Events-with-FSEvents-Parser.pdf + +type: CLIENT + +parameters: + - name: GlobTable + type: csv + default: | + Glob + /.fseventsd/* + /System/Volumes/Data/.fseventsd/* + - name: Glob + type: string + description: Instead of providing the globs in a table, a single glob may e given. + - name: PathRegex + description: Filter the path by this regexp + default: . + type: regex + - name: FlagsRegex + description: Filter by flags + type: regex + default: . +export: | + LET FSEventProfile = '''[ + ["Header", 0, [ + ["Signature", 0, "String", { + length: 4 + }], + ["StreamSize", 8, uint32], + ["Items", 12, "Array", { + count: 10000, + max_count: 10000, + type: FSEventEntry, + sentinel: "x=>len(list=x.path) = 0", + }] + ]], + ["FSEventEntry", "x=>len(list=x.path) + 21", [ + ["path", 0, "String"], + ["id", "x=>len(list=x.path) + 1", "uint64"], + ["flags", "x=>len(list=x.path) + 9", "Flags", { + type: "uint32", + bitmap: { + FSE_CREATE_FILE: 0, + FSE_DELETE: 1, + FSE_STAT_CHANGED: 2, + FSE_RENAME: 3, + FSE_CONTENT_MODIFIED: 4, + FSE_EXCHANGE: 5, + FSE_FINDER_INFO_CHANGED: 6, + FSE_CREATE_DIR: 7, + FSE_CHOWN: 8, + FSE_XATTR_MODIFIED: 9, + FSE_XATTR_REMOVED: 10, + FSE_DOCID_CREATED: 11, + FSE_DOCID_CHANGED: 12, + FSE_UNMOUNT_PENDING: 13, + FSE_CLONE: 14, + FSE_MODE_CLONE: 16, + FSE_TRUNCATED_PATH: 17, + FSE_REMOTE_DIR_EVENT: 18, + FSE_MODE_LAST_HLINK: 19, + FSE_MODE_HLINK: 20, + IsSymbolicLink: 22, + IsFile: 23, + IsDirectory: 24, + Mount: 25, + Unmount: 26, + EndOfTransaction: 29 + } + }], + ]] + ]''' + +sources: + - query: | + LET files = SELECT OSPath, Mtime + FROM glob(globs=(Glob || GlobTable.Glob)) + WHERE log(message=OSPath) + + SELECT * FROM foreach(row=files, + query={ + SELECT OSPath.Basename AS File, Mtime, path, + id, join(array=flags, sep=", ") AS flags + FROM foreach(row=parse_binary( + filename=read_file(filename=OSPath, accessor="gzip", length=1000000), + accessor="data", + profile=FSEventProfile, struct="Header").Items) + }) + WHERE path =~ PathRegex AND flags =~ FlagsRegex diff --git a/artifacts/definitions/Server/Import/PreviousReleases.yaml b/artifacts/definitions/Server/Import/PreviousReleases.yaml index 400d5ea842..b537de3214 100644 --- a/artifacts/definitions/Server/Import/PreviousReleases.yaml +++ b/artifacts/definitions/Server/Import/PreviousReleases.yaml @@ -23,13 +23,14 @@ parameters: description: | The Velociraptor Release to import. type: choices - default: v0.6.4 + default: v0.6.5 choices: - v0.6.0 - v0.6.1 - v0.6.2 - v0.6.3 - v0.6.4 + - v0.6.5 sources: - query: | diff --git a/artifacts/definitions/Windows/Carving/CobaltStrike.yaml b/artifacts/definitions/Windows/Carving/CobaltStrike.yaml index f7dccc50a1..52bd2cb1ea 100644 --- a/artifacts/definitions/Windows/Carving/CobaltStrike.yaml +++ b/artifacts/definitions/Windows/Carving/CobaltStrike.yaml @@ -436,7 +436,7 @@ sources: -- function to extract potential additional encoded PE in data section - LET embedded_section(path,type) = SELECT + LET embedded_section(path,type) = SELECT path as OriginalFileName, _value.Name as Name, _value.Size as Size, @@ -473,16 +473,29 @@ sources: FullPath,Size, 'Embedded data section: ' + Rule as Rule, substr(start=0,end=1,str=String.Data) as Xor, - read_file(accessor='data',filename=File.FullPath,offset=String.Offset,length=ExtractBytes) as _Data - FROM yara(files=parse_binary(accessor='data',filename= embedded_section(path=TargetBytes,type='data')[0].Data,profile=PROFILE,struct="EmbeddedPE").DecodedPayload, accessor='data', rules=FindConfig, number=99) + read_file(accessor='data', + filename=File.FullPath, + offset=String.Offset, + length=ExtractBytes) as _Data + FROM yara(files=parse_binary( + accessor='data', + filename= embedded_section(path=TargetBytes,type='data')[0].Data, + profile=PROFILE, + struct="EmbeddedPE").DecodedPayload, + accessor='data', rules=FindConfig, number=99) }, section_encoded_stager = { - SELECT + SELECT FullPath,Size, '' as Xor, 'Embedded data section: ' + Rule as Rule, read_file(accessor='data',filename=File.FullPath) as _Data - FROM yara(files=parse_binary(accessor='data',filename= embedded_section(path=TargetBytes,type='data')[0].Data,profile=PROFILE,struct="EmbeddedPE").DecodedPayload, accessor='data', rules=FindShellcode, number=99) + FROM yara(files=parse_binary( + accessor='data', + filename= embedded_section(path=TargetBytes,type='data')[0].Data, + profile=PROFILE, + struct="EmbeddedPE").DecodedPayload, + accessor='data', rules=FindShellcode, number=99) }, sleepfunction = { SELECT *, '' as Xor, @@ -493,7 +506,7 @@ sources: }) -- find target files - LET TargetFiles = SELECT FullPath,Size + LET TargetFiles = SELECT OSPath AS FullPath,Size FROM glob(globs=TargetFileGlob) WHERE NOT IsDir @@ -505,7 +518,7 @@ sources: FullPath, Size, hash(path=FullPath) as Hash, Xor,_Data, - Rule + '|' + FullPath as _Group + Rule + '|' + FullPath.String as _Group FROM switch( -- switchcase will find beacon as priority, then search for shellcode beacon = { SELECT *, @@ -523,16 +536,29 @@ sources: FullPath,Size, 'Embedded data section: ' + Rule as Rule, substr(start=0,end=1,str=String.Data) as Xor, - read_file(accessor='data',filename=File.FullPath,offset=String.Offset,length=ExtractBytes) as _Data - FROM yara(files=parse_binary(accessor='data',filename= embedded_section(path=FullPath,type='auto')[0].Data,profile=PROFILE,struct="EmbeddedPE").DecodedPayload, accessor='data', rules=FindConfig, number=99) + read_file(accessor='data',filename=File.OSPath, + offset=String.Offset,length=ExtractBytes) as _Data + FROM yara(files=parse_binary( + accessor='data', + filename= embedded_section(path=FullPath,type='auto')[0].Data, + profile=PROFILE, + struct="EmbeddedPE").DecodedPayload, + accessor='data', rules=FindConfig, number=99) }, section_encoded_stager = { - SELECT + SELECT FullPath,Size, '' as Xor, 'Embedded data section: ' + Rule as Rule, - read_file(accessor='data',filename=File.FullPath,length=ExtractBytes) as _Data - FROM yara(files=parse_binary(accessor='data',filename= embedded_section(path=FullPath,type='auto')[0].Data,profile=PROFILE,struct="EmbeddedPE").DecodedPayload, accessor='data', rules=FindShellcode, number=99) + read_file(accessor='data', + filename=File.FullPath, + length=ExtractBytes) as _Data + FROM yara(files=parse_binary( + accessor='data', + filename= embedded_section(path=FullPath,type='auto')[0].Data, + profile=PROFILE, + struct="EmbeddedPE").DecodedPayload, + accessor='data', rules=FindShellcode, number=99) }, sleepfunction = { SELECT *, '' as Xor, @@ -633,13 +659,13 @@ sources: else=_Data)) as DecodedData FROM results - LET cleanup(config) = to_dict(item= - { - SELECT _key, _value - FROM items(item=config) + LET cleanup(config) = to_dict(item= + { + SELECT _key, _value + FROM items(item=config) WHERE NOT _key =~ '^__' AND ( _value OR _key =~ '^license' ) }) - + -- output rows, standard config priority, exclude _Data SELECT *, if(condition= format(format='%T',args=DecodedConfig)='string', @@ -656,4 +682,4 @@ sources: then= output_decoded_data, else= results) GROUP BY _Group - }, exclude=["_Data","_Group"]) \ No newline at end of file + }, exclude=["_Data","_Group"]) diff --git a/artifacts/definitions/Windows/NTFS/MFT.yaml b/artifacts/definitions/Windows/NTFS/MFT.yaml index ff64c1abb0..f32b26a072 100644 --- a/artifacts/definitions/Windows/NTFS/MFT.yaml +++ b/artifacts/definitions/Windows/NTFS/MFT.yaml @@ -14,23 +14,23 @@ description: | MFT artifact. Due to the multi-drive features, the MFTPath will output the MFT path of the entry. - Available filters include: - - - PathRegex (OSPath): e.g `^C:\\folder\\file\.ext$` or partial `\\folder\\folder2\\` or `string|string2|string3` - - Fileregex: `^filename.ext$` or partial `string1|string2` - - Time bounds to select files with a timestamp within time ranges - - FileSize bounds - - MFTDrive: drive to target collection and show as source in results during offline pricessing. - - MFTPath: optional filter for offline MFT processing. - - NOTE: Generally more efficient to filter on filename. + Available filters include: + + - PathRegex (OSPath): e.g `^C:\\folder\\file\.ext$` or partial `\\folder\\folder2\\` or `string|string2|string3` + - Fileregex: `^filename.ext$` or partial `string1|string2` + - Time bounds to select files with a timestamp within time ranges + - FileSize bounds + - MFTDrive: drive to target collection and show as source in results during offline pricessing. + - MFTPath: optional filter for offline MFT processing. + + NOTE: Generally more efficient to filter on filename. Multiple filters are cumulative. OSPath output now uses expected Windows backslash "`\`". - + parameters: - name: MFTDrive description: | - The path to to the drive that holds the MFT file (can be a pathspec). This + The path to to the drive that holds the MFT file (can be a pathspec). This drive is also used for results for offline processing. default: "C:" - name: MFTPath @@ -67,7 +67,7 @@ parameters: sources: - query: | - -- The path to to the drive that holds the MFT file (can be a pathspec) + -- The path to to the drive that holds the M}FT file (can be a pathspec) LET Drive <= pathspec(parse=MFTDrive, path_type="windows") -- time testing @@ -96,9 +96,9 @@ sources: SELECT EntryNumber, InUse, ParentEntryNumber, Drive + OSPath AS OSPath, FileName, FileSize, ReferenceCount, IsDir, - Created0x10, Created0x30, + Created0x10, Created0x30, LastModified0x10, LastModified0x30, - LastRecordChange0x10, LastRecordChange0x30, + LastRecordChange0x10, LastRecordChange0x30, LastAccess0x10,LastAccess0x30, HasADS, SI_Lt_FN, uSecZeros, Copied, FileNames, FileNameTypes @@ -108,13 +108,13 @@ sources: -- Check only one date bound LET mftsearch_after_date(Drive, MFTPath) = - SELECT + SELECT EntryNumber, InUse, ParentEntryNumber, Drive + OSPath AS OSPath, FileName, FileSize, ReferenceCount, IsDir, - Created0x10, Created0x30, + Created0x10, Created0x30, LastModified0x10, LastModified0x30, - LastRecordChange0x10, LastRecordChange0x30, + LastRecordChange0x10, LastRecordChange0x30, LastAccess0x10,LastAccess0x30, HasADS, SI_Lt_FN, uSecZeros, Copied, FileNames, FileNameTypes @@ -133,9 +133,9 @@ sources: SELECT EntryNumber, InUse, ParentEntryNumber, Drive + OSPath AS OSPath, FileName, FileSize, ReferenceCount, IsDir, - Created0x10, Created0x30, + Created0x10, Created0x30, LastModified0x10, LastModified0x30, - LastRecordChange0x10, LastRecordChange0x30, + LastRecordChange0x10, LastRecordChange0x30, LastAccess0x10,LastAccess0x30, HasADS, SI_Lt_FN, uSecZeros, Copied, FileNames, FileNameTypes @@ -155,9 +155,9 @@ sources: SELECT EntryNumber, InUse, ParentEntryNumber, Drive + OSPath AS OSPath, FileName, FileSize, ReferenceCount, IsDir, - Created0x10, Created0x30, + Created0x10, Created0x30, LastModified0x10, LastModified0x30, - LastRecordChange0x10, LastRecordChange0x30, + LastRecordChange0x10, LastRecordChange0x30, LastAccess0x10,LastAccess0x30, HasADS, SI_Lt_FN, uSecZeros, Copied, FileNames, FileNameTypes @@ -221,7 +221,7 @@ sources: SELECT * FROM all_drives }, else={ - SELECT * FROM mftsearch(Drive=Drive, + SELECT * FROM mftsearch(Drive=Drive, MFTPath=if(condition= MFTPath , then= MFTPath, else= Drive + "$MFT")) @@ -230,8 +230,8 @@ sources: LET enriched_results = SELECT *, parse_ntfs(mft=EntryNumber, device=Drive ) as NtfsMetadata FROM results - + -- return rows SELECT * FROM if(condition=AllNtfs, then= enriched_results, - else= results) \ No newline at end of file + else= results) diff --git a/artifacts/testdata/files/fs_events_00000000007cff3d b/artifacts/testdata/files/fs_events_00000000007cff3d new file mode 100644 index 0000000000000000000000000000000000000000..113b80f1653214ef53969bfc7f478f1a551cdb8f GIT binary patch literal 70 zcmb2|=3oE=VI!Vzg&)7@?a4fP;J||EVRNFU%?b~ivnYPf;@NZNM^A`26cBp)2m@;m X&sB~-C7_o7|Ct#k&6*u&1!MyN-R&E> literal 0 HcmV?d00001 diff --git a/artifacts/testdata/server/testcases/cobalt.in.yaml b/artifacts/testdata/server/testcases/cobalt.in.yaml index e8e524c4f4..43ea592b60 100644 --- a/artifacts/testdata/server/testcases/cobalt.in.yaml +++ b/artifacts/testdata/server/testcases/cobalt.in.yaml @@ -17,9 +17,8 @@ Queries: - SELECT Rule, relpath(path=FullPath, base=srcDir, sep="/") as FullPath,Hash,Xor,DecodedConfig FROM Artifact.Windows.Carving.CobaltStrike(TargetFileGlob=srcDir + "/artifacts/testdata/files/CSx86sleep.bin") - # tests embedded shellcode in data section parsing - - SELECT Rule,FullPath,Hash,Xor,DecodedConfig + - SELECT Rule,FullPath.Basename,Hash,Xor,DecodedConfig FROM Artifact.Windows.Carving.CobaltStrike(TargetFileGlob=srcDir+"/artifacts/testdata/files/CSsectionStager.exe") # Use byte scanning of the raw file. diff --git a/artifacts/testdata/server/testcases/cobalt.out.yaml b/artifacts/testdata/server/testcases/cobalt.out.yaml index 60176e2fb9..1075ba137b 100644 --- a/artifacts/testdata/server/testcases/cobalt.out.yaml +++ b/artifacts/testdata/server/testcases/cobalt.out.yaml @@ -170,10 +170,10 @@ SELECT Rule, relpath(path=FullPath, base=srcDir, sep="/") as FullPath,Hash,Xor,D "Xor": "0x00", "DecodedConfig": "Sleep mask 32-bit 4.2 deobfuscation routine found." } -]SELECT Rule,FullPath,Hash,Xor,DecodedConfig FROM Artifact.Windows.Carving.CobaltStrike(TargetFileGlob=srcDir+"/artifacts/testdata/files/CSsectionStager.exe")[ +]SELECT Rule,FullPath.Basename,Hash,Xor,DecodedConfig FROM Artifact.Windows.Carving.CobaltStrike(TargetFileGlob=srcDir+"/artifacts/testdata/files/CSsectionStager.exe")[ { "Rule": "Embedded data section: cobalt_strike_shellcode", - "FullPath": "X:\\artifacts\\testdata\\files\\CSsectionStager.exe", + "FullPath.Basename": "CSsectionStager.exe", "Hash": { "MD5": "12dd068bb362a3ef64fc0b19ad752ed5", "SHA1": "184bb361cec7fcc10b1ab98d7f9aa0eb05e2ce35", diff --git a/artifacts/testdata/server/testcases/macos.in.yaml b/artifacts/testdata/server/testcases/macos.in.yaml index f87ebc2d15..d9b48bf97a 100644 --- a/artifacts/testdata/server/testcases/macos.in.yaml +++ b/artifacts/testdata/server/testcases/macos.in.yaml @@ -10,3 +10,6 @@ Queries: }) FROM scope() - SELECT * FROM Artifact.MacOS.System.Packages() + + - SELECT File, path, id, flags + FROM Artifact.MacOS.Forensics.FSEvents(Glob=srcDir+"/artifacts/testdata/files/fs_events_*") diff --git a/artifacts/testdata/server/testcases/macos.out.yaml b/artifacts/testdata/server/testcases/macos.out.yaml index fedf351e57..a2fd26caeb 100644 --- a/artifacts/testdata/server/testcases/macos.out.yaml +++ b/artifacts/testdata/server/testcases/macos.out.yaml @@ -21,4 +21,11 @@ SELECT OSPath.Basename, Content.home FROM Artifact.MacOS.System.Plist( PlistGlob "Name": "Slack", "_Source": "MacOS.System.Packages" } +]SELECT File, path, id, flags FROM Artifact.MacOS.Forensics.FSEvents(Glob=srcDir+"/artifacts/testdata/files/fs_events_*")[ + { + "File": "fs_events_00000000007cff3d", + "path": ".fseventsd/sl-compat", + "id": 163194, + "flags": "IsDirectory" + } ] \ No newline at end of file diff --git a/artifacts/testdata/server/testcases/orgs.in.yaml b/artifacts/testdata/server/testcases/orgs.in.yaml index 5c6296d859..61cb77097f 100644 --- a/artifacts/testdata/server/testcases/orgs.in.yaml +++ b/artifacts/testdata/server/testcases/orgs.in.yaml @@ -133,3 +133,6 @@ Queries: FROM glob(globs="/**", accessor="fs") WHERE OSPath =~ "file.txt" }, org_id="ORGID2") + +- LET _ <= org_delete(org="ORGID2") +- SELECT OrgId FROM orgs() diff --git a/artifacts/testdata/server/testcases/orgs.out.yaml b/artifacts/testdata/server/testcases/orgs.out.yaml index 6e8052e992..3de5a72b23 100644 --- a/artifacts/testdata/server/testcases/orgs.out.yaml +++ b/artifacts/testdata/server/testcases/orgs.out.yaml @@ -1,20 +1,20 @@ SELECT Name, OrgId FROM orgs() ORDER BY OrgId[ { - "Name": "\u003croot org\u003e", - "OrgId": "" + "Name": "\u003croot\u003e", + "OrgId": "root" } ]LET _ <= user_create(user="FailedUser", roles="reader", password="X", orgs=["ORGID"])[]SELECT * FROM test_read_logs() WHERE Log =~ "Org not found" AND NOT Log =~ "SELECT"[ { "Log": "Velociraptor: user_create: Org not found\n" } ]SELECT * FROM gui_users(all_orgs=TRUE) ORDER BY name[]LET _ <= org_create(name="MyOrg", org_id="ORGID")[]SELECT Name, OrgId FROM orgs() ORDER BY OrgId[ - { - "Name": "\u003croot org\u003e", - "OrgId": "" - }, { "Name": "MyOrg", "OrgId": "ORGID" + }, + { + "Name": "\u003croot\u003e", + "OrgId": "root" } ]SELECT user_create(user="ReaderUser", roles="reader", password="X", orgs=["root", "ORGID"]), user_create(user="OrgUser", roles="administrator", password="X", orgs=["ORGID"]), user_create(user="OrgAdmin", roles="administrator", password="X") FROM scope()[ { @@ -25,8 +25,8 @@ SELECT Name, OrgId FROM orgs() ORDER BY OrgId[ ]SELECT * FROM gui_users(all_orgs=TRUE) ORDER BY name[ { "name": "OrgAdmin", - "org_id": "", - "org_name": "\u003croot org\u003e", + "org_id": "root", + "org_name": "\u003croot\u003e", "picture": "", "email": false, "roles": [ @@ -82,8 +82,8 @@ SELECT Name, OrgId FROM orgs() ORDER BY OrgId[ }, { "name": "ReaderUser", - "org_id": "", - "org_name": "\u003croot org\u003e", + "org_id": "root", + "org_name": "\u003croot\u003e", "picture": "", "email": false, "roles": [ @@ -109,8 +109,8 @@ SELECT Name, OrgId FROM orgs() ORDER BY OrgId[ ]SELECT * FROM gui_users() ORDER BY name[ { "name": "OrgAdmin", - "org_id": "", - "org_name": "\u003croot org\u003e", + "org_id": "root", + "org_name": "\u003croot\u003e", "picture": "", "email": false, "roles": [ @@ -138,8 +138,8 @@ SELECT Name, OrgId FROM orgs() ORDER BY OrgId[ }, { "name": "ReaderUser", - "org_id": "", - "org_name": "\u003croot org\u003e", + "org_id": "root", + "org_name": "\u003croot\u003e", "picture": "", "email": false, "roles": [ @@ -197,10 +197,10 @@ SELECT Name, OrgId FROM orgs() ORDER BY OrgId[ } ]SELECT * FROM query(query={ SELECT OrgId FROM orgs() ORDER BY OrgId }, runas="OrgAdmin", org_id="root")[ { - "OrgId": "" + "OrgId": "ORGID" }, { - "OrgId": "ORGID" + "OrgId": "root" } ]SELECT * FROM query(query={ SELECT OrgId FROM orgs() ORDER BY OrgId }, runas="OrgUser", org_id="ORGID")[]SELECT * FROM test_read_logs() WHERE Log =~ "Permission denied.+ORG_ADMIN" AND NOT Log =~ "SELECT"[ { @@ -300,4 +300,11 @@ SELECT Name, OrgId FROM orgs() ORDER BY OrgId[ "OSPath": "fs:/clients/C.123/uploads/ORG2_file.txt", "PathHasORGID": true } +]LET _ <= org_delete(org="ORGID2")[]SELECT OrgId FROM orgs()[ + { + "OrgId": "root" + }, + { + "OrgId": "ORGID" + } ] \ No newline at end of file diff --git a/bin/config.go b/bin/config.go index 145404ec31..6de3d00c3f 100644 --- a/bin/config.go +++ b/bin/config.go @@ -1,5 +1,3 @@ -// +build !aix - /* Velociraptor - Dig Deeper Copyright (C) 2019-2022 Rapid7 Inc. @@ -47,8 +45,8 @@ var ( config_command = app.Command( "config", "Manipulate the configuration.") - config_command_org = config_command.Flag("org", "Org ID to show"). - String() + config_command_org = config_command.Flag( + "org", "Org ID to show").String() config_show_command = config_command.Command( "show", "Show the current config.") @@ -115,7 +113,6 @@ func maybeGetOrgConfig( org_id string, config_obj *config_proto.Config) ( *config_proto.Config, error) { - // For for proper initialization to catch bugs earlier. org_manager, err := services.GetOrgManager() if err != nil { return config_obj, err diff --git a/bin/frontend.go b/bin/frontend.go index 31cf06cc05..26be517ca8 100644 --- a/bin/frontend.go +++ b/bin/frontend.go @@ -21,6 +21,7 @@ import ( "fmt" "github.com/sirupsen/logrus" + "www.velocidex.com/golang/velociraptor/config" assets "www.velocidex.com/golang/velociraptor/gui/velociraptor" "www.velocidex.com/golang/velociraptor/logging" "www.velocidex.com/golang/velociraptor/server" @@ -58,6 +59,7 @@ func doFrontend() error { WithRequiredUser(). WithRequiredLogging().LoadAndValidate() if err != nil { + logging.FlushPrelogs(config.GetDefaultConfig()) return fmt.Errorf("loading config file: %w", err) } diff --git a/bin/orgs.go b/bin/orgs.go index 2c29b37182..9a5d43d57e 100644 --- a/bin/orgs.go +++ b/bin/orgs.go @@ -5,6 +5,7 @@ import ( api_proto "www.velocidex.com/golang/velociraptor/api/proto" "www.velocidex.com/golang/velociraptor/json" + logging "www.velocidex.com/golang/velociraptor/logging" "www.velocidex.com/golang/velociraptor/services" "www.velocidex.com/golang/velociraptor/startup" ) @@ -18,6 +19,9 @@ var ( orgs_create_name = orgs_create.Arg("name", "Name of the new org").Required().String() + orgs_delete = orgs_command.Command("rm", "Delete an org") + orgs_delete_org_id = orgs_delete.Arg("org_id", "Id of org to remove").Required().String() + orgs_user_add = orgs_command.Command("user_add", "Add a user to the org") orgs_user_add_org = orgs_user_add.Arg("org_id", "Org ID to add user to"). Required().String() @@ -33,6 +37,7 @@ func doOrgLs() error { if err != nil { return fmt.Errorf("loading config file: %w", err) } + config_obj.Frontend.ServerServices = services.GenericToolServices() ctx, cancel := install_sig_handler() defer cancel() @@ -64,6 +69,7 @@ func doOrgUserAdd() error { if err != nil { return fmt.Errorf("loading config file: %w", err) } + config_obj.Frontend.ServerServices = services.GenericToolServices() ctx, cancel := install_sig_handler() defer cancel() @@ -109,6 +115,8 @@ func doOrgCreate() error { return fmt.Errorf("loading config file: %w", err) } + config_obj.Frontend.ServerServices = services.GenericToolServices() + ctx, cancel := install_sig_handler() defer cancel() @@ -134,6 +142,38 @@ func doOrgCreate() error { return nil } +func doOrgDelete() error { + config_obj, err := makeDefaultConfigLoader(). + WithRequiredFrontend(). + WithRequiredUser(). + WithRequiredLogging().LoadAndValidate() + if err != nil { + return fmt.Errorf("loading config file: %w", err) + } + + config_obj.Frontend.ServerServices = services.GenericToolServices() + + ctx, cancel := install_sig_handler() + defer cancel() + + sm, err := startup.StartToolServices(ctx, config_obj) + defer sm.Close() + + if err != nil { + return err + } + + org_manager, err := services.GetOrgManager() + if err != nil { + return err + } + + logger := logging.GetLogger(config_obj, &logging.ToolComponent) + logger.Info("Will remove org %v\n", *orgs_delete_org_id) + + return org_manager.DeleteOrg(*orgs_delete_org_id) +} + func init() { command_handlers = append(command_handlers, func(command string) bool { switch command { @@ -143,6 +183,9 @@ func init() { case orgs_create.FullCommand(): FatalIfError(orgs_create, doOrgCreate) + case orgs_delete.FullCommand(): + FatalIfError(orgs_delete, doOrgDelete) + case orgs_user_add.FullCommand(): FatalIfError(orgs_user_add, doOrgUserAdd) diff --git a/config/proto/config.pb.go b/config/proto/config.pb.go index 96ac911ffe..14cbe2b851 100644 --- a/config/proto/config.pb.go +++ b/config/proto/config.pb.go @@ -871,8 +871,20 @@ type GUILink struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Text string `protobuf:"bytes,1,opt,name=text,proto3" json:"text,omitempty"` - Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"` + Text string `protobuf:"bytes,1,opt,name=text,proto3" json:"text,omitempty"` + Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"` + IconUrl string `protobuf:"bytes,3,opt,name=icon_url,json=iconUrl,proto3" json:"icon_url,omitempty"` + // This can be "sidebar" (default), "context" + Type string `protobuf:"bytes,4,opt,name=type,proto3" json:"type,omitempty"` + // If set we open in new tab + NewTab bool `protobuf:"varint,5,opt,name=new_tab,json=newTab,proto3" json:"new_tab,omitempty"` + // Encode value first using this (can be "plain", "base64") + Encode string `protobuf:"bytes,6,opt,name=encode,proto3" json:"encode,omitempty"` + Parameter string `protobuf:"bytes,7,opt,name=parameter,proto3" json:"parameter,omitempty"` + // Can be GET (default) or POST + Method string `protobuf:"bytes,8,opt,name=method,proto3" json:"method,omitempty"` + // If set we ignore this entry completely + Disabled bool `protobuf:"varint,9,opt,name=disabled,proto3" json:"disabled,omitempty"` } func (x *GUILink) Reset() { @@ -921,6 +933,55 @@ func (x *GUILink) GetUrl() string { return "" } +func (x *GUILink) GetIconUrl() string { + if x != nil { + return x.IconUrl + } + return "" +} + +func (x *GUILink) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *GUILink) GetNewTab() bool { + if x != nil { + return x.NewTab + } + return false +} + +func (x *GUILink) GetEncode() string { + if x != nil { + return x.Encode + } + return "" +} + +func (x *GUILink) GetParameter() string { + if x != nil { + return x.Parameter + } + return "" +} + +func (x *GUILink) GetMethod() string { + if x != nil { + return x.Method + } + return "" +} + +func (x *GUILink) GetDisabled() bool { + if x != nil { + return x.Disabled + } + return false +} + type Authenticator struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1100,8 +1161,9 @@ type GUIConfig struct { PublicUrl string `protobuf:"bytes,7,opt,name=public_url,json=publicUrl,proto3" json:"public_url,omitempty"` ReverseProxy []*ReverseProxyConfig `protobuf:"bytes,8,rep,name=reverse_proxy,json=reverseProxy,proto3" json:"reverse_proxy,omitempty"` Links []*GUILink `protobuf:"bytes,9,rep,name=links,proto3" json:"links,omitempty"` - // These users are created if they do no already exist in the data - // store. + // These users are created with administrator role if they do not + // already exist in the data store. This is useful for + // initializing the server with some valid administrators. InitialUsers []*GUIUser `protobuf:"bytes,17,rep,name=initial_users,json=initialUsers,proto3" json:"initial_users,omitempty"` // The authenticator to use - can not be null. Authenticator *Authenticator `protobuf:"bytes,19,opt,name=authenticator,proto3" json:"authenticator,omitempty"` @@ -3915,799 +3977,811 @@ var file_config_proto_rawDesc = []byte{ 0x65, 0x6e, 0x74, 0x2e, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x70, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x70, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x2f, 0x0a, 0x07, 0x47, 0x55, 0x49, 0x4c, - 0x69, 0x6e, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x74, 0x65, 0x78, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x84, 0x08, 0x0a, 0x0d, 0x41, 0x75, - 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, - 0xb9, 0x01, 0x0a, 0x0b, 0x6f, 0x69, 0x64, 0x63, 0x5f, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x97, 0x01, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x90, 0x01, 0x12, - 0x8d, 0x01, 0x55, 0x52, 0x4c, 0x20, 0x74, 0x6f, 0x20, 0x4f, 0x49, 0x44, 0x43, 0x20, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x44, 0x6f, 0x63, 0x75, - 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, - 0x65, 0x20, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x27, 0x6f, 0x69, 0x64, 0x63, 0x5f, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x20, - 0x2b, 0x20, 0x2f, 0x2e, 0x77, 0x65, 0x6c, 0x6c, 0x2d, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x2f, 0x6f, - 0x70, 0x65, 0x6e, 0x69, 0x64, 0x2d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x27, 0x20, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x2e, 0x20, 0x52, - 0x0a, 0x6f, 0x69, 0x64, 0x63, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x6f, - 0x69, 0x64, 0x63, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x6f, 0x69, 0x64, 0x63, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, - 0x61, 0x72, 0x18, 0x13, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, - 0x12, 0x58, 0x0a, 0x0f, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x30, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, - 0x2a, 0x12, 0x28, 0x49, 0x66, 0x20, 0x73, 0x65, 0x74, 0x20, 0x77, 0x65, 0x20, 0x75, 0x73, 0x65, - 0x20, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x20, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x52, 0x0d, 0x6f, 0x61, 0x75, - 0x74, 0x68, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x60, 0x0a, 0x13, 0x6f, 0x61, - 0x75, 0x74, 0x68, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, - 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x42, 0x30, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x2a, 0x12, - 0x28, 0x49, 0x66, 0x20, 0x73, 0x65, 0x74, 0x20, 0x77, 0x65, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, - 0x61, 0x75, 0x74, 0x68, 0x20, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x52, 0x11, 0x6f, 0x61, 0x75, 0x74, 0x68, - 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x16, 0x0a, 0x06, - 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x65, - 0x6e, 0x61, 0x6e, 0x74, 0x12, 0x44, 0x0a, 0x10, 0x73, 0x61, 0x6d, 0x6c, 0x5f, 0x63, 0x65, 0x72, - 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x42, 0x19, - 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x13, 0x12, 0x11, 0x53, 0x41, 0x4d, 0x4c, 0x20, 0x63, 0x65, 0x72, - 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x0f, 0x73, 0x61, 0x6d, 0x6c, 0x43, - 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x43, 0x0a, 0x10, 0x73, 0x61, - 0x6d, 0x6c, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x0d, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x19, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x13, 0x12, 0x11, 0x53, 0x41, - 0x4d, 0x4c, 0x20, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x2e, 0x52, - 0x0e, 0x73, 0x61, 0x6d, 0x6c, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, - 0x5f, 0x0a, 0x15, 0x73, 0x61, 0x6d, 0x6c, 0x5f, 0x69, 0x64, 0x70, 0x5f, 0x6d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2c, - 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x26, 0x12, 0x24, 0x53, 0x41, 0x4d, 0x4c, 0x20, 0x69, 0x64, 0x65, - 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x20, 0x6d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x20, 0x55, 0x52, 0x4c, 0x2e, 0x52, 0x12, 0x73, 0x61, - 0x6d, 0x6c, 0x49, 0x64, 0x70, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x55, 0x72, 0x6c, - 0x12, 0x3a, 0x0a, 0x0d, 0x73, 0x61, 0x6d, 0x6c, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x75, 0x72, - 0x6c, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x42, 0x16, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x10, 0x12, - 0x0e, 0x53, 0x41, 0x4d, 0x4c, 0x20, 0x72, 0x6f, 0x6f, 0x74, 0x20, 0x55, 0x52, 0x4c, 0x2e, 0x52, - 0x0b, 0x73, 0x61, 0x6d, 0x6c, 0x52, 0x6f, 0x6f, 0x74, 0x55, 0x72, 0x6c, 0x12, 0x70, 0x0a, 0x13, - 0x73, 0x61, 0x6d, 0x6c, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x42, 0x40, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, - 0x3a, 0x12, 0x38, 0x53, 0x41, 0x4d, 0x4c, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x69, 0x64, 0x65, 0x6e, - 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x11, 0x73, 0x61, 0x6d, - 0x6c, 0x55, 0x73, 0x65, 0x72, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x43, - 0x0a, 0x12, 0x73, 0x75, 0x62, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, - 0x74, 0x6f, 0x72, 0x73, 0x18, 0x11, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, - 0x52, 0x11, 0x73, 0x75, 0x62, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, - 0x6f, 0x72, 0x73, 0x12, 0x3b, 0x0a, 0x1a, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x73, - 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x5f, 0x6d, 0x69, - 0x6e, 0x18, 0x14, 0x20, 0x01, 0x28, 0x04, 0x52, 0x17, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, - 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x70, 0x69, 0x72, 0x79, 0x4d, 0x69, 0x6e, - 0x22, 0xf0, 0x0c, 0x0a, 0x09, 0x47, 0x55, 0x49, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x98, - 0x01, 0x0a, 0x0c, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x75, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x6f, 0x12, 0x6d, 0x41, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x69, 0x6e, 0x64, 0x20, 0x47, - 0x55, 0x49, 0x20, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x2e, 0x20, 0x54, 0x68, 0x69, - 0x73, 0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x75, 0x73, 0x75, 0x61, 0x6c, 0x6c, 0x79, - 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x62, 0x65, 0x20, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, - 0x2e, 0x31, 0x2c, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x77, 0x69, 0x73, 0x65, 0x20, 0x62, 0x65, - 0x20, 0x73, 0x75, 0x72, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x6c, - 0x79, 0x20, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x69, 0x74, 0x2e, 0x52, 0x0b, 0x62, 0x69, - 0x6e, 0x64, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x35, 0x0a, 0x09, 0x62, 0x69, 0x6e, - 0x64, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x18, 0xe2, 0xfc, - 0xe3, 0xc4, 0x01, 0x12, 0x12, 0x10, 0x50, 0x6f, 0x72, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x69, - 0x6e, 0x64, 0x20, 0x74, 0x6f, 0x2e, 0x52, 0x08, 0x62, 0x69, 0x6e, 0x64, 0x50, 0x6f, 0x72, 0x74, - 0x12, 0x24, 0x0a, 0x0e, 0x75, 0x73, 0x65, 0x5f, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x5f, 0x68, 0x74, - 0x74, 0x70, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x75, 0x73, 0x65, 0x50, 0x6c, 0x61, - 0x69, 0x6e, 0x48, 0x74, 0x74, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x70, - 0x61, 0x74, 0x68, 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x61, 0x73, 0x65, 0x50, - 0x61, 0x74, 0x68, 0x12, 0xc3, 0x01, 0x0a, 0x0e, 0x67, 0x77, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x42, 0x9b, 0x01, 0xe2, - 0xfc, 0xe3, 0xc4, 0x01, 0x94, 0x01, 0x12, 0x91, 0x01, 0x54, 0x68, 0x65, 0x20, 0x47, 0x55, 0x49, - 0x20, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x73, 0x20, 0x61, 0x20, 0x48, 0x54, 0x54, 0x50, 0x20, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x67, 0x52, 0x50, 0x43, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x2e, - 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x65, 0x72, 0x74, - 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x72, 0x69, 0x76, - 0x61, 0x74, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x77, 0x69, 0x6c, - 0x6c, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x6f, 0x6e, - 0x6e, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x67, 0x52, 0x50, 0x43, - 0x20, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x2e, 0x52, 0x0d, 0x67, 0x77, 0x43, 0x65, - 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x6b, 0x0a, 0x0e, 0x67, 0x77, 0x5f, - 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x0b, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x45, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x3f, 0x12, 0x3d, 0x54, 0x68, 0x65, 0x20, 0x70, - 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x50, 0x45, 0x4d, - 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x52, 0x0c, 0x67, 0x77, 0x50, 0x72, 0x69, 0x76, - 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x97, 0x01, 0x0a, 0x0d, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x5f, 0x63, 0x69, 0x64, 0x72, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x42, 0x72, - 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x6c, 0x12, 0x6a, 0x43, 0x49, 0x44, 0x52, 0x20, 0x61, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, - 0x61, 0x6c, 0x20, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x20, 0x28, 0x65, 0x2e, 0x67, - 0x2e, 0x20, 0x31, 0x39, 0x32, 0x2e, 0x31, 0x36, 0x38, 0x2e, 0x30, 0x2e, 0x30, 0x2f, 0x31, 0x36, - 0x29, 0x2e, 0x20, 0x57, 0x65, 0x20, 0x75, 0x73, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x74, - 0x6f, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x69, 0x63, 0x6f, - 0x6e, 0x2e, 0x52, 0x0c, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x69, 0x64, 0x72, - 0x12, 0x88, 0x01, 0x0a, 0x08, 0x76, 0x70, 0x6e, 0x5f, 0x63, 0x69, 0x64, 0x72, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x09, 0x42, 0x6d, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x67, 0x12, 0x65, 0x43, 0x49, 0x44, - 0x52, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x76, - 0x70, 0x6e, 0x20, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x20, 0x28, 0x65, 0x2e, 0x67, - 0x2e, 0x20, 0x31, 0x39, 0x32, 0x2e, 0x31, 0x36, 0x38, 0x2e, 0x30, 0x2e, 0x30, 0x2f, 0x31, 0x36, - 0x29, 0x2e, 0x20, 0x57, 0x65, 0x20, 0x75, 0x73, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x74, - 0x6f, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x69, 0x63, 0x6f, - 0x6e, 0x2e, 0x52, 0x07, 0x76, 0x70, 0x6e, 0x43, 0x69, 0x64, 0x72, 0x12, 0x45, 0x0a, 0x0a, 0x70, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x42, - 0x26, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x20, 0x12, 0x1e, 0x54, 0x68, 0x65, 0x20, 0x70, 0x75, 0x62, - 0x6c, 0x69, 0x63, 0x20, 0x55, 0x52, 0x4c, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x55, - 0x72, 0x6c, 0x12, 0x63, 0x0a, 0x0d, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x5f, 0x70, 0x72, - 0x6f, 0x78, 0x79, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2e, 0x52, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x42, 0x23, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x1d, 0x12, 0x1b, 0x52, 0x6f, - 0x75, 0x74, 0x65, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, - 0x20, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x65, 0x73, 0x2e, 0x52, 0x0c, 0x72, 0x65, 0x76, 0x65, 0x72, - 0x73, 0x65, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x12, 0x55, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x6b, 0x73, - 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, - 0x55, 0x49, 0x4c, 0x69, 0x6e, 0x6b, 0x42, 0x2f, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x29, 0x12, 0x27, - 0x41, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x6c, 0x69, 0x6e, 0x6b, 0x73, - 0x20, 0x74, 0x6f, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x47, 0x55, 0x49, 0x2e, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x12, 0x33, - 0x0a, 0x0d, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, - 0x11, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x55, - 0x49, 0x55, 0x73, 0x65, 0x72, 0x52, 0x0c, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x55, 0x73, - 0x65, 0x72, 0x73, 0x12, 0x3a, 0x0a, 0x0d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, - 0x61, 0x74, 0x6f, 0x72, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, - 0x52, 0x0d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x12, - 0x34, 0x0a, 0x16, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x73, 0x65, 0x61, 0x72, - 0x63, 0x68, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x14, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x46, - 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x10, 0x73, 0x61, 0x6d, 0x6c, 0x5f, 0x63, 0x65, - 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0f, 0x73, 0x61, 0x6d, 0x6c, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, - 0x12, 0x28, 0x0a, 0x10, 0x73, 0x61, 0x6d, 0x6c, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, - 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x61, 0x6d, 0x6c, - 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x31, 0x0a, 0x15, 0x73, 0x61, - 0x6d, 0x6c, 0x5f, 0x69, 0x64, 0x70, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, - 0x75, 0x72, 0x6c, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x73, 0x61, 0x6d, 0x6c, 0x49, - 0x64, 0x70, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x55, 0x72, 0x6c, 0x12, 0x22, 0x0a, - 0x0d, 0x73, 0x61, 0x6d, 0x6c, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x0f, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x61, 0x6d, 0x6c, 0x52, 0x6f, 0x6f, 0x74, 0x55, 0x72, - 0x6c, 0x12, 0x2e, 0x0a, 0x13, 0x73, 0x61, 0x6d, 0x6c, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x61, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, + 0x72, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xe1, 0x01, 0x0a, 0x07, 0x47, 0x55, 0x49, + 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x74, 0x65, 0x78, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x63, + 0x6f, 0x6e, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x69, 0x63, + 0x6f, 0x6e, 0x55, 0x72, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x65, 0x77, + 0x5f, 0x74, 0x61, 0x62, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x6e, 0x65, 0x77, 0x54, + 0x61, 0x62, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x61, + 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, + 0x6f, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, + 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, 0x84, 0x08, 0x0a, + 0x0d, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x12, + 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x12, 0xb9, 0x01, 0x0a, 0x0b, 0x6f, 0x69, 0x64, 0x63, 0x5f, 0x69, 0x73, 0x73, 0x75, + 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x97, 0x01, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, + 0x90, 0x01, 0x12, 0x8d, 0x01, 0x55, 0x52, 0x4c, 0x20, 0x74, 0x6f, 0x20, 0x4f, 0x49, 0x44, 0x43, + 0x20, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x44, + 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c, + 0x64, 0x20, 0x62, 0x65, 0x20, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x69, + 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x27, 0x6f, 0x69, 0x64, 0x63, 0x5f, 0x69, 0x73, 0x73, 0x75, + 0x65, 0x72, 0x20, 0x2b, 0x20, 0x2f, 0x2e, 0x77, 0x65, 0x6c, 0x6c, 0x2d, 0x6b, 0x6e, 0x6f, 0x77, + 0x6e, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x64, 0x2d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x27, 0x20, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x2e, 0x20, 0x52, 0x0a, 0x6f, 0x69, 0x64, 0x63, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x12, 0x1b, + 0x0a, 0x09, 0x6f, 0x69, 0x64, 0x63, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x6f, 0x69, 0x64, 0x63, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, + 0x76, 0x61, 0x74, 0x61, 0x72, 0x18, 0x13, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x76, 0x61, + 0x74, 0x61, 0x72, 0x12, 0x58, 0x0a, 0x0f, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x30, 0xe2, 0xfc, + 0xe3, 0xc4, 0x01, 0x2a, 0x12, 0x28, 0x49, 0x66, 0x20, 0x73, 0x65, 0x74, 0x20, 0x77, 0x65, 0x20, + 0x75, 0x73, 0x65, 0x20, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x20, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, + 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x52, 0x0d, + 0x6f, 0x61, 0x75, 0x74, 0x68, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x60, 0x0a, + 0x13, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x65, + 0x63, 0x72, 0x65, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x42, 0x30, 0xe2, 0xfc, 0xe3, 0xc4, + 0x01, 0x2a, 0x12, 0x28, 0x49, 0x66, 0x20, 0x73, 0x65, 0x74, 0x20, 0x77, 0x65, 0x20, 0x75, 0x73, + 0x65, 0x20, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x20, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x52, 0x11, 0x6f, 0x61, + 0x75, 0x74, 0x68, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, + 0x16, 0x0a, 0x06, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x12, 0x44, 0x0a, 0x10, 0x73, 0x61, 0x6d, 0x6c, 0x5f, + 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x19, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x13, 0x12, 0x11, 0x53, 0x41, 0x4d, 0x4c, 0x20, + 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x0f, 0x73, 0x61, + 0x6d, 0x6c, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x43, 0x0a, + 0x10, 0x73, 0x61, 0x6d, 0x6c, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, + 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x42, 0x19, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x13, 0x12, + 0x11, 0x53, 0x41, 0x4d, 0x4c, 0x20, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x20, 0x6b, 0x65, + 0x79, 0x2e, 0x52, 0x0e, 0x73, 0x61, 0x6d, 0x6c, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, + 0x65, 0x79, 0x12, 0x5f, 0x0a, 0x15, 0x73, 0x61, 0x6d, 0x6c, 0x5f, 0x69, 0x64, 0x70, 0x5f, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x0e, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x2c, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x26, 0x12, 0x24, 0x53, 0x41, 0x4d, 0x4c, 0x20, + 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x72, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x20, 0x55, 0x52, 0x4c, 0x2e, 0x52, + 0x12, 0x73, 0x61, 0x6d, 0x6c, 0x49, 0x64, 0x70, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x55, 0x72, 0x6c, 0x12, 0x3a, 0x0a, 0x0d, 0x73, 0x61, 0x6d, 0x6c, 0x5f, 0x72, 0x6f, 0x6f, 0x74, + 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x42, 0x16, 0xe2, 0xfc, 0xe3, 0xc4, + 0x01, 0x10, 0x12, 0x0e, 0x53, 0x41, 0x4d, 0x4c, 0x20, 0x72, 0x6f, 0x6f, 0x74, 0x20, 0x55, 0x52, + 0x4c, 0x2e, 0x52, 0x0b, 0x73, 0x61, 0x6d, 0x6c, 0x52, 0x6f, 0x6f, 0x74, 0x55, 0x72, 0x6c, 0x12, + 0x70, 0x0a, 0x13, 0x73, 0x61, 0x6d, 0x6c, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x61, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x42, 0x40, 0xe2, 0xfc, + 0xe3, 0xc4, 0x01, 0x3a, 0x12, 0x38, 0x53, 0x41, 0x4d, 0x4c, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x20, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x69, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x11, 0x73, 0x61, 0x6d, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x12, 0x33, 0x0a, 0x16, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5f, 0x6f, 0x61, 0x75, 0x74, - 0x68, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x13, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x4f, 0x61, 0x75, 0x74, 0x68, 0x43, 0x6c, - 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x3b, 0x0a, 0x1a, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x5f, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x65, - 0x63, 0x72, 0x65, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x17, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x4f, 0x61, 0x75, 0x74, 0x68, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x63, - 0x72, 0x65, 0x74, 0x22, 0x67, 0x0a, 0x07, 0x47, 0x55, 0x49, 0x55, 0x73, 0x65, 0x72, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x68, - 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x61, 0x73, 0x73, 0x77, - 0x6f, 0x72, 0x64, 0x48, 0x61, 0x73, 0x68, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x61, 0x73, 0x73, 0x77, - 0x6f, 0x72, 0x64, 0x5f, 0x73, 0x61, 0x6c, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, - 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x53, 0x61, 0x6c, 0x74, 0x22, 0xa3, 0x01, 0x0a, - 0x08, 0x43, 0x41, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x96, 0x01, 0x0a, 0x0b, 0x70, 0x72, - 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, - 0x75, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x6f, 0x12, 0x6d, 0x54, 0x68, 0x65, 0x20, 0x70, 0x72, 0x69, - 0x76, 0x61, 0x74, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x43, 0x41, 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x50, 0x45, - 0x4d, 0x2e, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x63, 0x6f, 0x72, - 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x69, 0x6e, 0x20, - 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x61, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, - 0x69, 0x63, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, - 0x65, 0x79, 0x22, 0x5f, 0x0a, 0x12, 0x52, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x50, 0x72, 0x6f, - 0x78, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x75, 0x74, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x10, - 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, - 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x5f, 0x61, 0x75, 0x74, 0x68, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x41, - 0x75, 0x74, 0x68, 0x22, 0xf5, 0x01, 0x0a, 0x0c, 0x44, 0x79, 0x6e, 0x44, 0x4e, 0x53, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1e, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x64, 0x6e, 0x73, 0x5f, 0x75, 0x73, 0x65, - 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x64, 0x6e, - 0x73, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x64, 0x6e, - 0x73, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0c, 0x64, 0x64, 0x6e, 0x73, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x1d, - 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x1c, 0x0a, - 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x63, - 0x68, 0x65, 0x63, 0x6b, 0x69, 0x70, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0a, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x69, 0x70, 0x55, 0x72, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, - 0x64, 0x6e, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x64, 0x6e, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0xe8, 0x07, 0x0a, 0x17, - 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x12, 0x34, 0x0a, 0x16, 0x63, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x14, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x12, 0x38, 0x0a, - 0x18, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x70, - 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x16, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x65, - 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x12, 0x34, 0x0a, 0x16, 0x65, 0x6e, 0x72, 0x6f, 0x6c, - 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, - 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x14, 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, - 0x65, 0x6e, 0x74, 0x73, 0x50, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x12, 0x20, 0x0a, - 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x09, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12, - 0x28, 0x0a, 0x10, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x68, 0x65, 0x61, 0x70, 0x5f, 0x73, - 0x69, 0x7a, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, - 0x74, 0x48, 0x65, 0x61, 0x70, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x2f, 0x0a, 0x13, 0x63, 0x6f, 0x6e, - 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, - 0x18, 0x18, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, - 0x6e, 0x63, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x60, 0x0a, 0x0f, 0x6d, 0x61, - 0x78, 0x5f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x0b, 0x20, - 0x01, 0x28, 0x04, 0x42, 0x38, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x32, 0x12, 0x30, 0x4d, 0x61, 0x78, - 0x69, 0x6d, 0x75, 0x6d, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x42, 0x79, 0x74, - 0x65, 0x73, 0x20, 0x77, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x61, 0x63, 0x63, 0x65, 0x70, - 0x74, 0x20, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x52, 0x0d, 0x6d, - 0x61, 0x78, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x70, 0x0a, 0x10, - 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, - 0x18, 0x0f, 0x20, 0x01, 0x28, 0x03, 0x42, 0x45, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x3f, 0x12, 0x3d, - 0x45, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, - 0x6f, 0x66, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, - 0x69, 0x73, 0x20, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x28, 0x64, - 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x31, 0x30, 0x30, 0x30, 0x30, 0x29, 0x52, 0x0f, 0x65, - 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x33, - 0x0a, 0x16, 0x70, 0x65, 0x72, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x75, 0x70, 0x6c, - 0x6f, 0x61, 0x64, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, 0x15, 0x20, 0x01, 0x28, 0x03, 0x52, 0x13, - 0x70, 0x65, 0x72, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, - 0x61, 0x74, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x75, 0x70, - 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, 0x16, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x10, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x61, 0x74, - 0x65, 0x12, 0x31, 0x0a, 0x15, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x65, 0x76, 0x65, 0x6e, - 0x74, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x18, 0x17, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x12, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x78, - 0x57, 0x61, 0x69, 0x74, 0x12, 0x38, 0x0a, 0x19, 0x6d, 0x69, 0x6e, 0x69, 0x6f, 0x6e, 0x5f, 0x62, - 0x61, 0x74, 0x63, 0x68, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d, - 0x73, 0x18, 0x19, 0x20, 0x01, 0x28, 0x04, 0x52, 0x15, 0x6d, 0x69, 0x6e, 0x69, 0x6f, 0x6e, 0x42, - 0x61, 0x74, 0x63, 0x68, 0x57, 0x61, 0x69, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x4d, 0x73, 0x12, 0x38, - 0x0a, 0x18, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, - 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x16, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x46, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x2d, 0x0a, 0x13, 0x63, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x6c, 0x72, 0x75, 0x5f, 0x74, 0x74, 0x6c, 0x18, - 0x1b, 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, - 0x6f, 0x4c, 0x72, 0x75, 0x54, 0x74, 0x6c, 0x12, 0x31, 0x0a, 0x15, 0x63, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, 0x69, 0x6d, 0x65, - 0x18, 0x1d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, - 0x66, 0x6f, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x33, 0x0a, 0x16, 0x63, 0x6c, - 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, - 0x74, 0x69, 0x6d, 0x65, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13, 0x63, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x57, 0x72, 0x69, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, - 0x35, 0x0a, 0x17, 0x6d, 0x61, 0x78, 0x5f, 0x6a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x62, - 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x14, 0x6d, 0x61, 0x78, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x42, 0x75, 0x66, 0x66, - 0x65, 0x72, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x95, 0x13, 0x0a, 0x0e, 0x46, 0x72, 0x6f, 0x6e, 0x74, - 0x65, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x23, 0x0a, 0x0b, 0x70, 0x75, 0x62, - 0x6c, 0x69, 0x63, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, - 0x18, 0x01, 0x52, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1a, - 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x69, - 0x6e, 0x64, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x62, 0x69, 0x6e, 0x64, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1b, 0x0a, - 0x09, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x08, 0x62, 0x69, 0x6e, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x61, - 0x73, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x19, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, - 0x61, 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x24, 0x0a, 0x0e, 0x75, 0x73, 0x65, 0x5f, 0x70, - 0x6c, 0x61, 0x69, 0x6e, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x18, 0x18, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0c, 0x75, 0x73, 0x65, 0x50, 0x6c, 0x61, 0x69, 0x6e, 0x48, 0x74, 0x74, 0x70, 0x12, 0x14, 0x0a, - 0x05, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x18, 0x21, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x70, 0x72, - 0x6f, 0x78, 0x79, 0x12, 0x4e, 0x0a, 0x0b, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2c, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x26, - 0x12, 0x24, 0x58, 0x35, 0x30, 0x39, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x20, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x52, 0x0b, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x65, 0x12, 0x66, 0x0a, 0x0b, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, - 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x45, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x3f, - 0x12, 0x3d, 0x54, 0x68, 0x65, 0x20, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x20, 0x6b, 0x65, - 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, - 0x64, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, - 0x20, 0x69, 0x6e, 0x20, 0x50, 0x45, 0x4d, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x52, - 0x0a, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x38, 0x0a, 0x18, 0x74, - 0x6c, 0x73, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x66, - 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x16, 0x74, - 0x6c, 0x73, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6c, - 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x37, 0x0a, 0x18, 0x74, 0x6c, 0x73, 0x5f, 0x70, 0x72, 0x69, - 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x74, 0x6c, 0x73, 0x50, 0x72, 0x69, 0x76, - 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x40, - 0x0a, 0x08, 0x64, 0x6e, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x25, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x1f, 0x12, 0x1d, 0x54, 0x68, 0x65, 0x20, 0x44, 0x4e, - 0x53, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x72, - 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x2e, 0x52, 0x07, 0x64, 0x6e, 0x73, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0xbb, 0x02, 0x0a, 0x19, 0x64, 0x6f, 0x5f, 0x6e, 0x6f, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x70, - 0x72, 0x65, 0x73, 0x73, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x18, 0x0a, - 0x20, 0x01, 0x28, 0x08, 0x42, 0xff, 0x01, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0xf8, 0x01, 0x12, 0xf5, - 0x01, 0x57, 0x68, 0x65, 0x6e, 0x20, 0x73, 0x65, 0x74, 0x20, 0x77, 0x65, 0x20, 0x64, 0x6f, 0x20, - 0x6e, 0x6f, 0x74, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x20, 0x61, 0x72, 0x74, - 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x20, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, - 0x69, 0x73, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x75, 0x73, 0x65, 0x66, 0x75, 0x6c, 0x20, 0x66, - 0x6f, 0x72, 0x20, 0x64, 0x65, 0x62, 0x75, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x2e, 0x20, 0x4e, 0x6f, - 0x74, 0x65, 0x3a, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x69, 0x73, - 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x20, 0x66, - 0x69, 0x65, 0x6c, 0x64, 0x73, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, - 0x61, 0x6e, 0x64, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, - 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x20, 0x69, 0x6e, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, - 0x64, 0x69, 0x73, 0x63, 0x6c, 0x6f, 0x73, 0x75, 0x72, 0x65, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x73, 0x20, 0x75, 0x6e, 0x74, 0x72, - 0x75, 0x73, 0x74, 0x65, 0x64, 0x2e, 0x52, 0x16, 0x64, 0x6f, 0x4e, 0x6f, 0x74, 0x43, 0x6f, 0x6d, - 0x70, 0x72, 0x65, 0x73, 0x73, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x5a, - 0x0a, 0x07, 0x64, 0x79, 0x6e, 0x5f, 0x64, 0x6e, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x79, 0x6e, 0x44, 0x4e, 0x53, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x42, 0x2c, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x26, 0x12, 0x24, 0x49, 0x66, - 0x20, 0x73, 0x65, 0x74, 0x20, 0x77, 0x65, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x64, 0x79, 0x6e, 0x20, 0x64, 0x6e, 0x73, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x2e, 0x52, 0x06, 0x64, 0x79, 0x6e, 0x44, 0x6e, 0x73, 0x12, 0x64, 0x0a, 0x0c, 0x70, 0x72, - 0x6f, 0x78, 0x79, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x41, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x3b, 0x12, 0x39, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, - 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x70, 0x72, 0x6f, 0x78, 0x79, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x20, 0x61, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, - 0x12, 0x86, 0x01, 0x0a, 0x23, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x63, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x61, - 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x09, 0x42, 0x37, - 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x31, 0x12, 0x2f, 0x54, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x69, 0x74, - 0x69, 0x61, 0x6c, 0x20, 0x73, 0x65, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x20, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x72, 0x74, - 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x2e, 0x52, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, - 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, - 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x8d, 0x01, 0x0a, 0x23, 0x64, 0x65, - 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x6d, 0x6f, 0x6e, - 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, - 0x73, 0x18, 0x1f, 0x20, 0x03, 0x28, 0x09, 0x42, 0x3e, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x38, 0x12, - 0x36, 0x41, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x69, 0x6e, 0x69, 0x74, - 0x69, 0x61, 0x6c, 0x20, 0x73, 0x65, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x20, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x72, 0x74, - 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x2e, 0x52, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, - 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x38, 0x0a, 0x18, 0x69, 0x6e, 0x69, - 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x61, 0x72, 0x74, 0x69, - 0x66, 0x61, 0x63, 0x74, 0x73, 0x18, 0x22, 0x20, 0x03, 0x28, 0x09, 0x52, 0x16, 0x69, 0x6e, 0x69, - 0x74, 0x69, 0x61, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, - 0x63, 0x74, 0x73, 0x12, 0x7e, 0x0a, 0x0b, 0x72, 0x75, 0x6e, 0x5f, 0x61, 0x73, 0x5f, 0x75, 0x73, - 0x65, 0x72, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x42, 0x5e, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x58, - 0x12, 0x56, 0x54, 0x68, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x20, 0x73, 0x68, 0x6f, - 0x75, 0x6c, 0x64, 0x20, 0x72, 0x75, 0x6e, 0x20, 0x61, 0x73, 0x2e, 0x20, 0x49, 0x66, 0x20, 0x73, - 0x65, 0x74, 0x20, 0x77, 0x65, 0x20, 0x72, 0x65, 0x66, 0x75, 0x73, 0x65, 0x20, 0x74, 0x6f, 0x20, - 0x72, 0x75, 0x6e, 0x20, 0x61, 0x73, 0x20, 0x61, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x74, 0x20, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x52, 0x09, 0x72, 0x75, 0x6e, 0x41, 0x73, 0x55, - 0x73, 0x65, 0x72, 0x12, 0x2b, 0x0a, 0x12, 0x47, 0x52, 0x50, 0x43, 0x5f, 0x70, 0x6f, 0x6f, 0x6c, - 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x11, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x0f, 0x47, 0x52, 0x50, 0x43, 0x50, 0x6f, 0x6f, 0x6c, 0x4d, 0x61, 0x78, 0x53, 0x69, 0x7a, 0x65, - 0x12, 0x2b, 0x0a, 0x12, 0x47, 0x52, 0x50, 0x43, 0x5f, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x6d, 0x61, - 0x78, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x47, 0x52, - 0x50, 0x43, 0x50, 0x6f, 0x6f, 0x6c, 0x4d, 0x61, 0x78, 0x57, 0x61, 0x69, 0x74, 0x12, 0x44, 0x0a, - 0x0f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x52, 0x0e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x73, 0x12, 0x3c, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, - 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, - 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, - 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x69, 0x73, 0x5f, 0x6d, 0x69, 0x6e, 0x69, 0x6f, 0x6e, 0x18, 0x1e, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x69, 0x73, 0x4d, 0x69, 0x6e, 0x69, 0x6f, 0x6e, 0x12, 0x60, - 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x09, 0x20, - 0x01, 0x28, 0x04, 0x42, 0x3e, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x38, 0x12, 0x36, 0x54, 0x68, 0x65, - 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x72, - 0x6f, 0x63, 0x65, 0x73, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, - 0x6c, 0x79, 0x2e, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, - 0x12, 0x60, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x73, - 0x69, 0x7a, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x04, 0x42, 0x38, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, - 0x32, 0x12, 0x30, 0x4d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x20, - 0x69, 0x6e, 0x20, 0x42, 0x79, 0x74, 0x65, 0x73, 0x20, 0x77, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, - 0x20, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x20, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x20, - 0x66, 0x6f, 0x72, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x69, - 0x7a, 0x65, 0x12, 0x70, 0x0a, 0x10, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x63, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x03, 0x42, 0x45, 0xe2, 0xfc, - 0xe3, 0xc4, 0x01, 0x3f, 0x12, 0x3d, 0x45, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x6e, - 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, - 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, - 0x65, 0x6e, 0x74, 0x20, 0x28, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x31, 0x30, 0x30, - 0x30, 0x30, 0x29, 0x52, 0x0f, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x43, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x73, 0x12, 0x33, 0x0a, 0x16, 0x70, 0x65, 0x72, 0x5f, 0x63, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x5f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, 0x15, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x13, 0x70, 0x65, 0x72, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x55, - 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x61, 0x74, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x67, 0x6c, 0x6f, - 0x62, 0x61, 0x6c, 0x5f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, - 0x16, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x55, 0x70, 0x6c, - 0x6f, 0x61, 0x64, 0x52, 0x61, 0x74, 0x65, 0x12, 0x31, 0x0a, 0x15, 0x63, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x77, 0x61, 0x69, 0x74, - 0x18, 0x17, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x78, 0x57, 0x61, 0x69, 0x74, 0x12, 0x44, 0x0a, 0x1e, 0x61, 0x72, - 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x20, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x1c, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x44, 0x65, 0x66, 0x69, - 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, - 0x12, 0x34, 0x0a, 0x16, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x23, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x14, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, - 0x72, 0x52, 0x65, 0x67, 0x65, 0x78, 0x12, 0x26, 0x0a, 0x0f, 0x64, 0x6f, 0x5f, 0x6e, 0x6f, 0x74, - 0x5f, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0d, 0x64, 0x6f, 0x4e, 0x6f, 0x74, 0x52, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x22, 0xaf, - 0x06, 0x0a, 0x0f, 0x44, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x12, 0x26, 0x0a, 0x0e, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x69, 0x6d, 0x70, 0x6c, - 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x6f, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2f, 0x0a, 0x13, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x74, - 0x6f, 0x72, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x12, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x44, 0x69, - 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x0c, 0x6d, 0x61, 0x78, 0x5f, 0x64, - 0x69, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x6d, - 0x61, 0x78, 0x44, 0x69, 0x72, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x36, 0x0a, 0x17, 0x6d, 0x65, 0x6d, - 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x73, 0x65, 0x63, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x15, 0x6d, 0x65, 0x6d, 0x63, - 0x61, 0x63, 0x68, 0x65, 0x45, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, - 0x63, 0x12, 0x43, 0x0a, 0x1e, 0x6d, 0x65, 0x6d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x77, 0x72, - 0x69, 0x74, 0x65, 0x5f, 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x62, 0x75, 0x66, - 0x66, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x1b, 0x6d, 0x65, 0x6d, 0x63, 0x61, + 0x65, 0x12, 0x43, 0x0a, 0x12, 0x73, 0x75, 0x62, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, + 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x11, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x6f, 0x72, 0x52, 0x11, 0x73, 0x75, 0x62, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, + 0x63, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x3b, 0x0a, 0x1a, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, + 0x74, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, + 0x5f, 0x6d, 0x69, 0x6e, 0x18, 0x14, 0x20, 0x01, 0x28, 0x04, 0x52, 0x17, 0x64, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x70, 0x69, 0x72, 0x79, + 0x4d, 0x69, 0x6e, 0x22, 0xf0, 0x0c, 0x0a, 0x09, 0x47, 0x55, 0x49, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x12, 0x98, 0x01, 0x0a, 0x0c, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x75, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x6f, + 0x12, 0x6d, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x69, 0x6e, + 0x64, 0x20, 0x47, 0x55, 0x49, 0x20, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x2e, 0x20, + 0x54, 0x68, 0x69, 0x73, 0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x75, 0x73, 0x75, 0x61, + 0x6c, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x62, 0x65, 0x20, 0x31, 0x32, 0x37, 0x2e, + 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x2c, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x77, 0x69, 0x73, 0x65, + 0x20, 0x62, 0x65, 0x20, 0x73, 0x75, 0x72, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x6c, 0x79, 0x20, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x69, 0x74, 0x2e, 0x52, + 0x0b, 0x62, 0x69, 0x6e, 0x64, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x35, 0x0a, 0x09, + 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x42, + 0x18, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x12, 0x12, 0x10, 0x50, 0x6f, 0x72, 0x74, 0x20, 0x74, 0x6f, + 0x20, 0x62, 0x69, 0x6e, 0x64, 0x20, 0x74, 0x6f, 0x2e, 0x52, 0x08, 0x62, 0x69, 0x6e, 0x64, 0x50, + 0x6f, 0x72, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x75, 0x73, 0x65, 0x5f, 0x70, 0x6c, 0x61, 0x69, 0x6e, + 0x5f, 0x68, 0x74, 0x74, 0x70, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x75, 0x73, 0x65, + 0x50, 0x6c, 0x61, 0x69, 0x6e, 0x48, 0x74, 0x74, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x61, 0x73, + 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x61, + 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0xc3, 0x01, 0x0a, 0x0e, 0x67, 0x77, 0x5f, 0x63, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x9b, 0x01, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x94, 0x01, 0x12, 0x91, 0x01, 0x54, 0x68, 0x65, 0x20, + 0x47, 0x55, 0x49, 0x20, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x73, 0x20, 0x61, 0x20, 0x48, 0x54, + 0x54, 0x50, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x20, 0x74, 0x6f, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x67, 0x52, 0x50, 0x43, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x2e, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x70, + 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, + 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, + 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x67, + 0x52, 0x50, 0x43, 0x20, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x2e, 0x52, 0x0d, 0x67, + 0x77, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x6b, 0x0a, 0x0e, + 0x67, 0x77, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x0b, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x45, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x3f, 0x12, 0x3d, 0x54, 0x68, + 0x65, 0x20, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x20, 0x6f, 0x66, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x20, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, + 0x50, 0x45, 0x4d, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x52, 0x0c, 0x67, 0x77, 0x50, + 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x97, 0x01, 0x0a, 0x0d, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x63, 0x69, 0x64, 0x72, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x09, 0x42, 0x72, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x6c, 0x12, 0x6a, 0x43, 0x49, 0x44, 0x52, 0x20, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x20, 0x28, + 0x65, 0x2e, 0x67, 0x2e, 0x20, 0x31, 0x39, 0x32, 0x2e, 0x31, 0x36, 0x38, 0x2e, 0x30, 0x2e, 0x30, + 0x2f, 0x31, 0x36, 0x29, 0x2e, 0x20, 0x57, 0x65, 0x20, 0x75, 0x73, 0x65, 0x20, 0x74, 0x68, 0x69, + 0x73, 0x20, 0x74, 0x6f, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, + 0x69, 0x63, 0x6f, 0x6e, 0x2e, 0x52, 0x0c, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, + 0x69, 0x64, 0x72, 0x12, 0x88, 0x01, 0x0a, 0x08, 0x76, 0x70, 0x6e, 0x5f, 0x63, 0x69, 0x64, 0x72, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x42, 0x6d, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x67, 0x12, 0x65, + 0x43, 0x49, 0x44, 0x52, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x20, 0x6f, + 0x66, 0x20, 0x76, 0x70, 0x6e, 0x20, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x20, 0x28, + 0x65, 0x2e, 0x67, 0x2e, 0x20, 0x31, 0x39, 0x32, 0x2e, 0x31, 0x36, 0x38, 0x2e, 0x30, 0x2e, 0x30, + 0x2f, 0x31, 0x36, 0x29, 0x2e, 0x20, 0x57, 0x65, 0x20, 0x75, 0x73, 0x65, 0x20, 0x74, 0x68, 0x69, + 0x73, 0x20, 0x74, 0x6f, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, + 0x69, 0x63, 0x6f, 0x6e, 0x2e, 0x52, 0x07, 0x76, 0x70, 0x6e, 0x43, 0x69, 0x64, 0x72, 0x12, 0x45, + 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x26, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x20, 0x12, 0x1e, 0x54, 0x68, 0x65, 0x20, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x55, 0x52, 0x4c, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, + 0x69, 0x73, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x55, 0x72, 0x6c, 0x12, 0x63, 0x0a, 0x0d, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, + 0x5f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x50, 0x72, 0x6f, 0x78, + 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x23, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x1d, 0x12, + 0x1b, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x72, 0x65, 0x76, 0x65, + 0x72, 0x73, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x65, 0x73, 0x2e, 0x52, 0x0c, 0x72, 0x65, + 0x76, 0x65, 0x72, 0x73, 0x65, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x12, 0x55, 0x0a, 0x05, 0x6c, 0x69, + 0x6e, 0x6b, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x47, 0x55, 0x49, 0x4c, 0x69, 0x6e, 0x6b, 0x42, 0x2f, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, + 0x29, 0x12, 0x27, 0x41, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x6c, 0x69, + 0x6e, 0x6b, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x69, + 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x47, 0x55, 0x49, 0x2e, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x6b, + 0x73, 0x12, 0x33, 0x0a, 0x0d, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x75, 0x73, 0x65, + 0x72, 0x73, 0x18, 0x11, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x47, 0x55, 0x49, 0x55, 0x73, 0x65, 0x72, 0x52, 0x0c, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, + 0x6c, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x3a, 0x0a, 0x0d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, + 0x74, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x6f, 0x72, 0x52, 0x0d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, + 0x6f, 0x72, 0x12, 0x34, 0x0a, 0x16, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x73, + 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x12, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x14, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x65, 0x61, 0x72, + 0x63, 0x68, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x10, 0x73, 0x61, 0x6d, 0x6c, + 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x0c, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0f, 0x73, 0x61, 0x6d, 0x6c, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x61, 0x6d, 0x6c, 0x5f, 0x70, 0x72, 0x69, 0x76, + 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, + 0x61, 0x6d, 0x6c, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x31, 0x0a, + 0x15, 0x73, 0x61, 0x6d, 0x6c, 0x5f, 0x69, 0x64, 0x70, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x73, 0x61, + 0x6d, 0x6c, 0x49, 0x64, 0x70, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x55, 0x72, 0x6c, + 0x12, 0x22, 0x0a, 0x0d, 0x73, 0x61, 0x6d, 0x6c, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x75, 0x72, + 0x6c, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x61, 0x6d, 0x6c, 0x52, 0x6f, 0x6f, + 0x74, 0x55, 0x72, 0x6c, 0x12, 0x2e, 0x0a, 0x13, 0x73, 0x61, 0x6d, 0x6c, 0x5f, 0x75, 0x73, 0x65, + 0x72, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x11, 0x73, 0x61, 0x6d, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x12, 0x33, 0x0a, 0x16, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5f, 0x6f, + 0x61, 0x75, 0x74, 0x68, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x4f, 0x61, 0x75, 0x74, + 0x68, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x3b, 0x0a, 0x1a, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x5f, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x17, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x4f, 0x61, 0x75, 0x74, 0x68, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x22, 0x67, 0x0a, 0x07, 0x47, 0x55, 0x49, 0x55, 0x73, 0x65, + 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, + 0x64, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x61, + 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x48, 0x61, 0x73, 0x68, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x61, + 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x73, 0x61, 0x6c, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0c, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x53, 0x61, 0x6c, 0x74, 0x22, + 0xa3, 0x01, 0x0a, 0x08, 0x43, 0x41, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x96, 0x01, 0x0a, + 0x0b, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x75, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x6f, 0x12, 0x6d, 0x54, 0x68, 0x65, 0x20, + 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x43, 0x41, 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x20, 0x69, 0x6e, + 0x20, 0x50, 0x45, 0x4d, 0x2e, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, + 0x63, 0x6f, 0x72, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, + 0x69, 0x6e, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x61, 0x5f, 0x63, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x76, 0x61, + 0x74, 0x65, 0x4b, 0x65, 0x79, 0x22, 0x5f, 0x0a, 0x12, 0x52, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, + 0x50, 0x72, 0x6f, 0x78, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x72, + 0x6f, 0x75, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x72, 0x6f, 0x75, 0x74, + 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x75, 0x72, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x5f, 0x61, + 0x75, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x72, 0x65, 0x71, 0x75, 0x69, + 0x72, 0x65, 0x41, 0x75, 0x74, 0x68, 0x22, 0xf5, 0x01, 0x0a, 0x0c, 0x44, 0x79, 0x6e, 0x44, 0x4e, + 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1e, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x08, 0x68, + 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x64, 0x6e, 0x73, 0x5f, + 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, + 0x64, 0x64, 0x6e, 0x73, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, + 0x64, 0x64, 0x6e, 0x73, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x64, 0x6e, 0x73, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, + 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x72, 0x6c, + 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x1f, + 0x0a, 0x0b, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x69, 0x70, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x69, 0x70, 0x55, 0x72, 0x6c, 0x12, + 0x1d, 0x0a, 0x0a, 0x64, 0x6e, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, 0x6e, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0xe8, + 0x07, 0x0a, 0x17, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x12, 0x34, 0x0a, 0x16, 0x63, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x73, 0x65, + 0x63, 0x6f, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x14, 0x63, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, + 0x12, 0x38, 0x0a, 0x18, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x16, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x50, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x12, 0x34, 0x0a, 0x16, 0x65, 0x6e, + 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x73, 0x65, + 0x63, 0x6f, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x14, 0x65, 0x6e, 0x72, 0x6f, + 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x50, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, + 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, + 0x63, 0x79, 0x12, 0x28, 0x0a, 0x10, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x68, 0x65, 0x61, + 0x70, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x74, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x48, 0x65, 0x61, 0x70, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x2f, 0x0a, 0x13, + 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x74, 0x69, 0x6d, 0x65, + 0x6f, 0x75, 0x74, 0x18, 0x18, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x63, 0x75, + 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x60, 0x0a, + 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x73, 0x69, 0x7a, 0x65, + 0x18, 0x0b, 0x20, 0x01, 0x28, 0x04, 0x42, 0x38, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x32, 0x12, 0x30, + 0x4d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x69, 0x6e, 0x20, + 0x42, 0x79, 0x74, 0x65, 0x73, 0x20, 0x77, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x61, 0x63, + 0x63, 0x65, 0x70, 0x74, 0x20, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x20, 0x66, 0x6f, 0x72, + 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x69, 0x7a, 0x65, 0x12, + 0x70, 0x0a, 0x10, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x03, 0x42, 0x45, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, + 0x3f, 0x12, 0x3d, 0x45, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x6e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x69, 0x6e, + 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, + 0x20, 0x28, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x31, 0x30, 0x30, 0x30, 0x30, 0x29, + 0x52, 0x0f, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x73, 0x12, 0x33, 0x0a, 0x16, 0x70, 0x65, 0x72, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, + 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, 0x15, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x13, 0x70, 0x65, 0x72, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x55, 0x70, 0x6c, 0x6f, + 0x61, 0x64, 0x52, 0x61, 0x74, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, + 0x5f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, 0x16, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x10, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, + 0x52, 0x61, 0x74, 0x65, 0x12, 0x31, 0x0a, 0x15, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x18, 0x17, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x12, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x4d, 0x61, 0x78, 0x57, 0x61, 0x69, 0x74, 0x12, 0x38, 0x0a, 0x19, 0x6d, 0x69, 0x6e, 0x69, 0x6f, + 0x6e, 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x74, 0x69, 0x6d, + 0x65, 0x5f, 0x6d, 0x73, 0x18, 0x19, 0x20, 0x01, 0x28, 0x04, 0x52, 0x15, 0x6d, 0x69, 0x6e, 0x69, + 0x6f, 0x6e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x57, 0x61, 0x69, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x4d, + 0x73, 0x12, 0x38, 0x0a, 0x18, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x73, 0x6e, 0x61, 0x70, 0x73, + 0x68, 0x6f, 0x74, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x1a, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x16, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, + 0x6f, 0x74, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x2d, 0x0a, 0x13, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x6c, 0x72, 0x75, 0x5f, 0x74, + 0x74, 0x6c, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x49, 0x6e, 0x66, 0x6f, 0x4c, 0x72, 0x75, 0x54, 0x74, 0x6c, 0x12, 0x31, 0x0a, 0x15, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, + 0x69, 0x6d, 0x65, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x33, 0x0a, + 0x16, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x77, 0x72, 0x69, + 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x57, 0x72, 0x69, 0x74, 0x65, 0x54, 0x69, + 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x17, 0x6d, 0x61, 0x78, 0x5f, 0x6a, 0x6f, 0x75, 0x72, 0x6e, 0x61, + 0x6c, 0x5f, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x1c, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x14, 0x6d, 0x61, 0x78, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x42, + 0x75, 0x66, 0x66, 0x65, 0x72, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x95, 0x13, 0x0a, 0x0e, 0x46, 0x72, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x23, 0x0a, 0x0b, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x50, 0x61, 0x74, + 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x13, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, + 0x0c, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x62, 0x69, 0x6e, 0x64, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x08, 0x62, 0x69, 0x6e, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1b, 0x0a, + 0x09, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x19, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x62, 0x61, 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x24, 0x0a, 0x0e, 0x75, 0x73, + 0x65, 0x5f, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x18, 0x18, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0c, 0x75, 0x73, 0x65, 0x50, 0x6c, 0x61, 0x69, 0x6e, 0x48, 0x74, 0x74, 0x70, + 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x18, 0x21, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x12, 0x4e, 0x0a, 0x0b, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2c, 0xe2, 0xfc, 0xe3, + 0xc4, 0x01, 0x26, 0x12, 0x24, 0x58, 0x35, 0x30, 0x39, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x64, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x52, 0x0b, 0x63, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x66, 0x0a, 0x0b, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, + 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x45, 0xe2, 0xfc, 0xe3, + 0xc4, 0x01, 0x3f, 0x12, 0x3d, 0x54, 0x68, 0x65, 0x20, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, + 0x20, 0x6b, 0x65, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x72, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x65, 0x6e, 0x63, 0x6f, + 0x64, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x50, 0x45, 0x4d, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, + 0x74, 0x2e, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x38, + 0x0a, 0x18, 0x74, 0x6c, 0x73, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x16, 0x74, 0x6c, 0x73, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, + 0x46, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x37, 0x0a, 0x18, 0x74, 0x6c, 0x73, 0x5f, + 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x66, 0x69, 0x6c, 0x65, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x74, 0x6c, 0x73, 0x50, + 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x40, 0x0a, 0x08, 0x64, 0x6e, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x25, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x1f, 0x12, 0x1d, 0x54, 0x68, 0x65, + 0x20, 0x44, 0x4e, 0x53, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x2e, 0x52, 0x07, 0x64, 0x6e, 0x73, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0xbb, 0x02, 0x0a, 0x19, 0x64, 0x6f, 0x5f, 0x6e, 0x6f, 0x74, 0x5f, 0x63, + 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, + 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x42, 0xff, 0x01, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0xf8, + 0x01, 0x12, 0xf5, 0x01, 0x57, 0x68, 0x65, 0x6e, 0x20, 0x73, 0x65, 0x74, 0x20, 0x77, 0x65, 0x20, + 0x64, 0x6f, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x20, + 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x20, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x74, + 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x20, 0x54, 0x68, + 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x75, 0x73, 0x65, 0x66, 0x75, + 0x6c, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x64, 0x65, 0x62, 0x75, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x2e, + 0x20, 0x4e, 0x6f, 0x74, 0x65, 0x3a, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x74, + 0x68, 0x69, 0x73, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, + 0x74, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x6e, 0x61, + 0x6d, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x64, 0x69, 0x73, 0x63, 0x6c, 0x6f, 0x73, 0x75, 0x72, 0x65, 0x20, 0x69, 0x66, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x73, 0x20, 0x75, + 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x2e, 0x52, 0x16, 0x64, 0x6f, 0x4e, 0x6f, 0x74, + 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, + 0x73, 0x12, 0x5a, 0x0a, 0x07, 0x64, 0x79, 0x6e, 0x5f, 0x64, 0x6e, 0x73, 0x18, 0x0c, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x79, 0x6e, 0x44, 0x4e, + 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x2c, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x26, 0x12, + 0x24, 0x49, 0x66, 0x20, 0x73, 0x65, 0x74, 0x20, 0x77, 0x65, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x79, 0x6e, 0x20, 0x64, 0x6e, 0x73, 0x20, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x2e, 0x52, 0x06, 0x64, 0x79, 0x6e, 0x44, 0x6e, 0x73, 0x12, 0x64, 0x0a, + 0x0c, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x0d, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x41, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x3b, 0x12, 0x39, 0x48, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x20, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x48, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x12, 0x86, 0x01, 0x0a, 0x23, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, + 0x67, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x18, 0x0e, 0x20, 0x03, 0x28, + 0x09, 0x42, 0x37, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x31, 0x12, 0x2f, 0x54, 0x68, 0x65, 0x20, 0x69, + 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x73, 0x65, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x20, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x20, + 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x2e, 0x52, 0x20, 0x64, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, + 0x69, 0x6e, 0x67, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x8d, 0x01, 0x0a, + 0x23, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, + 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, + 0x61, 0x63, 0x74, 0x73, 0x18, 0x1f, 0x20, 0x03, 0x28, 0x09, 0x42, 0x3e, 0xe2, 0xfc, 0xe3, 0xc4, + 0x01, 0x38, 0x12, 0x36, 0x41, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x69, + 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x73, 0x65, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x20, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x20, + 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x2e, 0x52, 0x20, 0x64, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, + 0x69, 0x6e, 0x67, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x38, 0x0a, 0x18, + 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x61, + 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x18, 0x22, 0x20, 0x03, 0x28, 0x09, 0x52, 0x16, + 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x72, 0x74, + 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x7e, 0x0a, 0x0b, 0x72, 0x75, 0x6e, 0x5f, 0x61, 0x73, + 0x5f, 0x75, 0x73, 0x65, 0x72, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x42, 0x5e, 0xe2, 0xfc, 0xe3, + 0xc4, 0x01, 0x58, 0x12, 0x56, 0x54, 0x68, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x74, 0x68, + 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x20, + 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x72, 0x75, 0x6e, 0x20, 0x61, 0x73, 0x2e, 0x20, 0x49, + 0x66, 0x20, 0x73, 0x65, 0x74, 0x20, 0x77, 0x65, 0x20, 0x72, 0x65, 0x66, 0x75, 0x73, 0x65, 0x20, + 0x74, 0x6f, 0x20, 0x72, 0x75, 0x6e, 0x20, 0x61, 0x73, 0x20, 0x61, 0x20, 0x64, 0x69, 0x66, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x52, 0x09, 0x72, 0x75, 0x6e, + 0x41, 0x73, 0x55, 0x73, 0x65, 0x72, 0x12, 0x2b, 0x0a, 0x12, 0x47, 0x52, 0x50, 0x43, 0x5f, 0x70, + 0x6f, 0x6f, 0x6c, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x11, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x0f, 0x47, 0x52, 0x50, 0x43, 0x50, 0x6f, 0x6f, 0x6c, 0x4d, 0x61, 0x78, 0x53, + 0x69, 0x7a, 0x65, 0x12, 0x2b, 0x0a, 0x12, 0x47, 0x52, 0x50, 0x43, 0x5f, 0x70, 0x6f, 0x6f, 0x6c, + 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x0f, 0x47, 0x52, 0x50, 0x43, 0x50, 0x6f, 0x6f, 0x6c, 0x4d, 0x61, 0x78, 0x57, 0x61, 0x69, 0x74, + 0x12, 0x44, 0x0a, 0x0f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x3c, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x73, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x69, 0x73, 0x5f, 0x6d, 0x69, 0x6e, 0x69, 0x6f, + 0x6e, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x69, 0x73, 0x4d, 0x69, 0x6e, 0x69, 0x6f, + 0x6e, 0x12, 0x60, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x42, 0x3e, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x38, 0x12, 0x36, + 0x54, 0x68, 0x65, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x20, 0x74, 0x6f, + 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, + 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x2e, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, + 0x6e, 0x63, 0x79, 0x12, 0x60, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x75, 0x70, 0x6c, 0x6f, 0x61, + 0x64, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x04, 0x42, 0x38, 0xe2, 0xfc, + 0xe3, 0xc4, 0x01, 0x32, 0x12, 0x30, 0x4d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x20, 0x73, 0x69, + 0x7a, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x42, 0x79, 0x74, 0x65, 0x73, 0x20, 0x77, 0x65, 0x20, 0x77, + 0x69, 0x6c, 0x6c, 0x20, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x20, 0x75, 0x70, 0x6c, 0x6f, 0x61, + 0x64, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x55, 0x70, 0x6c, 0x6f, 0x61, + 0x64, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x70, 0x0a, 0x10, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, + 0x64, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x03, 0x42, + 0x45, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x3f, 0x12, 0x3d, 0x45, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, + 0x64, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x64, 0x65, 0x70, 0x6c, + 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x28, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, + 0x31, 0x30, 0x30, 0x30, 0x30, 0x29, 0x52, 0x0f, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, + 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x33, 0x0a, 0x16, 0x70, 0x65, 0x72, 0x5f, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x72, 0x61, 0x74, + 0x65, 0x18, 0x15, 0x20, 0x01, 0x28, 0x03, 0x52, 0x13, 0x70, 0x65, 0x72, 0x43, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x61, 0x74, 0x65, 0x12, 0x2c, 0x0a, 0x12, + 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x72, 0x61, + 0x74, 0x65, 0x18, 0x16, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, + 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x61, 0x74, 0x65, 0x12, 0x31, 0x0a, 0x15, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x77, + 0x61, 0x69, 0x74, 0x18, 0x17, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x78, 0x57, 0x61, 0x69, 0x74, 0x12, 0x44, 0x0a, + 0x1e, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x18, + 0x20, 0x20, 0x01, 0x28, 0x09, 0x52, 0x1c, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x44, + 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x79, 0x12, 0x34, 0x0a, 0x16, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x23, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x14, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x67, 0x65, 0x78, 0x12, 0x26, 0x0a, 0x0f, 0x64, 0x6f, 0x5f, + 0x6e, 0x6f, 0x74, 0x5f, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x18, 0x1a, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0d, 0x64, 0x6f, 0x4e, 0x6f, 0x74, 0x52, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, + 0x74, 0x22, 0xaf, 0x06, 0x0a, 0x0f, 0x44, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x26, 0x0a, 0x0e, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x69, + 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, + 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2f, 0x0a, 0x13, 0x66, 0x69, 0x6c, + 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x74, 0x6f, 0x72, + 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x0c, 0x6d, 0x61, + 0x78, 0x5f, 0x64, 0x69, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x0a, 0x6d, 0x61, 0x78, 0x44, 0x69, 0x72, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x36, 0x0a, 0x17, + 0x6d, 0x65, 0x6d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x65, 0x63, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x15, 0x6d, + 0x65, 0x6d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x45, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x53, 0x65, 0x63, 0x12, 0x43, 0x0a, 0x1e, 0x6d, 0x65, 0x6d, 0x63, 0x61, 0x63, 0x68, 0x65, + 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x1b, 0x6d, 0x65, + 0x6d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x57, 0x72, 0x69, 0x74, 0x65, 0x4d, 0x75, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x12, 0x45, 0x0a, 0x1f, 0x6d, 0x65, 0x6d, + 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x6d, 0x75, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x1c, 0x6d, 0x65, 0x6d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x57, 0x72, 0x69, 0x74, + 0x65, 0x4d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x72, 0x73, + 0x12, 0x44, 0x0a, 0x1f, 0x6d, 0x65, 0x6d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x77, 0x72, 0x69, + 0x74, 0x65, 0x5f, 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x69, 0x6e, 0x5f, + 0x61, 0x67, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x03, 0x52, 0x1b, 0x6d, 0x65, 0x6d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x57, 0x72, 0x69, 0x74, 0x65, 0x4d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x12, 0x45, 0x0a, 0x1f, 0x6d, 0x65, 0x6d, 0x63, 0x61, 0x63, + 0x4d, 0x69, 0x6e, 0x41, 0x67, 0x65, 0x12, 0x44, 0x0a, 0x1f, 0x6d, 0x65, 0x6d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x1c, 0x6d, 0x65, 0x6d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x57, 0x72, 0x69, 0x74, 0x65, 0x4d, 0x75, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x72, 0x73, 0x12, 0x44, 0x0a, - 0x1f, 0x6d, 0x65, 0x6d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, - 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x69, 0x6e, 0x5f, 0x61, 0x67, 0x65, - 0x18, 0x0e, 0x20, 0x01, 0x28, 0x03, 0x52, 0x1b, 0x6d, 0x65, 0x6d, 0x63, 0x61, 0x63, 0x68, 0x65, - 0x57, 0x72, 0x69, 0x74, 0x65, 0x4d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x69, 0x6e, - 0x41, 0x67, 0x65, 0x12, 0x44, 0x0a, 0x1f, 0x6d, 0x65, 0x6d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, - 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, - 0x61, 0x78, 0x5f, 0x61, 0x67, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x1b, 0x6d, 0x65, - 0x6d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x57, 0x72, 0x69, 0x74, 0x65, 0x4d, 0x75, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x78, 0x41, 0x67, 0x65, 0x12, 0x3d, 0x0a, 0x1b, 0x6d, 0x65, 0x6d, - 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, - 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x18, - 0x6d, 0x65, 0x6d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x44, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, - 0x65, 0x4d, 0x61, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x46, 0x0a, 0x20, 0x6d, 0x65, 0x6d, 0x63, - 0x61, 0x63, 0x68, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x6d, - 0x61, 0x78, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x0b, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x1c, 0x6d, 0x65, 0x6d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x44, 0x61, 0x74, 0x61, - 0x73, 0x74, 0x6f, 0x72, 0x65, 0x4d, 0x61, 0x78, 0x49, 0x74, 0x65, 0x6d, 0x53, 0x69, 0x7a, 0x65, - 0x12, 0x44, 0x0a, 0x1f, 0x6d, 0x65, 0x6d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x64, 0x61, 0x74, - 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x69, 0x72, 0x5f, 0x73, - 0x69, 0x7a, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x03, 0x52, 0x1b, 0x6d, 0x65, 0x6d, 0x63, 0x61, - 0x63, 0x68, 0x65, 0x44, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x4d, 0x61, 0x78, 0x44, - 0x69, 0x72, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x33, 0x0a, 0x15, 0x6d, 0x69, 0x6e, 0x69, 0x6f, 0x6e, - 0x5f, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x6d, 0x69, 0x6e, 0x69, 0x6f, 0x6e, 0x49, 0x6d, 0x70, - 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x33, 0x0a, 0x15, 0x6d, - 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x6d, 0x61, 0x73, 0x74, - 0x65, 0x72, 0x49, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x22, 0x89, 0x03, 0x0a, 0x0a, 0x4d, 0x61, 0x69, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, - 0x65, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x51, 0xe2, - 0xfc, 0xe3, 0xc4, 0x01, 0x4b, 0x12, 0x49, 0x57, 0x68, 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, - 0x20, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x2e, 0x20, 0x49, 0x66, 0x20, 0x6e, - 0x6f, 0x74, 0x20, 0x73, 0x65, 0x74, 0x20, 0x77, 0x65, 0x20, 0x75, 0x73, 0x65, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x2e, - 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x3b, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x23, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x1d, 0x12, 0x1b, - 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x53, - 0x4d, 0x54, 0x50, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x52, 0x06, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x12, 0x40, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x70, 0x6f, - 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x42, 0x1f, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x19, - 0x12, 0x17, 0x50, 0x6f, 0x72, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x53, 0x4d, - 0x54, 0x50, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x48, 0x0a, 0x0d, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x75, 0x73, - 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x23, 0xe2, 0xfc, - 0xe3, 0xc4, 0x01, 0x1d, 0x12, 0x1b, 0x4e, 0x61, 0x6d, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x75, - 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, - 0x2e, 0x52, 0x0c, 0x61, 0x75, 0x74, 0x68, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, - 0x4b, 0x0a, 0x0d, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x26, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x20, 0x12, 0x1e, - 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x75, 0x74, 0x68, - 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x2e, 0x52, 0x0c, - 0x61, 0x75, 0x74, 0x68, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x72, 0x0a, 0x16, - 0x4c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x72, - 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x6d, - 0x61, 0x78, 0x5f, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6d, 0x61, - 0x78, 0x41, 0x67, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, - 0x22, 0xd9, 0x04, 0x0a, 0x0d, 0x4c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x12, 0x75, 0x0a, 0x10, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x64, 0x69, 0x72, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x4a, 0xe2, 0xfc, - 0xe3, 0xc4, 0x01, 0x44, 0x12, 0x42, 0x54, 0x68, 0x65, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x20, 0x6c, 0x6f, 0x67, 0x20, - 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x20, 0x49, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x65, - 0x74, 0x20, 0x77, 0x65, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x20, 0x6e, 0x6f, 0x20, 0x6c, 0x6f, - 0x67, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x52, 0x0f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, - 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x7a, 0x0a, 0x1b, 0x73, 0x65, 0x70, - 0x61, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x63, - 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x42, 0x3b, - 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x35, 0x12, 0x33, 0x49, 0x66, 0x20, 0x73, 0x65, 0x74, 0x2c, 0x20, - 0x65, 0x61, 0x63, 0x68, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x20, 0x77, - 0x69, 0x6c, 0x6c, 0x20, 0x6c, 0x6f, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x73, 0x65, 0x70, - 0x61, 0x72, 0x61, 0x74, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x52, 0x18, 0x73, 0x65, 0x70, - 0x61, 0x72, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x50, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x70, - 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x4b, 0x0a, 0x0d, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x42, 0x26, 0xe2, 0xfc, - 0xe3, 0xc4, 0x01, 0x20, 0x12, 0x1e, 0x48, 0x6f, 0x77, 0x20, 0x6f, 0x66, 0x74, 0x65, 0x6e, 0x20, - 0x74, 0x6f, 0x20, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, - 0x6c, 0x65, 0x73, 0x2e, 0x52, 0x0c, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, - 0x6d, 0x65, 0x12, 0x6b, 0x0a, 0x07, 0x6d, 0x61, 0x78, 0x5f, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x04, 0x42, 0x52, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x4c, 0x12, 0x40, 0x4d, 0x61, 0x78, - 0x69, 0x6d, 0x75, 0x6d, 0x20, 0x61, 0x67, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x65, 0x61, 0x63, 0x68, - 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x28, 0x46, 0x69, 0x6c, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, - 0x20, 0x62, 0x65, 0x20, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x20, 0x61, 0x66, 0x74, 0x65, - 0x72, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x29, 0x2e, 0x32, 0x08, 0x33, - 0x31, 0x35, 0x33, 0x36, 0x30, 0x30, 0x30, 0x52, 0x06, 0x6d, 0x61, 0x78, 0x41, 0x67, 0x65, 0x12, - 0x33, 0x0a, 0x05, 0x64, 0x65, 0x62, 0x75, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x52, 0x65, - 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x05, 0x64, - 0x65, 0x62, 0x75, 0x67, 0x12, 0x31, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x6f, 0x67, 0x67, 0x69, - 0x6e, 0x67, 0x52, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x33, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, - 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xf8, 0x01, 0x0a, - 0x10, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x12, 0x9f, 0x01, 0x0a, 0x0c, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x7c, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x76, - 0x12, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x69, 0x6e, - 0x64, 0x20, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x65, 0x6e, 0x64, - 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x2e, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x73, 0x68, 0x6f, 0x75, - 0x6c, 0x64, 0x20, 0x75, 0x73, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, - 0x62, 0x65, 0x20, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x2c, 0x20, 0x6f, 0x74, - 0x68, 0x65, 0x72, 0x77, 0x69, 0x73, 0x65, 0x20, 0x62, 0x65, 0x20, 0x73, 0x75, 0x72, 0x65, 0x20, - 0x74, 0x6f, 0x20, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x6c, 0x79, 0x20, 0x73, 0x65, 0x63, 0x75, - 0x72, 0x65, 0x20, 0x69, 0x74, 0x2e, 0x52, 0x0b, 0x62, 0x69, 0x6e, 0x64, 0x41, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x12, 0x42, 0x0a, 0x09, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x70, 0x6f, 0x72, 0x74, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x25, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x1f, 0x12, 0x1d, - 0x50, 0x6f, 0x72, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x69, 0x6e, 0x64, 0x20, 0x6d, 0x6f, 0x6e, - 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x52, 0x08, 0x62, - 0x69, 0x6e, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x22, 0x68, 0x0a, 0x0e, 0x41, 0x75, 0x74, 0x6f, 0x45, - 0x78, 0x65, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x67, - 0x76, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x61, 0x72, 0x67, 0x76, 0x12, 0x42, 0x0a, - 0x14, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x13, 0x61, 0x72, - 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x22, 0xed, 0x08, 0x0a, 0x14, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x21, 0x0a, 0x0c, 0x68, 0x75, - 0x6e, 0x74, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x0b, 0x68, 0x75, 0x6e, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x12, 0x27, 0x0a, - 0x0f, 0x68, 0x75, 0x6e, 0x74, 0x5f, 0x64, 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x68, 0x75, 0x6e, 0x74, 0x44, 0x69, 0x73, 0x70, - 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, - 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0e, 0x73, 0x74, 0x61, 0x74, 0x73, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, - 0x2b, 0x0a, 0x11, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, - 0x72, 0x69, 0x6e, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x29, 0x0a, 0x10, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x72, - 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x79, 0x6e, 0x5f, 0x64, - 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x79, 0x6e, 0x44, 0x6e, 0x73, - 0x12, 0x24, 0x0a, 0x0d, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x6f, 0x67, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x6f, - 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x61, 0x6e, 0x69, 0x74, 0x79, - 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, - 0x73, 0x61, 0x6e, 0x69, 0x74, 0x79, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x12, 0x1f, 0x0a, - 0x0b, 0x76, 0x66, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x09, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x0a, 0x76, 0x66, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x21, - 0x0a, 0x0c, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x18, 0x0a, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, - 0x72, 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x6f, 0x6e, 0x69, - 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x63, 0x6c, - 0x69, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x2d, - 0x0a, 0x12, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x6d, 0x6f, 0x6e, 0x69, - 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x1d, 0x0a, - 0x0a, 0x61, 0x70, 0x69, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x0d, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x09, 0x61, 0x70, 0x69, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x27, 0x0a, 0x0f, - 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, - 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x53, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x75, 0x69, 0x5f, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x67, 0x75, 0x69, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x6e, 0x64, 0x65, - 0x78, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x27, 0x0a, 0x0f, 0x6a, 0x6f, 0x75, 0x72, 0x6e, - 0x61, 0x6c, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x0e, 0x6a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x12, 0x2f, 0x0a, 0x13, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x72, - 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x12, 0x31, 0x0a, 0x14, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x13, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x12, 0x2d, 0x0a, 0x12, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, - 0x72, 0x79, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x18, 0x13, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x11, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x61, 0x6e, 0x61, - 0x67, 0x65, 0x72, 0x12, 0x36, 0x0a, 0x17, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, - 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x18, 0x19, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x12, 0x2b, 0x0a, 0x11, 0x69, - 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, - 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x15, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x63, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, - 0x65, 0x6c, 0x18, 0x16, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, - 0x1a, 0x0a, 0x08, 0x6c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x65, 0x72, 0x18, 0x17, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x08, 0x6c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x10, 0x6e, - 0x6f, 0x74, 0x65, 0x62, 0x6f, 0x6f, 0x6b, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, - 0x18, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x6e, 0x6f, 0x74, 0x65, 0x62, 0x6f, 0x6f, 0x6b, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x2b, 0x0a, 0x11, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x63, - 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x1b, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x10, 0x68, 0x74, 0x74, 0x70, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, - 0x74, 0x6f, 0x72, 0x12, 0x2c, 0x0a, 0x12, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x65, 0x76, - 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x10, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x22, 0xea, 0x02, 0x0a, 0x08, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x2a, - 0x0a, 0x11, 0x68, 0x75, 0x6e, 0x74, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x5f, 0x68, 0x6f, - 0x75, 0x72, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x68, 0x75, 0x6e, 0x74, 0x45, - 0x78, 0x70, 0x69, 0x72, 0x79, 0x48, 0x6f, 0x75, 0x72, 0x73, 0x12, 0x39, 0x0a, 0x19, 0x6e, 0x6f, - 0x74, 0x65, 0x62, 0x6f, 0x6f, 0x6b, 0x5f, 0x63, 0x65, 0x6c, 0x6c, 0x5f, 0x74, 0x69, 0x6d, 0x65, - 0x6f, 0x75, 0x74, 0x5f, 0x6d, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x16, 0x6e, - 0x6f, 0x74, 0x65, 0x62, 0x6f, 0x6f, 0x6b, 0x43, 0x65, 0x6c, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x6f, - 0x75, 0x74, 0x4d, 0x69, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x73, 0x76, 0x5f, 0x64, 0x65, 0x6c, - 0x69, 0x6d, 0x69, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x73, - 0x76, 0x44, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x72, 0x12, 0x24, 0x0a, 0x0e, 0x65, 0x76, - 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x0c, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x78, 0x57, 0x61, 0x69, 0x74, - 0x12, 0x31, 0x0a, 0x15, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x77, 0x61, - 0x69, 0x74, 0x5f, 0x6a, 0x69, 0x74, 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x12, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x78, 0x57, 0x61, 0x69, 0x74, 0x4a, 0x69, 0x74, - 0x74, 0x65, 0x72, 0x12, 0x44, 0x0a, 0x1f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x5f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x5f, 0x61, 0x6c, 0x6c, 0x5f, 0x63, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x65, 0x76, - 0x65, 0x6e, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x41, - 0x6c, 0x6c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x33, 0x0a, 0x16, 0x6d, 0x61, 0x78, - 0x5f, 0x76, 0x66, 0x73, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x73, - 0x69, 0x7a, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13, 0x6d, 0x61, 0x78, 0x56, 0x66, - 0x73, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x2d, - 0x0a, 0x0c, 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1d, - 0x0a, 0x0a, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x72, 0x6f, 0x6f, 0x74, 0x43, 0x65, 0x72, 0x74, 0x73, 0x22, 0x5d, 0x0a, - 0x0a, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, - 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, - 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x74, 0x68, 0x54, 0x79, 0x70, 0x65, 0x22, 0xda, 0x02, 0x0a, - 0x0f, 0x52, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x74, 0x79, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4d, 0x6f, 0x75, - 0x6e, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x21, 0x0a, - 0x02, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2e, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x02, 0x6f, 0x6e, - 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, - 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, - 0x6f, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, - 0x0a, 0x03, 0x65, 0x6e, 0x76, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x51, 0x4c, 0x45, 0x6e, 0x76, 0x52, 0x03, 0x65, 0x6e, 0x76, 0x12, - 0x2d, 0x0a, 0x12, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f, 0x66, 0x75, 0x6e, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x64, 0x69, 0x73, - 0x61, 0x62, 0x6c, 0x65, 0x64, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x29, - 0x0a, 0x10, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f, 0x70, 0x6c, 0x75, 0x67, 0x69, - 0x6e, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, - 0x65, 0x64, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x22, 0xf5, 0x0b, 0x0a, 0x06, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2b, 0x0a, 0x0f, 0x61, 0x75, 0x74, 0x6f, 0x63, 0x65, 0x72, 0x74, - 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, - 0x01, 0x52, 0x0e, 0x61, 0x75, 0x74, 0x6f, 0x63, 0x65, 0x72, 0x74, 0x44, 0x6f, 0x6d, 0x61, 0x69, - 0x6e, 0x12, 0x46, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x42, 0x1c, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x16, 0x12, 0x14, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, - 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x4a, 0x0a, 0x06, 0x43, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x1d, - 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x17, 0x12, 0x15, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x06, 0x43, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x50, 0x0a, 0x03, 0x41, 0x50, 0x49, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x50, 0x49, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x42, 0x2c, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x26, 0x12, 0x24, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x6f, 0x72, 0x20, - 0x67, 0x52, 0x50, 0x43, 0x20, 0x41, 0x50, 0x49, 0x20, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, - 0x74, 0x2e, 0x52, 0x03, 0x41, 0x50, 0x49, 0x12, 0x22, 0x0a, 0x03, 0x47, 0x55, 0x49, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x55, 0x49, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x03, 0x47, 0x55, 0x49, 0x12, 0x1f, 0x0a, 0x02, 0x43, - 0x41, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, - 0x43, 0x41, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x02, 0x43, 0x41, 0x12, 0x31, 0x0a, 0x08, - 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x08, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x12, - 0x3d, 0x0a, 0x0e, 0x45, 0x78, 0x74, 0x72, 0x61, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, - 0x73, 0x18, 0x1f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, - 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0e, - 0x45, 0x78, 0x74, 0x72, 0x61, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x73, 0x12, 0x34, - 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x73, 0x74, - 0x6f, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x09, 0x44, 0x61, 0x74, 0x61, 0x73, - 0x74, 0x6f, 0x72, 0x65, 0x12, 0x32, 0x0a, 0x09, 0x57, 0x72, 0x69, 0x74, 0x65, 0x62, 0x61, 0x63, - 0x6b, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, - 0x57, 0x72, 0x69, 0x74, 0x65, 0x62, 0x61, 0x63, 0x6b, 0x42, 0x02, 0x18, 0x01, 0x52, 0x09, 0x57, - 0x72, 0x69, 0x74, 0x65, 0x62, 0x61, 0x63, 0x6b, 0x12, 0x25, 0x0a, 0x04, 0x4d, 0x61, 0x69, 0x6c, - 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4d, - 0x61, 0x69, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x04, 0x4d, 0x61, 0x69, 0x6c, 0x12, - 0x2e, 0x0a, 0x07, 0x4c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x07, 0x4c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x12, - 0x40, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, - 0x42, 0x26, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x20, 0x12, 0x1e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, - 0x20, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x20, 0x6c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, - 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x2e, 0x52, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, - 0x65, 0x12, 0x5c, 0x0a, 0x13, 0x61, 0x75, 0x74, 0x6f, 0x63, 0x65, 0x72, 0x74, 0x5f, 0x63, 0x65, - 0x72, 0x74, 0x5f, 0x63, 0x61, 0x63, 0x68, 0x65, 0x18, 0x16, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2c, - 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x26, 0x12, 0x24, 0x50, 0x61, 0x74, 0x68, 0x20, 0x74, 0x6f, 0x20, - 0x73, 0x74, 0x6f, 0x72, 0x65, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x63, 0x65, 0x72, 0x74, 0x20, 0x63, - 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x52, 0x11, 0x61, 0x75, - 0x74, 0x6f, 0x63, 0x65, 0x72, 0x74, 0x43, 0x65, 0x72, 0x74, 0x43, 0x61, 0x63, 0x68, 0x65, 0x12, - 0x6e, 0x0a, 0x0a, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x19, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, - 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x35, 0xe2, 0xfc, - 0xe3, 0xc4, 0x01, 0x2f, 0x12, 0x2d, 0x57, 0x68, 0x65, 0x72, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x62, - 0x69, 0x6e, 0x64, 0x20, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x20, 0x6d, - 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, - 0x6e, 0x74, 0x2e, 0x52, 0x0a, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x12, - 0x7f, 0x0a, 0x0a, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x1a, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x70, 0x69, 0x43, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x48, 0xe2, 0xfc, 0xe3, - 0xc4, 0x01, 0x42, 0x12, 0x40, 0x49, 0x66, 0x20, 0x77, 0x65, 0x20, 0x6c, 0x6f, 0x61, 0x64, 0x65, - 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x70, 0x69, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x20, 0x77, 0x65, 0x20, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x6e, - 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x52, 0x09, 0x61, 0x70, 0x69, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x12, 0x8f, 0x01, 0x0a, 0x08, 0x61, 0x75, 0x74, 0x6f, 0x65, 0x78, 0x65, 0x63, 0x18, 0x1c, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x75, 0x74, 0x6f, - 0x45, 0x78, 0x65, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x5c, 0xe2, 0xfc, 0xe3, 0xc4, - 0x01, 0x56, 0x12, 0x54, 0x49, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x73, - 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x77, 0x65, 0x20, 0x6c, 0x61, 0x75, 0x6e, - 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x20, 0x77, 0x69, - 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x20, 0x63, 0x6f, 0x6d, - 0x6d, 0x61, 0x6e, 0x64, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x6d, 0x61, - 0x74, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x2e, 0x52, 0x08, 0x61, 0x75, 0x74, 0x6f, 0x65, 0x78, - 0x65, 0x63, 0x12, 0x50, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x74, 0x79, 0x70, - 0x65, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2f, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x29, 0x12, - 0x27, 0x54, 0x79, 0x70, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, - 0x28, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x2c, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x2c, - 0x20, 0x64, 0x61, 0x72, 0x77, 0x69, 0x6e, 0x29, 0x52, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x2b, 0x0a, 0x11, 0x6f, 0x62, 0x66, 0x75, 0x73, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x20, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x10, 0x6f, 0x62, 0x66, 0x75, 0x73, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x6f, 0x6e, 0x63, - 0x65, 0x12, 0x2b, 0x0a, 0x08, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x21, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x65, 0x66, 0x61, - 0x75, 0x6c, 0x74, 0x73, 0x52, 0x08, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x27, - 0x0a, 0x0f, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, - 0x74, 0x18, 0x22, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, - 0x73, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x36, 0x0a, 0x0a, 0x72, 0x65, 0x6d, 0x61, 0x70, - 0x70, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x23, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x52, 0x0a, 0x72, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x12, - 0x15, 0x0a, 0x06, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x24, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x6f, 0x72, 0x67, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x72, 0x67, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x25, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x72, 0x67, 0x4e, 0x61, 0x6d, - 0x65, 0x42, 0x34, 0x5a, 0x32, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x64, - 0x65, 0x78, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x76, 0x65, - 0x6c, 0x6f, 0x63, 0x69, 0x72, 0x61, 0x70, 0x74, 0x6f, 0x72, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6e, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x61, 0x67, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x1b, 0x6d, 0x65, 0x6d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x57, 0x72, 0x69, 0x74, 0x65, 0x4d, 0x75, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x78, 0x41, 0x67, 0x65, 0x12, 0x3d, 0x0a, 0x1b, + 0x6d, 0x65, 0x6d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, + 0x72, 0x65, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x18, 0x6d, 0x65, 0x6d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x44, 0x61, 0x74, 0x61, 0x73, + 0x74, 0x6f, 0x72, 0x65, 0x4d, 0x61, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x46, 0x0a, 0x20, 0x6d, + 0x65, 0x6d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, + 0x65, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, + 0x0b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x1c, 0x6d, 0x65, 0x6d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x44, + 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x4d, 0x61, 0x78, 0x49, 0x74, 0x65, 0x6d, 0x53, + 0x69, 0x7a, 0x65, 0x12, 0x44, 0x0a, 0x1f, 0x6d, 0x65, 0x6d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, + 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x69, + 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x03, 0x52, 0x1b, 0x6d, 0x65, + 0x6d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x44, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x4d, + 0x61, 0x78, 0x44, 0x69, 0x72, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x33, 0x0a, 0x15, 0x6d, 0x69, 0x6e, + 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x6d, 0x69, 0x6e, 0x69, 0x6f, 0x6e, + 0x49, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x33, + 0x0a, 0x15, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x6d, + 0x61, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x22, 0x89, 0x03, 0x0a, 0x0a, 0x4d, 0x61, 0x69, 0x6c, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x12, 0x65, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x51, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x4b, 0x12, 0x49, 0x57, 0x68, 0x65, 0x72, 0x65, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, + 0x20, 0x62, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x2e, 0x20, 0x49, + 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x65, 0x74, 0x20, 0x77, 0x65, 0x20, 0x75, 0x73, 0x65, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, + 0x6d, 0x65, 0x2e, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x3b, 0x0a, 0x06, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x23, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, + 0x1d, 0x12, 0x1b, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x53, 0x4d, 0x54, 0x50, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x52, 0x06, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x40, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x42, 0x1f, 0xe2, 0xfc, 0xe3, + 0xc4, 0x01, 0x19, 0x12, 0x17, 0x50, 0x6f, 0x72, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x53, 0x4d, 0x54, 0x50, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x0a, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x48, 0x0a, 0x0d, 0x61, 0x75, 0x74, 0x68, + 0x5f, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x23, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x1d, 0x12, 0x1b, 0x4e, 0x61, 0x6d, 0x65, 0x20, 0x74, 0x6f, + 0x20, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x75, 0x6e, + 0x64, 0x65, 0x72, 0x2e, 0x52, 0x0c, 0x61, 0x75, 0x74, 0x68, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x4b, 0x0a, 0x0d, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x77, + 0x6f, 0x72, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x26, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, + 0x20, 0x12, 0x1e, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x61, + 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, + 0x2e, 0x52, 0x0c, 0x61, 0x75, 0x74, 0x68, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, + 0x72, 0x0a, 0x16, 0x4c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x74, 0x65, 0x6e, 0x74, + 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x6f, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x0c, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x17, + 0x0a, 0x07, 0x6d, 0x61, 0x78, 0x5f, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x06, 0x6d, 0x61, 0x78, 0x41, 0x67, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, + 0x6c, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, + 0x6c, 0x65, 0x64, 0x22, 0xd9, 0x04, 0x0a, 0x0d, 0x4c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x75, 0x0a, 0x10, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, + 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x4a, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x44, 0x12, 0x42, 0x54, 0x68, 0x65, 0x20, 0x6c, 0x6f, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x20, 0x6c, + 0x6f, 0x67, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x20, 0x49, 0x66, 0x20, 0x6e, 0x6f, 0x74, + 0x20, 0x73, 0x65, 0x74, 0x20, 0x77, 0x65, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x20, 0x6e, 0x6f, + 0x20, 0x6c, 0x6f, 0x67, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x52, 0x0f, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x7a, 0x0a, 0x1b, + 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x5f, 0x70, 0x65, + 0x72, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x08, 0x42, 0x3b, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x35, 0x12, 0x33, 0x49, 0x66, 0x20, 0x73, 0x65, + 0x74, 0x2c, 0x20, 0x65, 0x61, 0x63, 0x68, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, + 0x74, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x6c, 0x6f, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x20, + 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x52, 0x18, + 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x50, 0x65, 0x72, 0x43, + 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x4b, 0x0a, 0x0d, 0x72, 0x6f, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x42, + 0x26, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x20, 0x12, 0x1e, 0x48, 0x6f, 0x77, 0x20, 0x6f, 0x66, 0x74, + 0x65, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x52, 0x0c, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x6b, 0x0a, 0x07, 0x6d, 0x61, 0x78, 0x5f, 0x61, 0x67, 0x65, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x42, 0x52, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x4c, 0x12, 0x40, + 0x4d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x20, 0x61, 0x67, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x65, + 0x61, 0x63, 0x68, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x28, 0x46, 0x69, 0x6c, 0x65, 0x20, 0x77, + 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x20, 0x61, + 0x66, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x29, 0x2e, + 0x32, 0x08, 0x33, 0x31, 0x35, 0x33, 0x36, 0x30, 0x30, 0x30, 0x52, 0x06, 0x6d, 0x61, 0x78, 0x41, + 0x67, 0x65, 0x12, 0x33, 0x0a, 0x05, 0x64, 0x65, 0x62, 0x75, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x6f, 0x67, 0x67, 0x69, 0x6e, + 0x67, 0x52, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x52, 0x05, 0x64, 0x65, 0x62, 0x75, 0x67, 0x12, 0x31, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x6f, + 0x67, 0x67, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x33, 0x0a, 0x05, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x4c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, + 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, + 0xf8, 0x01, 0x0a, 0x10, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x12, 0x9f, 0x01, 0x0a, 0x0c, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x61, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x7c, 0xe2, 0xfc, 0xe3, + 0xc4, 0x01, 0x76, 0x12, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x74, 0x6f, 0x20, + 0x62, 0x69, 0x6e, 0x64, 0x20, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x20, + 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x2e, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x73, + 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x75, 0x73, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x6f, 0x6e, + 0x6c, 0x79, 0x20, 0x62, 0x65, 0x20, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x2c, + 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x77, 0x69, 0x73, 0x65, 0x20, 0x62, 0x65, 0x20, 0x73, 0x75, + 0x72, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x6c, 0x79, 0x20, 0x73, + 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x69, 0x74, 0x2e, 0x52, 0x0b, 0x62, 0x69, 0x6e, 0x64, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x42, 0x0a, 0x09, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x70, + 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x25, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, + 0x1f, 0x12, 0x1d, 0x50, 0x6f, 0x72, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x69, 0x6e, 0x64, 0x20, + 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x52, 0x08, 0x62, 0x69, 0x6e, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x22, 0x68, 0x0a, 0x0e, 0x41, 0x75, + 0x74, 0x6f, 0x45, 0x78, 0x65, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a, 0x04, + 0x61, 0x72, 0x67, 0x76, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x61, 0x72, 0x67, 0x76, + 0x12, 0x42, 0x0a, 0x14, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x64, 0x65, 0x66, + 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, + 0x13, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xed, 0x08, 0x0a, 0x14, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x21, 0x0a, + 0x0c, 0x68, 0x75, 0x6e, 0x74, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0b, 0x68, 0x75, 0x6e, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, + 0x12, 0x27, 0x0a, 0x0f, 0x68, 0x75, 0x6e, 0x74, 0x5f, 0x64, 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, + 0x68, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x68, 0x75, 0x6e, 0x74, 0x44, + 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x74, 0x61, + 0x74, 0x73, 0x5f, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0e, 0x73, 0x74, 0x61, 0x74, 0x73, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x12, 0x2b, 0x0a, 0x11, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x6d, 0x6f, 0x6e, + 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x12, + 0x29, 0x0a, 0x10, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x79, + 0x6e, 0x5f, 0x64, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x79, 0x6e, + 0x44, 0x6e, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x6f, 0x67, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x72, 0x6f, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x61, 0x6e, + 0x69, 0x74, 0x79, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0d, 0x73, 0x61, 0x6e, 0x69, 0x74, 0x79, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, + 0x12, 0x1f, 0x0a, 0x0b, 0x76, 0x66, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x76, 0x66, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, + 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x4d, 0x61, 0x6e, + 0x61, 0x67, 0x65, 0x72, 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x6d, + 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x10, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, + 0x67, 0x12, 0x2d, 0x0a, 0x12, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x5f, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x6d, + 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x70, 0x69, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x0d, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x70, 0x69, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, + 0x27, 0x0a, 0x0f, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x5f, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x64, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x75, 0x69, 0x5f, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x67, 0x75, + 0x69, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x6e, 0x64, 0x65, 0x78, + 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x27, 0x0a, 0x0f, 0x6a, 0x6f, + 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x11, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0e, 0x6a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x2f, 0x0a, 0x13, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x12, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x12, 0x31, 0x0a, 0x14, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x12, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x13, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x2d, 0x0a, 0x12, 0x72, 0x65, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x18, 0x13, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x11, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x4d, + 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x12, 0x36, 0x0a, 0x17, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, + 0x72, 0x18, 0x19, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x12, 0x2b, + 0x0a, 0x11, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x69, 0x6e, 0x76, 0x65, 0x6e, + 0x74, 0x6f, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x15, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x14, 0x0a, 0x05, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x16, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x65, 0x72, 0x18, 0x17, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x65, 0x72, 0x12, 0x29, + 0x0a, 0x10, 0x6e, 0x6f, 0x74, 0x65, 0x62, 0x6f, 0x6f, 0x6b, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x18, 0x18, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x6e, 0x6f, 0x74, 0x65, 0x62, 0x6f, + 0x6f, 0x6b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x2b, 0x0a, 0x11, 0x68, 0x74, 0x74, + 0x70, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x1b, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x68, 0x74, 0x74, 0x70, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, + 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x2c, 0x0a, 0x12, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x1c, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x10, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x22, 0xea, 0x02, 0x0a, 0x08, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, + 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x68, 0x75, 0x6e, 0x74, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, + 0x5f, 0x68, 0x6f, 0x75, 0x72, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x68, 0x75, + 0x6e, 0x74, 0x45, 0x78, 0x70, 0x69, 0x72, 0x79, 0x48, 0x6f, 0x75, 0x72, 0x73, 0x12, 0x39, 0x0a, + 0x19, 0x6e, 0x6f, 0x74, 0x65, 0x62, 0x6f, 0x6f, 0x6b, 0x5f, 0x63, 0x65, 0x6c, 0x6c, 0x5f, 0x74, + 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x6d, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x16, 0x6e, 0x6f, 0x74, 0x65, 0x62, 0x6f, 0x6f, 0x6b, 0x43, 0x65, 0x6c, 0x6c, 0x54, 0x69, + 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x69, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x73, 0x76, 0x5f, + 0x64, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0c, 0x63, 0x73, 0x76, 0x44, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x72, 0x12, 0x24, 0x0a, + 0x0e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x78, 0x57, + 0x61, 0x69, 0x74, 0x12, 0x31, 0x0a, 0x15, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x61, 0x78, + 0x5f, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x6a, 0x69, 0x74, 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x12, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x78, 0x57, 0x61, 0x69, 0x74, + 0x4a, 0x69, 0x74, 0x74, 0x65, 0x72, 0x12, 0x44, 0x0a, 0x1f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, + 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x5f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x5f, 0x61, 0x6c, + 0x6c, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x1b, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4e, 0x6f, 0x74, 0x69, + 0x66, 0x79, 0x41, 0x6c, 0x6c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x33, 0x0a, 0x16, + 0x6d, 0x61, 0x78, 0x5f, 0x76, 0x66, 0x73, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x79, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13, 0x6d, 0x61, + 0x78, 0x56, 0x66, 0x73, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x69, 0x7a, + 0x65, 0x22, 0x2d, 0x0a, 0x0c, 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x6f, 0x6f, 0x74, 0x43, 0x65, 0x72, 0x74, 0x73, + 0x22, 0x5d, 0x0a, 0x0a, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x1a, + 0x0a, 0x08, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, + 0x65, 0x66, 0x69, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x72, 0x65, 0x66, + 0x69, 0x78, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x74, 0x68, 0x54, 0x79, 0x70, 0x65, 0x22, + 0xda, 0x02, 0x0a, 0x0f, 0x52, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x04, 0x66, 0x72, 0x6f, + 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, + 0x12, 0x21, 0x0a, 0x02, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, + 0x02, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x02, 0x6f, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x1f, 0x0a, 0x03, 0x65, 0x6e, 0x76, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x51, 0x4c, 0x45, 0x6e, 0x76, 0x52, 0x03, 0x65, + 0x6e, 0x76, 0x12, 0x2d, 0x0a, 0x12, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, + 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x29, 0x0a, 0x10, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f, 0x70, 0x6c, + 0x75, 0x67, 0x69, 0x6e, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x64, 0x69, 0x73, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x22, 0xf5, 0x0b, 0x0a, + 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2b, 0x0a, 0x0f, 0x61, 0x75, 0x74, 0x6f, 0x63, + 0x65, 0x72, 0x74, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x02, 0x18, 0x01, 0x52, 0x0e, 0x61, 0x75, 0x74, 0x6f, 0x63, 0x65, 0x72, 0x74, 0x44, 0x6f, + 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x46, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x1c, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x16, 0x12, 0x14, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x4a, 0x0a, 0x06, + 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x42, 0x1d, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x17, 0x12, 0x15, 0x43, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x52, 0x06, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x50, 0x0a, 0x03, 0x41, 0x50, 0x49, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x50, + 0x49, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x2c, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x26, 0x12, + 0x24, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, + 0x6f, 0x72, 0x20, 0x67, 0x52, 0x50, 0x43, 0x20, 0x41, 0x50, 0x49, 0x20, 0x65, 0x6e, 0x64, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x2e, 0x52, 0x03, 0x41, 0x50, 0x49, 0x12, 0x22, 0x0a, 0x03, 0x47, 0x55, + 0x49, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x47, 0x55, 0x49, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x03, 0x47, 0x55, 0x49, 0x12, 0x1f, + 0x0a, 0x02, 0x43, 0x41, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x43, 0x41, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x02, 0x43, 0x41, 0x12, + 0x31, 0x0a, 0x08, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x08, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x64, 0x12, 0x3d, 0x0a, 0x0e, 0x45, 0x78, 0x74, 0x72, 0x61, 0x46, 0x72, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x64, 0x73, 0x18, 0x1f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x52, 0x0e, 0x45, 0x78, 0x74, 0x72, 0x61, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, + 0x73, 0x12, 0x34, 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x61, 0x74, + 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x09, 0x44, 0x61, + 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x32, 0x0a, 0x09, 0x57, 0x72, 0x69, 0x74, 0x65, + 0x62, 0x61, 0x63, 0x6b, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x62, 0x61, 0x63, 0x6b, 0x42, 0x02, 0x18, 0x01, + 0x52, 0x09, 0x57, 0x72, 0x69, 0x74, 0x65, 0x62, 0x61, 0x63, 0x6b, 0x12, 0x25, 0x0a, 0x04, 0x4d, + 0x61, 0x69, 0x6c, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x4d, 0x61, 0x69, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x04, 0x4d, 0x61, + 0x69, 0x6c, 0x12, 0x2e, 0x0a, 0x07, 0x4c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x18, 0x17, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x6f, 0x67, 0x67, + 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x07, 0x4c, 0x6f, 0x67, 0x67, 0x69, + 0x6e, 0x67, 0x12, 0x40, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x18, 0x14, 0x20, + 0x01, 0x28, 0x08, 0x42, 0x26, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x20, 0x12, 0x1e, 0x45, 0x6e, 0x61, + 0x62, 0x6c, 0x65, 0x20, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x20, 0x6c, 0x6f, 0x67, 0x67, + 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x2e, 0x52, 0x07, 0x76, 0x65, 0x72, + 0x62, 0x6f, 0x73, 0x65, 0x12, 0x5c, 0x0a, 0x13, 0x61, 0x75, 0x74, 0x6f, 0x63, 0x65, 0x72, 0x74, + 0x5f, 0x63, 0x65, 0x72, 0x74, 0x5f, 0x63, 0x61, 0x63, 0x68, 0x65, 0x18, 0x16, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x2c, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x26, 0x12, 0x24, 0x50, 0x61, 0x74, 0x68, 0x20, + 0x74, 0x6f, 0x20, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x63, 0x65, 0x72, + 0x74, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x52, + 0x11, 0x61, 0x75, 0x74, 0x6f, 0x63, 0x65, 0x72, 0x74, 0x43, 0x65, 0x72, 0x74, 0x43, 0x61, 0x63, + 0x68, 0x65, 0x12, 0x6e, 0x0a, 0x0a, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, + 0x18, 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4d, + 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, + 0x35, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x2f, 0x12, 0x2d, 0x57, 0x68, 0x65, 0x72, 0x65, 0x20, 0x74, + 0x6f, 0x20, 0x62, 0x69, 0x6e, 0x64, 0x20, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, + 0x73, 0x20, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x65, 0x6e, 0x64, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x2e, 0x52, 0x0a, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, + 0x6e, 0x67, 0x12, 0x7f, 0x0a, 0x0a, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x18, 0x1a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, + 0x70, 0x69, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x48, + 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x42, 0x12, 0x40, 0x49, 0x66, 0x20, 0x77, 0x65, 0x20, 0x6c, 0x6f, + 0x61, 0x64, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x70, 0x69, 0x20, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x20, 0x77, 0x65, 0x20, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x74, 0x68, 0x69, 0x73, + 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, + 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x52, 0x09, 0x61, 0x70, 0x69, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x12, 0x8f, 0x01, 0x0a, 0x08, 0x61, 0x75, 0x74, 0x6f, 0x65, 0x78, 0x65, 0x63, + 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, + 0x75, 0x74, 0x6f, 0x45, 0x78, 0x65, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x5c, 0xe2, + 0xfc, 0xe3, 0xc4, 0x01, 0x56, 0x12, 0x54, 0x49, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, + 0x73, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x77, 0x65, 0x20, 0x6c, + 0x61, 0x75, 0x6e, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x20, + 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x61, 0x75, 0x74, + 0x6f, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x2e, 0x52, 0x08, 0x61, 0x75, 0x74, + 0x6f, 0x65, 0x78, 0x65, 0x63, 0x12, 0x50, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2f, 0xe2, 0xfc, 0xe3, 0xc4, + 0x01, 0x29, 0x12, 0x27, 0x54, 0x79, 0x70, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x20, 0x28, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x2c, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x6f, + 0x77, 0x73, 0x2c, 0x20, 0x64, 0x61, 0x72, 0x77, 0x69, 0x6e, 0x29, 0x52, 0x0a, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x2b, 0x0a, 0x11, 0x6f, 0x62, 0x66, 0x75, 0x73, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x20, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x10, 0x6f, 0x62, 0x66, 0x75, 0x73, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, + 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x2b, 0x0a, 0x08, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, + 0x18, 0x21, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, + 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x52, 0x08, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, + 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x5f, 0x74, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x18, 0x22, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x61, 0x6e, 0x61, 0x6c, + 0x79, 0x73, 0x69, 0x73, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x36, 0x0a, 0x0a, 0x72, 0x65, + 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x23, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0a, 0x72, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, + 0x67, 0x73, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x24, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x6f, 0x72, 0x67, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x72, 0x67, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x25, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x72, 0x67, + 0x4e, 0x61, 0x6d, 0x65, 0x42, 0x34, 0x5a, 0x32, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x6c, 0x6f, + 0x63, 0x69, 0x64, 0x65, 0x78, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, + 0x2f, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x72, 0x61, 0x70, 0x74, 0x6f, 0x72, 0x2f, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( diff --git a/config/proto/config.proto b/config/proto/config.proto index aed5127a7b..06ab82a71e 100644 --- a/config/proto/config.proto +++ b/config/proto/config.proto @@ -279,6 +279,23 @@ message ApiClientConfig { message GUILink { string text = 1; string url = 2; + string icon_url = 3; + + // This can be "sidebar" (default), "context" + string type = 4; + + // If set we open in new tab + bool new_tab = 5; + + // Encode value first using this (can be "plain", "base64") + string encode = 6; + string parameter = 7; + + // Can be GET (default) or POST + string method = 8; + + // If set we ignore this entry completely + bool disabled = 9; } message Authenticator { @@ -377,8 +394,9 @@ message GUIConfig { description: "Additional links to present in the GUI." }]; - // These users are created if they do no already exist in the data - // store. + // These users are created with administrator role if they do not + // already exist in the data store. This is useful for + // initializing the server with some valid administrators. repeated GUIUser initial_users = 17; // The authenticator to use - can not be null. @@ -405,7 +423,6 @@ message GUIUser { string name = 1; string password_hash = 2; string password_salt = 3; - } message CAConfig { diff --git a/constants/constants.go b/constants/constants.go index 802591e0ff..108fccbc93 100644 --- a/constants/constants.go +++ b/constants/constants.go @@ -23,7 +23,7 @@ import ( ) const ( - VERSION = "0.6.6-rc2" + VERSION = "0.6.6" ENROLLMENT_WELL_KNOWN_FLOW = "E:Enrol" MONITORING_WELL_KNOWN_FLOW = FLOW_PREFIX + "Monitoring" diff --git a/crypto/proto/jobs.pb.go b/crypto/proto/jobs.pb.go index dcf856ee44..7a6a33dff3 100644 --- a/crypto/proto/jobs.pb.go +++ b/crypto/proto/jobs.pb.go @@ -755,6 +755,8 @@ type VeloStatus struct { Duration int64 `protobuf:"varint,4,opt,name=duration,proto3" json:"duration,omitempty"` // A List of artifacts that had some results. NamesWithResponse []string `protobuf:"bytes,5,rep,name=names_with_response,json=namesWithResponse,proto3" json:"names_with_response,omitempty"` + // The artifact that this status refers to + Artifact string `protobuf:"bytes,10,opt,name=Artifact,proto3" json:"Artifact,omitempty"` // How many log rows we generated LogRows int64 `protobuf:"varint,6,opt,name=log_rows,json=logRows,proto3" json:"log_rows,omitempty"` ResultRows int64 `protobuf:"varint,7,opt,name=result_rows,json=resultRows,proto3" json:"result_rows,omitempty"` @@ -831,6 +833,13 @@ func (x *VeloStatus) GetNamesWithResponse() []string { return nil } +func (x *VeloStatus) GetArtifact() string { + if x != nil { + return x.Artifact + } + return "" +} + func (x *VeloStatus) GetLogRows() int64 { if x != nil { return x.LogRows @@ -1506,7 +1515,7 @@ var file_jobs_proto_rawDesc = []byte{ 0x65, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x63, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x63, 0x6e, 0x22, 0x20, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x07, 0x0a, 0x03, 0x43, 0x53, 0x52, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x43, 0x52, 0x54, 0x10, 0x01, 0x12, 0x06, 0x0a, 0x02, - 0x43, 0x41, 0x10, 0x02, 0x22, 0xfe, 0x02, 0x0a, 0x0a, 0x56, 0x65, 0x6c, 0x6f, 0x53, 0x74, 0x61, + 0x43, 0x41, 0x10, 0x02, 0x22, 0x9a, 0x03, 0x0a, 0x0a, 0x56, 0x65, 0x6c, 0x6f, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x38, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x65, 0x6c, 0x6f, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x53, @@ -1519,146 +1528,148 @@ var file_jobs_proto_rawDesc = []byte{ 0x28, 0x03, 0x52, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x13, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x6e, 0x61, 0x6d, 0x65, 0x73, - 0x57, 0x69, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, - 0x6c, 0x6f, 0x67, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, - 0x6c, 0x6f, 0x67, 0x52, 0x6f, 0x77, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x65, - 0x73, 0x75, 0x6c, 0x74, 0x52, 0x6f, 0x77, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x5f, 0x69, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x71, 0x75, 0x65, - 0x72, 0x69, 0x65, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x74, 0x6f, 0x74, 0x61, - 0x6c, 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x22, 0x2b, 0x0a, 0x0e, 0x52, 0x65, 0x74, 0x75, - 0x72, 0x6e, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x06, 0x0a, 0x02, 0x4f, 0x4b, - 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x49, 0x43, 0x5f, 0x45, 0x52, - 0x52, 0x4f, 0x52, 0x10, 0x0a, 0x22, 0x33, 0x0a, 0x0b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x4c, 0x69, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x03, 0x6a, 0x6f, 0x62, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x65, 0x6c, 0x6f, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x03, 0x6a, 0x6f, 0x62, 0x22, 0xf0, 0x05, 0x0a, 0x11, 0x50, - 0x61, 0x63, 0x6b, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, - 0x12, 0x4a, 0x0a, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x61, - 0x63, 0x6b, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x2e, - 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, - 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0c, 0x52, 0x0b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, - 0x6c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x04, 0x42, 0x4e, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x48, 0x0a, 0x0b, 0x52, 0x44, 0x46, 0x44, - 0x61, 0x74, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x39, 0x54, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x73, 0x20, 0x69, 0x74, 0x73, 0x20, 0x74, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x72, 0x65, 0x76, 0x65, - 0x6e, 0x74, 0x20, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x20, 0x61, 0x74, 0x74, 0x61, 0x63, 0x6b, - 0x73, 0x2e, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0xc6, 0x03, - 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x42, 0xaf, 0x03, - 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0xa8, 0x03, 0x12, 0xa5, 0x03, 0x41, 0x20, 0x73, 0x68, 0x61, 0x72, - 0x65, 0x64, 0x20, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x61, 0x6e, 0x64, 0x20, - 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x6d, 0x75, 0x73, - 0x74, 0x20, 0x62, 0x65, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x20, 0x75, 0x73, 0x65, 0x73, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x74, - 0x6f, 0x20, 0x65, 0x6e, 0x73, 0x75, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x20, 0x62, 0x65, 0x6c, 0x6f, 0x6e, 0x67, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, - 0x6e, 0x74, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x2e, 0x20, 0x57, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x63, - 0x68, 0x65, 0x63, 0x6b, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, - 0x6d, 0x61, 0x79, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x61, - 0x6e, 0x79, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x20, 0x4e, 0x4f, 0x54, 0x45, 0x20, - 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x77, 0x65, 0x61, 0x6b, 0x20, 0x63, - 0x68, 0x65, 0x63, 0x6b, 0x20, 0x2d, 0x20, 0x61, 0x6e, 0x79, 0x6f, 0x6e, 0x65, 0x20, 0x77, 0x68, - 0x6f, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x6f, 0x6d, 0x69, 0x73, 0x65, 0x73, 0x20, 0x61, 0x20, - 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x64, - 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x65, 0x78, - 0x74, 0x72, 0x61, 0x63, 0x74, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x6e, 0x63, 0x65, - 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6f, 0x20, - 0x74, 0x68, 0x61, 0x74, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2c, 0x20, 0x62, 0x75, 0x74, - 0x20, 0x69, 0x74, 0x20, 0x6d, 0x61, 0x6b, 0x65, 0x73, 0x20, 0x69, 0x74, 0x20, 0x61, 0x20, 0x6c, - 0x69, 0x74, 0x74, 0x6c, 0x65, 0x20, 0x68, 0x61, 0x72, 0x64, 0x65, 0x72, 0x20, 0x74, 0x6f, 0x20, - 0x6a, 0x6f, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x56, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x72, 0x61, 0x70, - 0x74, 0x6f, 0x72, 0x20, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x52, - 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x22, 0x35, 0x0a, 0x0f, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x0c, 0x55, 0x4e, 0x43, - 0x4f, 0x4d, 0x50, 0x52, 0x45, 0x53, 0x53, 0x45, 0x44, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x5a, - 0x43, 0x4f, 0x4d, 0x50, 0x52, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x22, 0xa4, 0x02, - 0x0a, 0x10, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, - 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x27, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0c, 0x42, 0x15, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x0f, 0x0a, 0x0d, 0x45, 0x6e, 0x63, - 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, - 0x36, 0x0a, 0x0b, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x69, 0x76, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0c, 0x42, 0x15, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x0f, 0x0a, 0x0d, 0x45, 0x6e, - 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x52, 0x0a, 0x6d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x49, 0x76, 0x12, 0x30, 0x0a, 0x08, 0x68, 0x6d, 0x61, 0x63, 0x5f, - 0x6b, 0x65, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x15, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, - 0x0f, 0x0a, 0x0d, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, - 0x52, 0x07, 0x68, 0x6d, 0x61, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x3d, 0x0a, 0x09, 0x68, 0x6d, 0x61, - 0x63, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, - 0x72, 0x74, 0x69, 0x65, 0x73, 0x2e, 0x48, 0x4d, 0x41, 0x43, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, - 0x68, 0x6d, 0x61, 0x63, 0x54, 0x79, 0x70, 0x65, 0x22, 0x2a, 0x0a, 0x08, 0x48, 0x4d, 0x41, 0x43, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x53, 0x49, 0x4d, 0x50, 0x4c, 0x45, 0x5f, 0x48, - 0x4d, 0x41, 0x43, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x46, 0x55, 0x4c, 0x4c, 0x5f, 0x48, 0x4d, - 0x41, 0x43, 0x10, 0x01, 0x22, 0x97, 0x01, 0x0a, 0x0e, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x4d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x67, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x4f, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x49, 0x0a, - 0x06, 0x52, 0x44, 0x46, 0x55, 0x52, 0x4e, 0x12, 0x3f, 0x54, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6d, - 0x6d, 0x6f, 0x6e, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x63, 0x69, - 0x70, 0x68, 0x65, 0x72, 0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x75, - 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x2e, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0xa4, - 0x03, 0x0a, 0x13, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, - 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x65, 0x6e, 0x63, 0x72, 0x79, - 0x70, 0x74, 0x65, 0x64, 0x12, 0x29, 0x0a, 0x10, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, - 0x64, 0x5f, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, - 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x12, - 0x3a, 0x0a, 0x19, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x69, 0x70, - 0x68, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x09, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x17, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x43, 0x69, 0x70, - 0x68, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x32, 0x0a, 0x09, 0x70, - 0x61, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x69, 0x76, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x15, - 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x0f, 0x0a, 0x0d, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x52, 0x08, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x49, 0x76, 0x12, - 0x39, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, - 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x70, - 0x69, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x0a, 0x61, 0x70, 0x69, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x66, - 0x75, 0x6c, 0x6c, 0x5f, 0x68, 0x6d, 0x61, 0x63, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, - 0x66, 0x75, 0x6c, 0x6c, 0x48, 0x6d, 0x61, 0x63, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x64, 0x64, - 0x69, 0x6e, 0x67, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x04, 0x52, 0x07, 0x70, 0x61, 0x64, 0x64, 0x69, - 0x6e, 0x67, 0x22, 0x41, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x09, 0x0a, 0x05, - 0x55, 0x4e, 0x53, 0x45, 0x54, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x02, 0x4f, 0x4b, 0x10, 0xc8, 0x01, - 0x12, 0x10, 0x0a, 0x0b, 0x42, 0x41, 0x44, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x10, - 0x90, 0x03, 0x12, 0x11, 0x0a, 0x0c, 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x10, 0x96, 0x03, 0x22, 0xf1, 0x01, 0x0a, 0x0a, 0x4c, 0x6f, 0x67, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x02, 0x69, 0x64, 0x12, 0x44, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2a, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x24, 0x12, 0x22, 0x54, - 0x68, 0x65, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x73, 0x65, - 0x6e, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x2e, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x5b, 0x0a, 0x09, 0x74, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x42, 0x3d, 0xe2, - 0xfc, 0xe3, 0xc4, 0x01, 0x37, 0x0a, 0x0b, 0x52, 0x44, 0x46, 0x44, 0x61, 0x74, 0x65, 0x74, 0x69, - 0x6d, 0x65, 0x12, 0x28, 0x54, 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x77, 0x68, 0x65, - 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x77, 0x61, - 0x73, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x2e, 0x52, 0x09, 0x74, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x72, 0x74, 0x69, 0x66, - 0x61, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x72, 0x74, 0x69, 0x66, - 0x61, 0x63, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0x3e, 0x0a, 0x09, 0x50, 0x75, 0x62, - 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x65, 0x6d, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x03, 0x70, 0x65, 0x6d, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x6e, 0x72, 0x6f, - 0x6c, 0x6c, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x65, - 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x42, 0x34, 0x5a, 0x32, 0x77, 0x77, 0x77, - 0x2e, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x64, 0x65, 0x78, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, - 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x72, 0x61, 0x70, 0x74, - 0x6f, 0x72, 0x2f, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x57, 0x69, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, + 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x6c, 0x6f, 0x67, 0x5f, + 0x72, 0x6f, 0x77, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x6c, 0x6f, 0x67, 0x52, + 0x6f, 0x77, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x5f, 0x72, 0x6f, + 0x77, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x52, 0x6f, 0x77, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x69, 0x64, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x71, 0x75, 0x65, 0x72, 0x79, 0x49, 0x64, 0x12, + 0x23, 0x0a, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x51, 0x75, 0x65, + 0x72, 0x69, 0x65, 0x73, 0x22, 0x2b, 0x0a, 0x0e, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x06, 0x0a, 0x02, 0x4f, 0x4b, 0x10, 0x00, 0x12, 0x11, + 0x0a, 0x0d, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x49, 0x43, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, + 0x0a, 0x22, 0x33, 0x0a, 0x0b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, + 0x12, 0x24, 0x0a, 0x03, 0x6a, 0x6f, 0x62, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x65, 0x6c, 0x6f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x52, 0x03, 0x6a, 0x6f, 0x62, 0x22, 0xf0, 0x05, 0x0a, 0x11, 0x50, 0x61, 0x63, 0x6b, 0x65, + 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x4a, 0x0a, 0x0b, + 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x28, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x64, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x43, 0x6f, 0x6d, 0x70, + 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x63, 0x6f, 0x6d, + 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0b, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x6c, 0x0a, 0x09, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x42, 0x4e, + 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x48, 0x0a, 0x0b, 0x52, 0x44, 0x46, 0x44, 0x61, 0x74, 0x65, 0x74, + 0x69, 0x6d, 0x65, 0x12, 0x39, 0x54, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, + 0x73, 0x65, 0x6e, 0x64, 0x73, 0x20, 0x69, 0x74, 0x73, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x72, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x20, 0x72, + 0x65, 0x70, 0x6c, 0x61, 0x79, 0x20, 0x61, 0x74, 0x74, 0x61, 0x63, 0x6b, 0x73, 0x2e, 0x52, 0x09, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0xc6, 0x03, 0x0a, 0x05, 0x6e, 0x6f, + 0x6e, 0x63, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x42, 0xaf, 0x03, 0xe2, 0xfc, 0xe3, 0xc4, + 0x01, 0xa8, 0x03, 0x12, 0xa5, 0x03, 0x41, 0x20, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x20, 0x6e, + 0x6f, 0x6e, 0x63, 0x65, 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, + 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x20, 0x75, 0x73, 0x65, 0x73, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x65, 0x6e, + 0x73, 0x75, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, + 0x62, 0x65, 0x6c, 0x6f, 0x6e, 0x67, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, + 0x61, 0x6d, 0x65, 0x20, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x61, + 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x20, 0x57, 0x69, + 0x74, 0x68, 0x6f, 0x75, 0x74, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x20, 0x61, 0x6e, 0x79, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x6d, 0x61, 0x79, 0x20, + 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x20, 0x4e, 0x4f, 0x54, 0x45, 0x20, 0x74, 0x68, 0x69, 0x73, + 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x77, 0x65, 0x61, 0x6b, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x20, 0x2d, 0x20, 0x61, 0x6e, 0x79, 0x6f, 0x6e, 0x65, 0x20, 0x77, 0x68, 0x6f, 0x20, 0x63, 0x6f, + 0x6d, 0x70, 0x72, 0x6f, 0x6d, 0x69, 0x73, 0x65, 0x73, 0x20, 0x61, 0x20, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x64, 0x65, 0x70, 0x6c, 0x6f, + 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, + 0x74, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x61, 0x74, + 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2c, 0x20, 0x62, 0x75, 0x74, 0x20, 0x69, 0x74, 0x20, + 0x6d, 0x61, 0x6b, 0x65, 0x73, 0x20, 0x69, 0x74, 0x20, 0x61, 0x20, 0x6c, 0x69, 0x74, 0x74, 0x6c, + 0x65, 0x20, 0x68, 0x61, 0x72, 0x64, 0x65, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x6a, 0x6f, 0x69, 0x6e, + 0x20, 0x61, 0x20, 0x56, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x72, 0x61, 0x70, 0x74, 0x6f, 0x72, 0x20, + 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x52, 0x05, 0x6e, 0x6f, 0x6e, + 0x63, 0x65, 0x22, 0x35, 0x0a, 0x0f, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x0c, 0x55, 0x4e, 0x43, 0x4f, 0x4d, 0x50, 0x52, + 0x45, 0x53, 0x53, 0x45, 0x44, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x5a, 0x43, 0x4f, 0x4d, 0x50, + 0x52, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x22, 0xa4, 0x02, 0x0a, 0x10, 0x43, 0x69, + 0x70, 0x68, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x27, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, + 0x15, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x0f, 0x0a, 0x0d, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x0b, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x69, 0x76, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, + 0x42, 0x15, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x0f, 0x0a, 0x0d, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x52, 0x0a, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x49, 0x76, 0x12, 0x30, 0x0a, 0x08, 0x68, 0x6d, 0x61, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x15, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x0f, 0x0a, 0x0d, 0x45, + 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x52, 0x07, 0x68, 0x6d, + 0x61, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x3d, 0x0a, 0x09, 0x68, 0x6d, 0x61, 0x63, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, + 0x73, 0x2e, 0x48, 0x4d, 0x41, 0x43, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x68, 0x6d, 0x61, 0x63, + 0x54, 0x79, 0x70, 0x65, 0x22, 0x2a, 0x0a, 0x08, 0x48, 0x4d, 0x41, 0x43, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x0f, 0x0a, 0x0b, 0x53, 0x49, 0x4d, 0x50, 0x4c, 0x45, 0x5f, 0x48, 0x4d, 0x41, 0x43, 0x10, + 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x46, 0x55, 0x4c, 0x4c, 0x5f, 0x48, 0x4d, 0x41, 0x43, 0x10, 0x01, + 0x22, 0x97, 0x01, 0x0a, 0x0e, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x12, 0x67, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x4f, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x49, 0x0a, 0x06, 0x52, 0x44, 0x46, + 0x55, 0x52, 0x4e, 0x12, 0x3f, 0x54, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x20, + 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, + 0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, + 0x74, 0x6f, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x77, + 0x69, 0x74, 0x68, 0x2e, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, + 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0xa4, 0x03, 0x0a, 0x13, 0x43, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, + 0x12, 0x29, 0x0a, 0x10, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x69, + 0x70, 0x68, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x65, 0x6e, 0x63, 0x72, + 0x79, 0x70, 0x74, 0x65, 0x64, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x12, 0x3a, 0x0a, 0x19, 0x65, + 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x5f, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x17, + 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x32, 0x0a, 0x09, 0x70, 0x61, 0x63, 0x6b, 0x65, + 0x74, 0x5f, 0x69, 0x76, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x15, 0xe2, 0xfc, 0xe3, 0xc4, + 0x01, 0x0f, 0x0a, 0x0d, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, + 0x79, 0x52, 0x08, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x49, 0x76, 0x12, 0x39, 0x0a, 0x06, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x70, 0x69, 0x5f, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x61, 0x70, 0x69, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x75, 0x6c, 0x6c, 0x5f, + 0x68, 0x6d, 0x61, 0x63, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x66, 0x75, 0x6c, 0x6c, + 0x48, 0x6d, 0x61, 0x63, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x18, + 0x0b, 0x20, 0x03, 0x28, 0x04, 0x52, 0x07, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x22, 0x41, + 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x09, 0x0a, 0x05, 0x55, 0x4e, 0x53, 0x45, + 0x54, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x02, 0x4f, 0x4b, 0x10, 0xc8, 0x01, 0x12, 0x10, 0x0a, 0x0b, + 0x42, 0x41, 0x44, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x10, 0x90, 0x03, 0x12, 0x11, + 0x0a, 0x0c, 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x96, + 0x03, 0x22, 0xf1, 0x01, 0x0a, 0x0a, 0x4c, 0x6f, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, + 0x12, 0x44, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x2a, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x24, 0x12, 0x22, 0x54, 0x68, 0x65, 0x20, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x74, + 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x52, 0x07, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x5b, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x42, 0x3d, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, + 0x37, 0x0a, 0x0b, 0x52, 0x44, 0x46, 0x44, 0x61, 0x74, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x28, + 0x54, 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x77, 0x61, 0x73, 0x20, 0x67, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x2e, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, + 0x14, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0x3e, 0x0a, 0x09, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, + 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x03, 0x70, 0x65, 0x6d, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x5f, 0x74, + 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x65, 0x6e, 0x72, 0x6f, 0x6c, + 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x42, 0x34, 0x5a, 0x32, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x6c, + 0x6f, 0x63, 0x69, 0x64, 0x65, 0x78, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, + 0x67, 0x2f, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x72, 0x61, 0x70, 0x74, 0x6f, 0x72, 0x2f, 0x63, + 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( diff --git a/crypto/proto/jobs.proto b/crypto/proto/jobs.proto index 7e2ad966cb..37c9d60df3 100644 --- a/crypto/proto/jobs.proto +++ b/crypto/proto/jobs.proto @@ -156,6 +156,9 @@ message VeloStatus { // A List of artifacts that had some results. repeated string names_with_response = 5; + // The artifact that this status refers to + string Artifact = 10; + // How many log rows we generated int64 log_rows = 6; diff --git a/datastore/filebased.go b/datastore/filebased.go index 49c3d320a2..e863bdbadd 100644 --- a/datastore/filebased.go +++ b/datastore/filebased.go @@ -146,7 +146,8 @@ func (self *FileBaseDataStore) SetSubjectWithCompletion( // Make sure to call the completer on all exit points // (FileBaseDataStore is actually synchronous). defer func() { - if completion != nil { + if completion != nil && + !utils.CompareFuncs(completion, utils.SyncCompleter) { completion() } }() @@ -174,7 +175,8 @@ func (self *FileBaseDataStore) DeleteSubjectWithCompletion( urn api.DSPathSpec, completion func()) error { err := self.DeleteSubject(config_obj, urn) - if completion != nil { + if completion != nil && + !utils.CompareFuncs(completion, utils.SyncCompleter) { completion() } @@ -419,8 +421,8 @@ func (self *FileBaseDataStore) SetBuffer( urn api.DSPathSpec, data []byte, completion func()) error { err := writeContentToFile(config_obj, urn, data) - - if completion != nil { + if completion != nil && + !utils.CompareFuncs(completion, utils.SyncCompleter) { completion() } return err diff --git a/datastore/memcache_file.go b/datastore/memcache_file.go index 06df50111a..7748d35fb4 100644 --- a/datastore/memcache_file.go +++ b/datastore/memcache_file.go @@ -114,9 +114,12 @@ type MemcacheFileDataStore struct { mu sync.Mutex cache *MemcacheDatastore - writer chan *Mutation - ctx context.Context - cancel func() + writer chan *Mutation + ctx context.Context + cancel func() + config_obj *config_proto.Config + + started bool } func (self *MemcacheFileDataStore) Stats() *MemcacheStats { @@ -148,6 +151,20 @@ func (self *MemcacheFileDataStore) ExpirationPolicy( return true } +func (self *MemcacheFileDataStore) Flush() { + for { + select { + case mutation, ok := <-self.writer: + if !ok { + return + } + self.processMutation(self.config_obj, mutation) + default: + return + } + } +} + // Starts the writer loop. func (self *MemcacheFileDataStore) StartWriter( ctx context.Context, wg *sync.WaitGroup, @@ -173,6 +190,7 @@ func (self *MemcacheFileDataStore) StartWriter( self.mu.Lock() self.writer = make(chan *Mutation, buffer_size) self.ctx = ctx + self.started = true self.mu.Unlock() if writers == 0 { @@ -200,40 +218,44 @@ func (self *MemcacheFileDataStore) StartWriter( if !ok { return } - - metricIdleWriters.Dec() - switch mutation.op { - case MUTATION_OP_SET_SUBJECT: - writeContentToFile(config_obj, mutation.urn, mutation.data) - self.invalidateDirCache(config_obj, mutation.urn) - - // Call the completion function once we hit - // the directory datastore. - if mutation.completion != nil { - mutation.completion() - } - - case MUTATION_OP_DEL_SUBJECT: - file_based_imp.DeleteSubject(config_obj, mutation.urn) - self.invalidateDirCache(config_obj, mutation.urn.Dir()) - - // Call the completion function once we hit - // the directory datastore. - if mutation.completion != nil { - mutation.completion() - } - } - - metricIdleWriters.Inc() - if mutation.wg != nil { - mutation.wg.Done() - } + self.processMutation(config_obj, mutation) } } }() } } +func (self *MemcacheFileDataStore) processMutation( + config_obj *config_proto.Config, mutation *Mutation) { + metricIdleWriters.Dec() + switch mutation.op { + case MUTATION_OP_SET_SUBJECT: + writeContentToFile(config_obj, mutation.urn, mutation.data) + self.invalidateDirCache(config_obj, mutation.urn) + + // Call the completion function once we hit + // the directory datastore. + if mutation.completion != nil { + mutation.completion() + } + + case MUTATION_OP_DEL_SUBJECT: + file_based_imp.DeleteSubject(config_obj, mutation.urn) + self.invalidateDirCache(config_obj, mutation.urn.Dir()) + + // Call the completion function once we hit + // the directory datastore. + if mutation.completion != nil { + mutation.completion() + } + } + + metricIdleWriters.Inc() + if mutation.wg != nil { + mutation.wg.Done() + } +} + func (self *MemcacheFileDataStore) GetSubject( config_obj *config_proto.Config, urn api.DSPathSpec, @@ -621,6 +643,7 @@ func NewMemcacheFileDataStore(config_obj *config_proto.Config) *MemcacheFileData } result := &MemcacheFileDataStore{ + config_obj: config_obj, cache: &MemcacheDatastore{ data_cache: NewDataLRUCache(config_obj, data_max_size, data_max_item_size), @@ -637,15 +660,26 @@ func StartMemcacheFileService( ctx context.Context, wg *sync.WaitGroup, config_obj *config_proto.Config) error { - _, err := GetDB(config_obj) + if config_obj.Datastore == nil { + return nil + } + + db, err := GetDB(config_obj) if err != nil { return err } - if memcache_file_imp != nil { + memcache_file_db, ok := db.(*MemcacheFileDataStore) + if !ok { + // If it not a MemcacheFileDataStore so we dont need to do + // anything to it. + return nil + } + + if !memcache_file_db.started { logger := logging.GetLogger(config_obj, &logging.FrontendComponent) logger.Info("Starting memcache service") - memcache_file_imp.StartWriter(ctx, wg, config_obj) + memcache_file_db.StartWriter(ctx, wg, config_obj) } return nil diff --git a/datastore/readonly.go b/datastore/readonly.go index 19ccc8ac88..104082315b 100644 --- a/datastore/readonly.go +++ b/datastore/readonly.go @@ -7,6 +7,7 @@ import ( "google.golang.org/protobuf/proto" config_proto "www.velocidex.com/golang/velociraptor/config/proto" "www.velocidex.com/golang/velociraptor/file_store/api" + "www.velocidex.com/golang/velociraptor/utils" ) var ( @@ -34,7 +35,8 @@ func (self *ReadOnlyDataStore) SetSubjectWithCompletion( completion func()) error { err := self.cache.SetSubject(config_obj, urn, message) - if completion != nil { + if completion != nil && + !utils.CompareFuncs(completion, utils.SyncCompleter) { completion() } return err diff --git a/datastore/remote.go b/datastore/remote.go index bacabf283f..8163ad4380 100644 --- a/datastore/remote.go +++ b/datastore/remote.go @@ -18,6 +18,7 @@ import ( "www.velocidex.com/golang/velociraptor/file_store/path_specs" "www.velocidex.com/golang/velociraptor/grpc_client" "www.velocidex.com/golang/velociraptor/logging" + "www.velocidex.com/golang/velociraptor/utils" ) var ( @@ -147,7 +148,8 @@ func (self *RemoteDataStore) SetSubjectWithCompletion( // Make sure to always call the completion regardless of error // paths. defer func() { - if completion != nil { + if completion != nil && + !utils.CompareFuncs(completion, utils.SyncCompleter) { completion() } }() diff --git a/docs/references/vql.yaml b/docs/references/vql.yaml index 87aae8439f..e7d75d8c7c 100644 --- a/docs/references/vql.yaml +++ b/docs/references/vql.yaml @@ -3034,7 +3034,7 @@ description: Return the details of the current org. type: Function - name: org_create - description: Creates a new organizaion. + description: Creates a new organization. type: Function args: - name: name @@ -3044,6 +3044,14 @@ - name: org_id type: string description: An ID for the new org (if not set use a random ID). +- name: org_delete + description: Deletes an Org from the server. + type: Function + args: + - name: org + type: string + description: The org ID to delete. + required: true - name: orgs description: Retrieve the list of orgs on this server. type: Plugin @@ -5790,4 +5798,3 @@ type: string description: If set use this key to cache the yara rules. category: plugin - diff --git a/flows/artifacts.go b/flows/artifacts.go index 341c501fe6..6fe07ad900 100644 --- a/flows/artifacts.go +++ b/flows/artifacts.go @@ -208,7 +208,7 @@ func closeContext( // until after all artifacts have been collected so users can // watch them and expect to see results. if collection_context.Request != nil && - collection_context.OutstandingRequests <= 0 && + int64(len(collection_context.QueryStats)) >= collection_context.TotalRequests && !collection_context.UserNotified { // Record the message was sent - so we never resent the @@ -461,26 +461,13 @@ func CheckForStatus( return errors.New("Invalid collection context") } - // Only record the first error. - if message.Status.Status != crypto_proto.VeloStatus_OK && - (collection_context.State == flows_proto.ArtifactCollectorContext_RUNNING || - collection_context.State == flows_proto.ArtifactCollectorContext_FINISHED) { - collection_context.State = flows_proto.ArtifactCollectorContext_ERROR - collection_context.Status = message.Status.ErrorMessage - collection_context.Backtrace = message.Status.Backtrace - } + // Update our record of all the status messages from this + // collection. + updateQueryStats(collection_context, message.Status) + UpdateFlowStats(collection_context) - // But these are updated for each response. + // Update the active time for each response. collection_context.ActiveTime = uint64(time.Now().UnixNano() / 1000) - collection_context.ExecutionDuration += message.Status.Duration - - // Each status message decreases outstanding_requests by one - - // when we hit 0 we can mark the flow as finished. - collection_context.OutstandingRequests-- - if collection_context.OutstandingRequests <= 0 && - collection_context.State == flows_proto.ArtifactCollectorContext_RUNNING { - collection_context.State = flows_proto.ArtifactCollectorContext_FINISHED - } collection_context.Dirty = true diff --git a/flows/artifacts_test.go b/flows/artifacts_test.go index ee574c3a60..135777cd1e 100644 --- a/flows/artifacts_test.go +++ b/flows/artifacts_test.go @@ -534,6 +534,7 @@ func (self *TestSuite) TestCollectionCompletionSuccessFollowedByErrLog() { Query: &actions_proto.VQLRequest{ Name: "Generic.Client.Info/BasicInformation", }, + QueryId: 0, }, }, { @@ -542,6 +543,7 @@ func (self *TestSuite) TestCollectionCompletionSuccessFollowedByErrLog() { Status: &crypto_proto.VeloStatus{ Status: crypto_proto.VeloStatus_OK, Duration: 100, + QueryId: 0, }, }, { @@ -553,6 +555,7 @@ func (self *TestSuite) TestCollectionCompletionSuccessFollowedByErrLog() { Query: &actions_proto.VQLRequest{ Name: "Generic.Client.Info/Users", }, + QueryId: 1, }, }, { @@ -568,6 +571,7 @@ func (self *TestSuite) TestCollectionCompletionSuccessFollowedByErrLog() { Status: &crypto_proto.VeloStatus{ Status: crypto_proto.VeloStatus_OK, Duration: 200, + QueryId: 1, }, }, }) @@ -595,7 +599,7 @@ func (self *TestSuite) TestCollectionCompletionTwoSourcesIncomplete() { State: flows_proto.ArtifactCollectorContext_RUNNING, // Two sources running in parallel. - OutstandingRequests: 2, + TotalRequests: 2, Request: &flows_proto.ArtifactCollectorArgs{ Artifacts: []string{"Generic.Client.Info"}, }, @@ -630,6 +634,7 @@ func (self *TestSuite) TestCollectionCompletionTwoSourcesIncomplete() { Query: &actions_proto.VQLRequest{ Name: "Generic.Client.Info/BasicInformation", }, + QueryId: 0, }, }) @@ -641,6 +646,7 @@ func (self *TestSuite) TestCollectionCompletionTwoSourcesIncomplete() { Status: &crypto_proto.VeloStatus{ Status: crypto_proto.VeloStatus_GENERIC_ERROR, Duration: 100, + QueryId: 0, }, }) runner.Close(context.Background()) @@ -680,6 +686,7 @@ func (self *TestSuite) TestCollectionCompletionTwoSourcesIncomplete() { Query: &actions_proto.VQLRequest{ Name: "Generic.Client.Info/Users", }, + QueryId: 1, }, }) @@ -691,6 +698,7 @@ func (self *TestSuite) TestCollectionCompletionTwoSourcesIncomplete() { Status: &crypto_proto.VeloStatus{ Status: crypto_proto.VeloStatus_OK, Duration: 100, + QueryId: 1, }, }) runner.Close(context.Background()) diff --git a/flows/collection_context.go b/flows/collection_context.go new file mode 100644 index 0000000000..7c943ebf1d --- /dev/null +++ b/flows/collection_context.go @@ -0,0 +1,87 @@ +package flows + +import ( + "google.golang.org/protobuf/proto" + crypto_proto "www.velocidex.com/golang/velociraptor/crypto/proto" + flows_proto "www.velocidex.com/golang/velociraptor/flows/proto" +) + +// Track stats for each query independently - then combine the whole +// thing into the overall collection stats. +func updateQueryStats( + collection_context *CollectionContext, + status *crypto_proto.VeloStatus) { + for idx, stat := range collection_context.QueryStats { + if status.QueryId == stat.QueryId { + // Error statuses are sticky - the first error stats for a + // query id will stick to the status and remove previous + // OK status. Further error status will be ignored. + if status.Status != crypto_proto.VeloStatus_OK && + stat.Status == crypto_proto.VeloStatus_OK { + new_stat := proto.Clone(status).(*crypto_proto.VeloStatus) + new_stat.Duration += status.Duration + new_stat.NamesWithResponse = append(new_stat.NamesWithResponse, stat.NamesWithResponse...) + collection_context.QueryStats[idx] = new_stat + continue + } + + if status.Artifact != "" { + stat.Artifact = status.Artifact + } + + if status.Duration > stat.Duration { + stat.Duration = status.Duration + } + + if len(status.NamesWithResponse) > len(stat.NamesWithResponse) { + stat.NamesWithResponse = status.NamesWithResponse + } + + return + } + } + + // We dont have this status yet + collection_context.QueryStats = append(collection_context.QueryStats, status) +} + +// The collection_context contains high level stats that summarise the +// colletion. We derive this information from the specific results of +// each query. +func UpdateFlowStats(collection_context *CollectionContext) { + // Support older colletions which do not have this info + if len(collection_context.QueryStats) == 0 { + return + } + + // Now update the overall collection statuses based on all the + // individual query status. The collection status is a high level + // overview of the entire collection. + collection_context.State = flows_proto.ArtifactCollectorContext_RUNNING + collection_context.Status = "" + collection_context.Backtrace = "" + for _, s := range collection_context.QueryStats { + // Get the first errored query. + if collection_context.State == flows_proto.ArtifactCollectorContext_RUNNING && + s.Status != crypto_proto.VeloStatus_OK { + collection_context.State = flows_proto.ArtifactCollectorContext_ERROR + collection_context.Status = s.ErrorMessage + collection_context.Backtrace = s.Backtrace + break + } + } + + // Total execution duration is the sum of all the query durations + // (this can be faster than wall time if queries run in parallel) + collection_context.ExecutionDuration = 0 + for _, s := range collection_context.QueryStats { + collection_context.ExecutionDuration += s.Duration + } + + collection_context.OutstandingRequests = collection_context.TotalRequests - + int64(len(collection_context.QueryStats)) + if collection_context.OutstandingRequests <= 0 && + collection_context.State == flows_proto.ArtifactCollectorContext_RUNNING { + collection_context.State = flows_proto.ArtifactCollectorContext_FINISHED + } +} diff --git a/flows/proto/artifact_collector.pb.go b/flows/proto/artifact_collector.pb.go index 05e3d0b86f..3aaf2e4348 100644 --- a/flows/proto/artifact_collector.pb.go +++ b/flows/proto/artifact_collector.pb.go @@ -78,7 +78,7 @@ func (x ArtifactCollectorContext_State) Number() protoreflect.EnumNumber { // Deprecated: Use ArtifactCollectorContext_State.Descriptor instead. func (ArtifactCollectorContext_State) EnumDescriptor() ([]byte, []int) { - return file_artifact_collector_proto_rawDescGZIP(), []int{6, 0} + return file_artifact_collector_proto_rawDescGZIP(), []int{7, 0} } type ArtifactParameters struct { @@ -476,7 +476,8 @@ func (x *ArtifactUploadedFileInfo) GetComponents() []string { // updated each time anyting about the collection is changed, without // having to race updating the main record. The read active_time is // the latest between this record and the one in -// ArtifactCollectorContext +// ArtifactCollectorContext. This is mainly used by the GUI to notice +// when a collection is updated. type PingContext struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -524,7 +525,82 @@ func (x *PingContext) GetActiveTime() uint64 { return 0 } -// This context is serialized into the data store. +// Keep track of each individual query and its status - a collection +// can contain multiple queries and artifacts some may fail and others +// may succeed. We keep track of the total here. +type QueryStats struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + QueryId uint64 `protobuf:"varint,1,opt,name=query_id,json=queryId,proto3" json:"query_id,omitempty"` + ExecutionDuration uint64 `protobuf:"varint,2,opt,name=execution_duration,json=executionDuration,proto3" json:"execution_duration,omitempty"` + Status string `protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"` + QueryName string `protobuf:"bytes,4,opt,name=query_name,json=queryName,proto3" json:"query_name,omitempty"` +} + +func (x *QueryStats) Reset() { + *x = QueryStats{} + if protoimpl.UnsafeEnabled { + mi := &file_artifact_collector_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryStats) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryStats) ProtoMessage() {} + +func (x *QueryStats) ProtoReflect() protoreflect.Message { + mi := &file_artifact_collector_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use QueryStats.ProtoReflect.Descriptor instead. +func (*QueryStats) Descriptor() ([]byte, []int) { + return file_artifact_collector_proto_rawDescGZIP(), []int{6} +} + +func (x *QueryStats) GetQueryId() uint64 { + if x != nil { + return x.QueryId + } + return 0 +} + +func (x *QueryStats) GetExecutionDuration() uint64 { + if x != nil { + return x.ExecutionDuration + } + return 0 +} + +func (x *QueryStats) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +func (x *QueryStats) GetQueryName() string { + if x != nil { + return x.QueryName + } + return "" +} + +// This context is serialized into the data store. We keep track of +// all aspects of a collection. type ArtifactCollectorContext struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -546,6 +622,7 @@ type ArtifactCollectorContext struct { TotalUploadedBytes uint64 `protobuf:"varint,26,opt,name=total_uploaded_bytes,json=totalUploadedBytes,proto3" json:"total_uploaded_bytes,omitempty"` TotalCollectedRows uint64 `protobuf:"varint,28,opt,name=total_collected_rows,json=totalCollectedRows,proto3" json:"total_collected_rows,omitempty"` TotalLogs uint64 `protobuf:"varint,32,opt,name=total_logs,json=totalLogs,proto3" json:"total_logs,omitempty"` + TotalRequests int64 `protobuf:"varint,35,opt,name=total_requests,json=totalRequests,proto3" json:"total_requests,omitempty"` OutstandingRequests int64 `protobuf:"varint,31,opt,name=outstanding_requests,json=outstandingRequests,proto3" json:"outstanding_requests,omitempty"` // We expect the next response from the client to have this id. NextResponseId uint64 `protobuf:"varint,30,opt,name=next_response_id,json=nextResponseId,proto3" json:"next_response_id,omitempty"` @@ -554,9 +631,14 @@ type ArtifactCollectorContext struct { ExecutionDuration int64 `protobuf:"varint,29,opt,name=execution_duration,json=executionDuration,proto3" json:"execution_duration,omitempty"` State ArtifactCollectorContext_State `protobuf:"varint,14,opt,name=state,proto3,enum=proto.ArtifactCollectorContext_State" json:"state,omitempty"` Status string `protobuf:"bytes,15,opt,name=status,proto3" json:"status,omitempty"` - UserNotified bool `protobuf:"varint,16,opt,name=user_notified,json=userNotified,proto3" json:"user_notified,omitempty"` + // This is used to keep track of any System.Flow.Completion events + // we already sent. We only send exactly one such message when the + // flow is completed. + UserNotified bool `protobuf:"varint,16,opt,name=user_notified,json=userNotified,proto3" json:"user_notified,omitempty"` // Some of the collected artifacts may not have results. ArtifactsWithResults []string `protobuf:"bytes,22,rep,name=artifacts_with_results,json=artifactsWithResults,proto3" json:"artifacts_with_results,omitempty"` + // Keep detailed track of each query status. + QueryStats []*proto1.VeloStatus `protobuf:"bytes,34,rep,name=query_stats,json=queryStats,proto3" json:"query_stats,omitempty"` // Uploads are now permanently stored in a json file. This field is // never serialized - it is just a place holder during processing. UploadedFiles []*ArtifactUploadedFileInfo `protobuf:"bytes,24,rep,name=uploaded_files,json=uploadedFiles,proto3" json:"uploaded_files,omitempty"` @@ -571,7 +653,7 @@ type ArtifactCollectorContext struct { func (x *ArtifactCollectorContext) Reset() { *x = ArtifactCollectorContext{} if protoimpl.UnsafeEnabled { - mi := &file_artifact_collector_proto_msgTypes[6] + mi := &file_artifact_collector_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -584,7 +666,7 @@ func (x *ArtifactCollectorContext) String() string { func (*ArtifactCollectorContext) ProtoMessage() {} func (x *ArtifactCollectorContext) ProtoReflect() protoreflect.Message { - mi := &file_artifact_collector_proto_msgTypes[6] + mi := &file_artifact_collector_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -597,7 +679,7 @@ func (x *ArtifactCollectorContext) ProtoReflect() protoreflect.Message { // Deprecated: Use ArtifactCollectorContext.ProtoReflect.Descriptor instead. func (*ArtifactCollectorContext) Descriptor() ([]byte, []int) { - return file_artifact_collector_proto_rawDescGZIP(), []int{6} + return file_artifact_collector_proto_rawDescGZIP(), []int{7} } func (x *ArtifactCollectorContext) GetClientId() string { @@ -684,6 +766,13 @@ func (x *ArtifactCollectorContext) GetTotalLogs() uint64 { return 0 } +func (x *ArtifactCollectorContext) GetTotalRequests() int64 { + if x != nil { + return x.TotalRequests + } + return 0 +} + func (x *ArtifactCollectorContext) GetOutstandingRequests() int64 { if x != nil { return x.OutstandingRequests @@ -733,6 +822,13 @@ func (x *ArtifactCollectorContext) GetArtifactsWithResults() []string { return nil } +func (x *ArtifactCollectorContext) GetQueryStats() []*proto1.VeloStatus { + if x != nil { + return x.QueryStats + } + return nil +} + func (x *ArtifactCollectorContext) GetUploadedFiles() []*ArtifactUploadedFileInfo { if x != nil { return x.UploadedFiles @@ -774,7 +870,7 @@ type LabelEvents struct { func (x *LabelEvents) Reset() { *x = LabelEvents{} if protoimpl.UnsafeEnabled { - mi := &file_artifact_collector_proto_msgTypes[7] + mi := &file_artifact_collector_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -787,7 +883,7 @@ func (x *LabelEvents) String() string { func (*LabelEvents) ProtoMessage() {} func (x *LabelEvents) ProtoReflect() protoreflect.Message { - mi := &file_artifact_collector_proto_msgTypes[7] + mi := &file_artifact_collector_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -800,7 +896,7 @@ func (x *LabelEvents) ProtoReflect() protoreflect.Message { // Deprecated: Use LabelEvents.ProtoReflect.Descriptor instead. func (*LabelEvents) Descriptor() ([]byte, []int) { - return file_artifact_collector_proto_rawDescGZIP(), []int{7} + return file_artifact_collector_proto_rawDescGZIP(), []int{8} } func (x *LabelEvents) GetLabel() string { @@ -830,7 +926,7 @@ type GetClientMonitoringStateRequest struct { func (x *GetClientMonitoringStateRequest) Reset() { *x = GetClientMonitoringStateRequest{} if protoimpl.UnsafeEnabled { - mi := &file_artifact_collector_proto_msgTypes[8] + mi := &file_artifact_collector_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -843,7 +939,7 @@ func (x *GetClientMonitoringStateRequest) String() string { func (*GetClientMonitoringStateRequest) ProtoMessage() {} func (x *GetClientMonitoringStateRequest) ProtoReflect() protoreflect.Message { - mi := &file_artifact_collector_proto_msgTypes[8] + mi := &file_artifact_collector_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -856,7 +952,7 @@ func (x *GetClientMonitoringStateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetClientMonitoringStateRequest.ProtoReflect.Descriptor instead. func (*GetClientMonitoringStateRequest) Descriptor() ([]byte, []int) { - return file_artifact_collector_proto_rawDescGZIP(), []int{8} + return file_artifact_collector_proto_rawDescGZIP(), []int{9} } func (x *GetClientMonitoringStateRequest) GetClientId() string { @@ -883,7 +979,7 @@ type ClientEventTable struct { func (x *ClientEventTable) Reset() { *x = ClientEventTable{} if protoimpl.UnsafeEnabled { - mi := &file_artifact_collector_proto_msgTypes[9] + mi := &file_artifact_collector_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -896,7 +992,7 @@ func (x *ClientEventTable) String() string { func (*ClientEventTable) ProtoMessage() {} func (x *ClientEventTable) ProtoReflect() protoreflect.Message { - mi := &file_artifact_collector_proto_msgTypes[9] + mi := &file_artifact_collector_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -909,7 +1005,7 @@ func (x *ClientEventTable) ProtoReflect() protoreflect.Message { // Deprecated: Use ClientEventTable.ProtoReflect.Descriptor instead. func (*ClientEventTable) Descriptor() ([]byte, []int) { - return file_artifact_collector_proto_rawDescGZIP(), []int{9} + return file_artifact_collector_proto_rawDescGZIP(), []int{10} } func (x *ClientEventTable) GetVersion() uint64 { @@ -953,7 +1049,7 @@ type UploadedFileInfo struct { func (x *UploadedFileInfo) Reset() { *x = UploadedFileInfo{} if protoimpl.UnsafeEnabled { - mi := &file_artifact_collector_proto_msgTypes[10] + mi := &file_artifact_collector_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -966,7 +1062,7 @@ func (x *UploadedFileInfo) String() string { func (*UploadedFileInfo) ProtoMessage() {} func (x *UploadedFileInfo) ProtoReflect() protoreflect.Message { - mi := &file_artifact_collector_proto_msgTypes[10] + mi := &file_artifact_collector_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -979,7 +1075,7 @@ func (x *UploadedFileInfo) ProtoReflect() protoreflect.Message { // Deprecated: Use UploadedFileInfo.ProtoReflect.Descriptor instead. func (*UploadedFileInfo) Descriptor() ([]byte, []int) { - return file_artifact_collector_proto_rawDescGZIP(), []int{10} + return file_artifact_collector_proto_rawDescGZIP(), []int{11} } func (x *UploadedFileInfo) GetName() string { @@ -1095,7 +1191,16 @@ var file_artifact_collector_proto_rawDesc = []byte{ 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x2e, 0x0a, 0x0b, 0x50, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x0a, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x22, 0xe3, 0x09, 0x0a, + 0x52, 0x0a, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x8d, 0x01, 0x0a, + 0x0a, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x49, 0x64, 0x12, 0x2d, 0x0a, 0x12, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x11, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x75, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1d, 0x0a, + 0x0a, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x71, 0x75, 0x65, 0x72, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xbe, 0x0a, 0x0a, 0x18, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, @@ -1128,86 +1233,91 @@ var file_artifact_collector_proto_rawDesc = []byte{ 0x04, 0x52, 0x12, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x6f, 0x77, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x20, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x6f, 0x74, 0x61, 0x6c, - 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x31, 0x0a, 0x14, 0x6f, 0x75, 0x74, 0x73, 0x74, 0x61, 0x6e, 0x64, - 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x1f, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x13, 0x6f, 0x75, 0x74, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x6e, 0x65, 0x78, 0x74, 0x5f, - 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x1e, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x0e, 0x6e, 0x65, 0x78, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, - 0x64, 0x12, 0x2d, 0x0a, 0x12, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, - 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x65, - 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x3b, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x25, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, - 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, - 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x4f, 0x0a, - 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x42, 0x37, 0xe2, - 0xfc, 0xe3, 0xc4, 0x01, 0x31, 0x12, 0x2f, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x20, - 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x73, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x20, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x23, - 0x0a, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, - 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, - 0x69, 0x65, 0x64, 0x12, 0x9f, 0x01, 0x0a, 0x16, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, - 0x73, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x16, - 0x20, 0x03, 0x28, 0x09, 0x42, 0x69, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x63, 0x12, 0x61, 0x54, 0x68, - 0x65, 0x20, 0x66, 0x75, 0x6c, 0x6c, 0x20, 0x70, 0x61, 0x74, 0x68, 0x20, 0x74, 0x6f, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x20, 0x77, 0x69, 0x74, - 0x68, 0x20, 0x74, 0x68, 0x65, 0x69, 0x72, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x2e, - 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x74, 0x61, 0x6b, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x20, 0x6e, 0x61, - 0x6d, 0x65, 0x2f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x52, - 0x14, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x57, 0x69, 0x74, 0x68, 0x52, 0x65, - 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x46, 0x0a, 0x0e, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, - 0x64, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x18, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x55, 0x70, - 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0d, - 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x25, 0x0a, - 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x14, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x6f, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x04, - 0x6c, 0x6f, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x69, 0x72, 0x74, 0x79, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x05, 0x64, 0x69, 0x72, 0x74, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, - 0x74, 0x61, 0x6c, 0x5f, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x18, 0x21, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x4c, 0x6f, 0x61, 0x64, 0x73, 0x22, 0x55, 0x0a, 0x05, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x55, 0x4e, 0x53, 0x45, 0x54, 0x10, 0x00, 0x12, - 0x0b, 0x0a, 0x07, 0x52, 0x55, 0x4e, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, - 0x46, 0x49, 0x4e, 0x49, 0x53, 0x48, 0x45, 0x44, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, - 0x52, 0x4f, 0x52, 0x10, 0x03, 0x12, 0x0c, 0x0a, 0x08, 0x41, 0x52, 0x43, 0x48, 0x49, 0x56, 0x45, - 0x44, 0x10, 0x04, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x4c, 0x45, 0x44, - 0x10, 0x05, 0x22, 0x5f, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x3a, 0x0a, 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, - 0x61, 0x63, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x43, 0x6f, 0x6c, 0x6c, 0x65, - 0x63, 0x74, 0x6f, 0x72, 0x41, 0x72, 0x67, 0x73, 0x52, 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, - 0x63, 0x74, 0x73, 0x22, 0x3e, 0x0a, 0x1f, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 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, 0x22, 0xda, 0x01, 0x0a, 0x10, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x12, 0x3a, 0x0a, 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x18, + 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x23, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x6f, + 0x74, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x12, 0x31, 0x0a, 0x14, 0x6f, + 0x75, 0x74, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x73, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x03, 0x52, 0x13, 0x6f, 0x75, 0x74, 0x73, 0x74, + 0x61, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x12, 0x28, + 0x0a, 0x10, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, + 0x69, 0x64, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x6e, 0x65, 0x78, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x64, 0x12, 0x2d, 0x0a, 0x12, 0x65, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x1d, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x44, + 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3b, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, + 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x12, 0x4f, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x0f, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x37, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x31, 0x12, 0x2f, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x62, + 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x52, 0x06, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x6f, + 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x75, 0x73, + 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x9f, 0x01, 0x0a, 0x16, 0x61, + 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x72, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x16, 0x20, 0x03, 0x28, 0x09, 0x42, 0x69, 0xe2, 0xfc, 0xe3, + 0xc4, 0x01, 0x63, 0x12, 0x61, 0x54, 0x68, 0x65, 0x20, 0x66, 0x75, 0x6c, 0x6c, 0x20, 0x70, 0x61, + 0x74, 0x68, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x69, 0x72, 0x20, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x2e, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x74, 0x61, 0x6b, + 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x61, 0x72, 0x74, 0x69, + 0x66, 0x61, 0x63, 0x74, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x2f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x52, 0x14, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, + 0x73, 0x57, 0x69, 0x74, 0x68, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x32, 0x0a, 0x0b, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x22, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x65, 0x6c, 0x6f, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x0a, 0x71, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x73, + 0x12, 0x46, 0x0a, 0x0e, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x5f, 0x66, 0x69, 0x6c, + 0x65, 0x73, 0x18, 0x18, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, + 0x64, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0d, 0x75, 0x70, 0x6c, 0x6f, 0x61, + 0x64, 0x65, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, + 0x18, 0x14, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, + 0x6f, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x12, + 0x14, 0x0a, 0x05, 0x64, 0x69, 0x72, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, + 0x64, 0x69, 0x72, 0x74, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x6c, + 0x6f, 0x61, 0x64, 0x73, 0x18, 0x21, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, + 0x6c, 0x4c, 0x6f, 0x61, 0x64, 0x73, 0x22, 0x55, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, + 0x09, 0x0a, 0x05, 0x55, 0x4e, 0x53, 0x45, 0x54, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x55, + 0x4e, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x46, 0x49, 0x4e, 0x49, 0x53, + 0x48, 0x45, 0x44, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, + 0x12, 0x0c, 0x0a, 0x08, 0x41, 0x52, 0x43, 0x48, 0x49, 0x56, 0x45, 0x44, 0x10, 0x04, 0x12, 0x0d, + 0x0a, 0x09, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x4c, 0x45, 0x44, 0x10, 0x05, 0x22, 0x5f, 0x0a, + 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x12, 0x3a, 0x0a, 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x41, - 0x72, 0x67, 0x73, 0x52, 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x35, - 0x0a, 0x0c, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x61, 0x62, - 0x65, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x0b, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x39, 0x0a, 0x0e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x65, 0x6c, 0x6f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x52, 0x0d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x22, 0x55, 0x0a, 0x10, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x46, 0x69, 0x6c, 0x65, - 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x76, 0x66, 0x73, 0x5f, - 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x66, 0x73, 0x50, - 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x42, 0x33, 0x5a, 0x31, 0x77, 0x77, 0x77, 0x2e, 0x76, - 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x64, 0x65, 0x78, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, - 0x61, 0x6e, 0x67, 0x2f, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x72, 0x61, 0x70, 0x74, 0x6f, 0x72, - 0x2f, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x72, 0x67, 0x73, 0x52, 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x22, 0x3e, + 0x0a, 0x1f, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x6e, 0x69, 0x74, + 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 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, 0x22, 0xda, + 0x01, 0x0a, 0x10, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3a, 0x0a, + 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, + 0x74, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x72, 0x67, 0x73, 0x52, 0x09, + 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x35, 0x0a, 0x0c, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x73, 0x52, 0x0b, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, + 0x12, 0x39, 0x0a, 0x0e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x56, 0x65, 0x6c, 0x6f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0d, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x55, 0x0a, 0x10, 0x55, + 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x76, 0x66, 0x73, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x66, 0x73, 0x50, 0x61, 0x74, 0x68, 0x12, 0x12, + 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x69, + 0x7a, 0x65, 0x42, 0x33, 0x5a, 0x31, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, + 0x64, 0x65, 0x78, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x76, + 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x72, 0x61, 0x70, 0x74, 0x6f, 0x72, 0x2f, 0x66, 0x6c, 0x6f, 0x77, + 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1223,7 +1333,7 @@ func file_artifact_collector_proto_rawDescGZIP() []byte { } var file_artifact_collector_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_artifact_collector_proto_msgTypes = make([]protoimpl.MessageInfo, 11) +var file_artifact_collector_proto_msgTypes = make([]protoimpl.MessageInfo, 12) var file_artifact_collector_proto_goTypes = []interface{}{ (ArtifactCollectorContext_State)(0), // 0: proto.ArtifactCollectorContext.State (*ArtifactParameters)(nil), // 1: proto.ArtifactParameters @@ -1232,35 +1342,38 @@ var file_artifact_collector_proto_goTypes = []interface{}{ (*ArtifactCollectorResponse)(nil), // 4: proto.ArtifactCollectorResponse (*ArtifactUploadedFileInfo)(nil), // 5: proto.ArtifactUploadedFileInfo (*PingContext)(nil), // 6: proto.PingContext - (*ArtifactCollectorContext)(nil), // 7: proto.ArtifactCollectorContext - (*LabelEvents)(nil), // 8: proto.LabelEvents - (*GetClientMonitoringStateRequest)(nil), // 9: proto.GetClientMonitoringStateRequest - (*ClientEventTable)(nil), // 10: proto.ClientEventTable - (*UploadedFileInfo)(nil), // 11: proto.UploadedFileInfo - (*proto.VQLEnv)(nil), // 12: proto.VQLEnv - (*proto.VQLCollectorArgs)(nil), // 13: proto.VQLCollectorArgs - (*proto1.LogMessage)(nil), // 14: proto.LogMessage - (*proto1.VeloMessage)(nil), // 15: proto.VeloMessage + (*QueryStats)(nil), // 7: proto.QueryStats + (*ArtifactCollectorContext)(nil), // 8: proto.ArtifactCollectorContext + (*LabelEvents)(nil), // 9: proto.LabelEvents + (*GetClientMonitoringStateRequest)(nil), // 10: proto.GetClientMonitoringStateRequest + (*ClientEventTable)(nil), // 11: proto.ClientEventTable + (*UploadedFileInfo)(nil), // 12: proto.UploadedFileInfo + (*proto.VQLEnv)(nil), // 13: proto.VQLEnv + (*proto.VQLCollectorArgs)(nil), // 14: proto.VQLCollectorArgs + (*proto1.VeloStatus)(nil), // 15: proto.VeloStatus + (*proto1.LogMessage)(nil), // 16: proto.LogMessage + (*proto1.VeloMessage)(nil), // 17: proto.VeloMessage } var file_artifact_collector_proto_depIdxs = []int32{ - 12, // 0: proto.ArtifactParameters.env:type_name -> proto.VQLEnv + 13, // 0: proto.ArtifactParameters.env:type_name -> proto.VQLEnv 1, // 1: proto.ArtifactSpec.parameters:type_name -> proto.ArtifactParameters 2, // 2: proto.ArtifactCollectorArgs.specs:type_name -> proto.ArtifactSpec - 13, // 3: proto.ArtifactCollectorArgs.compiled_collector_args:type_name -> proto.VQLCollectorArgs + 14, // 3: proto.ArtifactCollectorArgs.compiled_collector_args:type_name -> proto.VQLCollectorArgs 3, // 4: proto.ArtifactCollectorResponse.request:type_name -> proto.ArtifactCollectorArgs 3, // 5: proto.ArtifactCollectorContext.request:type_name -> proto.ArtifactCollectorArgs 0, // 6: proto.ArtifactCollectorContext.state:type_name -> proto.ArtifactCollectorContext.State - 5, // 7: proto.ArtifactCollectorContext.uploaded_files:type_name -> proto.ArtifactUploadedFileInfo - 14, // 8: proto.ArtifactCollectorContext.logs:type_name -> proto.LogMessage - 3, // 9: proto.LabelEvents.artifacts:type_name -> proto.ArtifactCollectorArgs - 3, // 10: proto.ClientEventTable.artifacts:type_name -> proto.ArtifactCollectorArgs - 8, // 11: proto.ClientEventTable.label_events:type_name -> proto.LabelEvents - 15, // 12: proto.ClientEventTable.client_message:type_name -> proto.VeloMessage - 13, // [13:13] is the sub-list for method output_type - 13, // [13:13] is the sub-list for method input_type - 13, // [13:13] is the sub-list for extension type_name - 13, // [13:13] is the sub-list for extension extendee - 0, // [0:13] is the sub-list for field type_name + 15, // 7: proto.ArtifactCollectorContext.query_stats:type_name -> proto.VeloStatus + 5, // 8: proto.ArtifactCollectorContext.uploaded_files:type_name -> proto.ArtifactUploadedFileInfo + 16, // 9: proto.ArtifactCollectorContext.logs:type_name -> proto.LogMessage + 3, // 10: proto.LabelEvents.artifacts:type_name -> proto.ArtifactCollectorArgs + 3, // 11: proto.ClientEventTable.artifacts:type_name -> proto.ArtifactCollectorArgs + 9, // 12: proto.ClientEventTable.label_events:type_name -> proto.LabelEvents + 17, // 13: proto.ClientEventTable.client_message:type_name -> proto.VeloMessage + 14, // [14:14] is the sub-list for method output_type + 14, // [14:14] is the sub-list for method input_type + 14, // [14:14] is the sub-list for extension type_name + 14, // [14:14] is the sub-list for extension extendee + 0, // [0:14] is the sub-list for field type_name } func init() { file_artifact_collector_proto_init() } @@ -1342,7 +1455,7 @@ func file_artifact_collector_proto_init() { } } file_artifact_collector_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ArtifactCollectorContext); i { + switch v := v.(*QueryStats); i { case 0: return &v.state case 1: @@ -1354,7 +1467,7 @@ func file_artifact_collector_proto_init() { } } file_artifact_collector_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LabelEvents); i { + switch v := v.(*ArtifactCollectorContext); i { case 0: return &v.state case 1: @@ -1366,7 +1479,7 @@ func file_artifact_collector_proto_init() { } } file_artifact_collector_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetClientMonitoringStateRequest); i { + switch v := v.(*LabelEvents); i { case 0: return &v.state case 1: @@ -1378,7 +1491,7 @@ func file_artifact_collector_proto_init() { } } file_artifact_collector_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ClientEventTable); i { + switch v := v.(*GetClientMonitoringStateRequest); i { case 0: return &v.state case 1: @@ -1390,6 +1503,18 @@ func file_artifact_collector_proto_init() { } } file_artifact_collector_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClientEventTable); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_artifact_collector_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UploadedFileInfo); i { case 0: return &v.state @@ -1408,7 +1533,7 @@ func file_artifact_collector_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_artifact_collector_proto_rawDesc, NumEnums: 1, - NumMessages: 11, + NumMessages: 12, NumExtensions: 0, NumServices: 0, }, diff --git a/flows/proto/artifact_collector.proto b/flows/proto/artifact_collector.proto index 1c5553e536..bc6279c3cf 100644 --- a/flows/proto/artifact_collector.proto +++ b/flows/proto/artifact_collector.proto @@ -92,12 +92,24 @@ message ArtifactUploadedFileInfo { // updated each time anyting about the collection is changed, without // having to race updating the main record. The read active_time is // the latest between this record and the one in -// ArtifactCollectorContext +// ArtifactCollectorContext. This is mainly used by the GUI to notice +// when a collection is updated. message PingContext { uint64 active_time = 1; } -// This context is serialized into the data store. +// Keep track of each individual query and its status - a collection +// can contain multiple queries and artifacts some may fail and others +// may succeed. We keep track of the total here. +message QueryStats { + uint64 query_id = 1; + uint64 execution_duration = 2; + string status = 3; + string query_name = 4; +} + +// This context is serialized into the data store. We keep track of +// all aspects of a collection. message ArtifactCollectorContext { string client_id = 27; string session_id = 13; @@ -120,6 +132,7 @@ message ArtifactCollectorContext { uint64 total_collected_rows = 28; uint64 total_logs = 32; + int64 total_requests = 35; int64 outstanding_requests = 31; // We expect the next response from the client to have this id. @@ -147,6 +160,9 @@ message ArtifactCollectorContext { description: "Contents of an error status sent by the client." }]; + // This is used to keep track of any System.Flow.Completion events + // we already sent. We only send exactly one such message when the + // flow is completed. bool user_notified = 16; // Some of the collected artifacts may not have results. @@ -155,6 +171,9 @@ message ArtifactCollectorContext { "This takes the form artifact name/source name." }]; + // Keep detailed track of each query status. + repeated VeloStatus query_stats = 34; + // The below are not serialized but are used during execution. // Uploads are now permanently stored in a json file. This field is diff --git a/gui/velociraptor/package-lock.json b/gui/velociraptor/package-lock.json index 031e7e6750..06838ba5f7 100644 --- a/gui/velociraptor/package-lock.json +++ b/gui/velociraptor/package-lock.json @@ -11,7 +11,7 @@ "@fortawesome/fontawesome-svg-core": "^1.3.0", "@fortawesome/free-solid-svg-icons": "^5.15.4", "@fortawesome/react-fontawesome": "0.2.0", - "ace-builds": "^1.9.3", + "ace-builds": "1.9.5", "axios": ">=0.27.2", "axios-retry": "3.3.1", "bootstrap": "^4.6.2", @@ -30,7 +30,7 @@ "is-svg": "^4.3.2", "lodash": "^4.17.21", "moment": "^2.29.4", - "moment-timezone": "^0.5.34", + "moment-timezone": "0.5.37", "npm-watch": "^0.11.0", "prop-types": "^15.8.1", "qs": "^6.11.0", @@ -47,6 +47,7 @@ "react-bootstrap-table2-toolkit": "^2.1.3", "react-bootstrap-typeahead": "^5.2.2", "react-calendar-timeline": "^0.28.0", + "react-contexify": "5.0.0", "react-datepicker": "^3.8.0", "react-datetime-picker": "^3.5.0", "react-dom": "^16.14.0", @@ -4293,9 +4294,9 @@ } }, "node_modules/ace-builds": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.9.3.tgz", - "integrity": "sha512-dpKkTdXYBbP99EUperoIzvRb0MCxqWbLIvz8dhg+APCVikO53JJuyZ+YDlAwxWa78ULkie/M6njOYrH0vjP6+A==" + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.9.5.tgz", + "integrity": "sha512-6iVEUPfqiKIGKsA63InrUhRRASmfuGnJCUBzkz/pL1BCPPEjasBp6fBA7mj4ovihICouopYYZaAKYhg6zypAwg==" }, "node_modules/acorn": { "version": "8.7.0", @@ -6263,6 +6264,14 @@ "mimic-response": "^1.0.0" } }, + "node_modules/clsx": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "engines": { + "node": ">=6" + } + }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -13714,9 +13723,9 @@ } }, "node_modules/moment-timezone": { - "version": "0.5.34", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.34.tgz", - "integrity": "sha512-3zAEHh2hKUs3EXLESx/wsgw6IQdusOT8Bxm3D9UrHPQR7zlMmzwybC8zHEM1tQ4LJwP7fcxrWr8tuBg05fFCbg==", + "version": "0.5.37", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.37.tgz", + "integrity": "sha512-uEDzDNFhfaywRl+vwXxffjjq1q0Vzr+fcQpQ1bU0kbzorfS7zVtZnCnGc8mhWmF39d4g4YriF6kwA75mJKE/Zg==", "dependencies": { "moment": ">= 2.9.0" }, @@ -16298,6 +16307,21 @@ "react-dom": ">=16.3" } }, + "node_modules/react-contexify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/react-contexify/-/react-contexify-5.0.0.tgz", + "integrity": "sha512-2FIp7lxJ6dtfGr8EZ4uVV5p5TQjd0n2h/JU7PrejNIMiCeZWvSVPFh4lj1ZvjXosglBvP7q5JQQ8yUCdSaMSaw==", + "dependencies": { + "clsx": "^1.1.1" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": ">=16", + "react-dom": ">=16" + } + }, "node_modules/react-datepicker": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-3.8.0.tgz", @@ -25187,9 +25211,9 @@ } }, "ace-builds": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.9.3.tgz", - "integrity": "sha512-dpKkTdXYBbP99EUperoIzvRb0MCxqWbLIvz8dhg+APCVikO53JJuyZ+YDlAwxWa78ULkie/M6njOYrH0vjP6+A==" + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.9.5.tgz", + "integrity": "sha512-6iVEUPfqiKIGKsA63InrUhRRASmfuGnJCUBzkz/pL1BCPPEjasBp6fBA7mj4ovihICouopYYZaAKYhg6zypAwg==" }, "acorn": { "version": "8.7.0", @@ -26721,6 +26745,11 @@ "mimic-response": "^1.0.0" } }, + "clsx": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==" + }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -32363,9 +32392,9 @@ "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==" }, "moment-timezone": { - "version": "0.5.34", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.34.tgz", - "integrity": "sha512-3zAEHh2hKUs3EXLESx/wsgw6IQdusOT8Bxm3D9UrHPQR7zlMmzwybC8zHEM1tQ4LJwP7fcxrWr8tuBg05fFCbg==", + "version": "0.5.37", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.37.tgz", + "integrity": "sha512-uEDzDNFhfaywRl+vwXxffjjq1q0Vzr+fcQpQ1bU0kbzorfS7zVtZnCnGc8mhWmF39d4g4YriF6kwA75mJKE/Zg==", "requires": { "moment": ">= 2.9.0" } @@ -34236,6 +34265,14 @@ "memoize-one": "^5.1.1" } }, + "react-contexify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/react-contexify/-/react-contexify-5.0.0.tgz", + "integrity": "sha512-2FIp7lxJ6dtfGr8EZ4uVV5p5TQjd0n2h/JU7PrejNIMiCeZWvSVPFh4lj1ZvjXosglBvP7q5JQQ8yUCdSaMSaw==", + "requires": { + "clsx": "^1.1.1" + } + }, "react-datepicker": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-3.8.0.tgz", diff --git a/gui/velociraptor/package.json b/gui/velociraptor/package.json index 0615b1ce8a..88e24ef2be 100644 --- a/gui/velociraptor/package.json +++ b/gui/velociraptor/package.json @@ -6,7 +6,7 @@ "@fortawesome/fontawesome-svg-core": "^1.3.0", "@fortawesome/free-solid-svg-icons": "^5.15.4", "@fortawesome/react-fontawesome": "0.2.0", - "ace-builds": "1.9.3", + "ace-builds": "1.9.5", "axios": ">=0.27.2", "axios-retry": "3.3.1", "bootstrap": "^4.6.2", @@ -25,7 +25,7 @@ "is-svg": "^4.3.2", "lodash": "^4.17.21", "moment": "^2.29.4", - "moment-timezone": "^0.5.34", + "moment-timezone": "0.5.37", "npm-watch": "^0.11.0", "prop-types": "^15.8.1", "qs": "^6.11.0", @@ -42,6 +42,7 @@ "react-bootstrap-table2-toolkit": "^2.1.3", "react-bootstrap-typeahead": "^5.2.2", "react-calendar-timeline": "^0.28.0", + "react-contexify": "5.0.0", "react-datepicker": "^3.8.0", "react-datetime-picker": "^3.5.0", "react-dom": "^16.14.0", diff --git a/gui/velociraptor/public/index.html b/gui/velociraptor/public/index.html index 5b4d1467fc..4c44ca6b0b 100644 --- a/gui/velociraptor/public/index.html +++ b/gui/velociraptor/public/index.html @@ -7,6 +7,7 @@ 'debug': false, 'lang': 'en', 'base_path': "{{.BasePath}}", + 'OrgId': "{{.OrgId}}", }; window.CsrfToken = "{{.CsrfToken}}"; window.base_path = "{{.BasePath}}"; diff --git a/gui/velociraptor/src/App.js b/gui/velociraptor/src/App.js index 75a403897b..90465a66d0 100644 --- a/gui/velociraptor/src/App.js +++ b/gui/velociraptor/src/App.js @@ -29,7 +29,7 @@ import LoginPage from './components/welcome/login.js'; import LogoffPage from './components/welcome/logoff.js'; import KeyboardHelp from './components/core/keyboard-help.js'; import { UserSettings } from './components/core/user.js'; - +import { ContextMenuPopup } from './components/utils/context.js'; import { Switch, Route } from "react-router-dom"; import { Join } from './components/utils/paths.js'; import { withRouter } from "react-router-dom"; @@ -222,6 +222,7 @@ class App extends Component { + ); diff --git a/gui/velociraptor/src/components/core/api-service.js b/gui/velociraptor/src/components/core/api-service.js index a8bb1f9e02..7f9915e9c6 100644 --- a/gui/velociraptor/src/components/core/api-service.js +++ b/gui/velociraptor/src/components/core/api-service.js @@ -1,7 +1,7 @@ import axios from 'axios'; import _ from 'lodash'; - +import qs from 'qs'; import axiosRetry from 'axios-retry'; // The following is copied from axios-retry to avoid a bug "cannot @@ -130,7 +130,7 @@ const get = function(url, params, cancel_token) { params: params, headers: { "X-CSRF-Token": window.CsrfToken, - "Grpc-Metadata-OrgId": window.globals.OrgId || "", + "Grpc-Metadata-OrgId": window.globals.OrgId || "root", }, cancelToken: cancel_token, }).then(response=>{ @@ -151,7 +151,7 @@ const get_blob = function(url, params, cancel_token) { params: params, headers: { "X-CSRF-Token": window.CsrfToken, - "Grpc-Metadata-OrgId": window.globals.OrgId || "", + "Grpc-Metadata-OrgId": window.globals.OrgId || "root", }, cancelToken: cancel_token, }).then((blob) => { @@ -181,7 +181,7 @@ const post = function(url, params, cancel_token) { cancelToken: cancel_token, headers: { "X-CSRF-Token": window.CsrfToken, - "Grpc-Metadata-OrgId": window.globals.OrgId || "", + "Grpc-Metadata-OrgId": window.globals.OrgId || "root", } }).then(response=>{ // Update the csrf token. @@ -207,11 +207,23 @@ const upload = function(url, files, params) { data: fd, headers: { "X-CSRF-Token": window.CsrfToken, - "Grpc-Metadata-OrgId": window.globals.OrgId || "", + "Grpc-Metadata-OrgId": window.globals.OrgId || "root", } }).catch(handle_error); }; +// Prepare a suitable href link for +const href = function(url, params, options) { + params = params || {}; + Object.assign(params, {org_id: window.globals.OrgId || "root"}); + + options = options || {}; + Object.assign(options, {indices: false}); + + return base_path + url + "?" + qs.stringify(params, options); +}; + + var hooks = []; /* eslint import/no-anonymous-default-export: [2, {"allowObject": true}] */ @@ -222,4 +234,5 @@ export default { upload: upload, hooks: hooks, base_path: base_path, + href: href, }; diff --git a/gui/velociraptor/src/components/core/keyboard-help.js b/gui/velociraptor/src/components/core/keyboard-help.js index 5a16f63420..62e83e3144 100644 --- a/gui/velociraptor/src/components/core/keyboard-help.js +++ b/gui/velociraptor/src/components/core/keyboard-help.js @@ -24,8 +24,8 @@ const helpTextCol1 = [ ["alt+p", T("Parameters configuration Step")], ["alt+r", T("Collection resource specification")], ["ctrl+l", T("Launch artifact")], - ["ctrl+right", T("Go to next step")], - ["ctrl+left", T("Go to previous step")], + ["ctrl+shift+right", T("Go to next step")], + ["ctrl+shift+left", T("Go to previous step")], ]], ]; diff --git a/gui/velociraptor/src/components/core/paged-table.js b/gui/velociraptor/src/components/core/paged-table.js index 9cadf28bda..efeb7f5610 100644 --- a/gui/velociraptor/src/components/core/paged-table.js +++ b/gui/velociraptor/src/components/core/paged-table.js @@ -12,7 +12,6 @@ import axios from 'axios'; import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import qs from 'qs'; import BootstrapTable from 'react-bootstrap-table-next'; import paginationFactory from 'react-bootstrap-table2-paginator'; import Button from 'react-bootstrap/Button'; @@ -458,15 +457,19 @@ class VeloPagedTable extends Component { diff --git a/gui/velociraptor/src/css/_variables.css b/gui/velociraptor/src/css/_variables.css index 48bb2c6545..dae92259d3 100644 --- a/gui/velociraptor/src/css/_variables.css +++ b/gui/velociraptor/src/css/_variables.css @@ -11,6 +11,11 @@ --font-json: roboto-mono, Menlo, Monaco, Consolas, "Courier New", monospace; --font-monospace: roboto-mono, "Courier New", Courier, monospace; + --color-calendar-background: #f0f0f0; + --background-calendar-tile-now: #feffe0; + --background-calendar-tile-active: var(--color-table-row-selected); + --color-calendar-tile: var(--color-foreground); + --color-canvas-background: #ffffff; --color-foreground: #000; --color-foreground-inverse: #fff; @@ -50,7 +55,6 @@ --color-no-link-color: #bbb; --color-notification-highlight-color: #eee; --color-no-content-color: #e0e0e0; - --color-grr-blue: #2aabd2; --color-hint-border-color: #f0c36d; --color-hint-background-color: #f9edbe; --color-section-separator: #efefef; @@ -74,4 +78,10 @@ --color-timeline-7: #471ecb; --color-vfs-files-timestomped: #bbdfff; + + --color-accent: #0096ff; + --color-accent-100: #0096ff; + --color-accent-75: #0096ffb0; + --color-accent-50: #0096ff80; + --color-accent-25: #0096ff40; } diff --git a/gui/velociraptor/src/css/index.css b/gui/velociraptor/src/css/index.css index ca7ce381a6..5aaea43b70 100644 --- a/gui/velociraptor/src/css/index.css +++ b/gui/velociraptor/src/css/index.css @@ -67,17 +67,21 @@ code { } -.dropdown-item { +.dropdown-item, +.dropdown-item:focus { color: var(--color-foreground); background: var(--color-btn-default-background); font-family: var(--font-family-sans-serif); font-size: var(--font-size-base); } -.dropdown-item:hover { - background: var(--color-accent-50); +.dropdown-item:hover, +.dropdown-item.active:hover { + background: var(--color-accent-75); } -.dropdown-item.active { +.dropdown-item.active, +.dropdown-item.active:focus { background: var(--color-accent-50); + color: var(--color-foreground); } diff --git a/gui/velociraptor/src/themes/coolgray-dark.css b/gui/velociraptor/src/themes/coolgray-dark.css index b2489e4c7b..d4e6bccce8 100644 --- a/gui/velociraptor/src/themes/coolgray-dark.css +++ b/gui/velociraptor/src/themes/coolgray-dark.css @@ -35,10 +35,10 @@ --accent-color: #87b8dd; --color-accent: 135, 184, 221; --color-accent-complement: #dead87; - --color-accent-100: rgba(var(--color-accent), 1); - --color-accent-75: rgba(var(--color-accent), 0.75); - --color-accent-50: rgba(var(--color-accent), 0.5); - --color-accent-25: rgba(var(--color-accent), 0.25); + --color-accent-100: #87b8ddff; + --color-accent-75: #87b8ddb0; + --color-accent-50: #87b8dd80; + --color-accent-25: #87b8dd40; --color-header-background: #141a1d; --color-footer-background: var(--color-canvas-background); @@ -103,7 +103,7 @@ --color-timeline-7: #471ecb; --color-vfs-files-timestomped: #ed5d40; - --color-calendar-background: #121212; + --color-calendar-background: var(--color-canvas-background); --color-level-error: #ff0000; } @@ -838,7 +838,7 @@ body.coolgray-dark { /* react timelines */ .coolgray-dark .react-calendar-timeline .rct-sidebar { - color: var(--color-foreground); + color: var(--color-foreground); } /* file tree */ @@ -867,20 +867,10 @@ body.coolgray-dark { } .coolgray-dark .dropdown-item { - color: var(--color-foreground); - background: var(--color-canvas-background); font-family: var(--font-family-sans-serif); font-size: var(--font-size-base); } -.coolgray-dark .dropdown-item:hover { - background: var(--color-accent-50); -} - -.coolgray-dark .dropdown-item.active { - background: var(--color-accent-50); -} - /* Datepicker */ .coolgray-dark .react-datepicker, .coolgray-dark .react-datetime-picker { @@ -890,7 +880,7 @@ body.coolgray-dark { .coolgray-dark .react-datetime-picker__inputGroup__input, .coolgray-dark .react-datetime-picker__button { - filter: invert(0); + filter: invert(0.7); } .coolgray-dark .react-datepicker-popper { diff --git a/gui/velociraptor/src/themes/github-dimmed-dark.css b/gui/velociraptor/src/themes/github-dimmed-dark.css index 1343fc78d3..0ce230eaee 100644 --- a/gui/velociraptor/src/themes/github-dimmed-dark.css +++ b/gui/velociraptor/src/themes/github-dimmed-dark.css @@ -95,6 +95,10 @@ --color-vfs-files-timestomped: #ed5d40; --color-calendar-background: #121212; + --color-calendar-background: var(--color-canvas-background); + + --background-calendar-tile-now: #feffe0; + --color-level-error: #aa0000; } @@ -726,33 +730,13 @@ body.github-dimmed-dark { } .github-dimmed-dark .dropdown-item { - color: var(--color-foreground); - background: var(--color-btn-default-background); font-family: var(--font-family-sans-serif); font-size: var(--font-size-base); } -.github-dimmed-dark .dropdown-item:hover { - background: var(--color-accent-50); -} - -.github-dimmed-dark .dropdown-item.active { - background: var(--color-accent-50); -} - -/* Datepicker */ -.github-dimmed-dark .react-datepicker, -.github-dimmed-dark .react-datetime-picker input, -.github-dimmed-dark .react-datetime-picker select, -.github-dimmed-dark .react-datetime-picker button, -.github-dimmed-dark .react-datetime-picker { - background: var(--color-canvas-background); - color: var(--color-foreground); -} - .github-dimmed-dark .react-datetime-picker__inputGroup__input, .github-dimmed-dark .react-datetime-picker__button { - filter: invert(0); + filter: invert(0.7); } .github-dimmed-dark .react-datepicker-popper { @@ -926,18 +910,3 @@ input[type="radio"] { text-shadow: none; box-shadow: none; } - - -/* react calendar */ -.github-dimmed-dark .react-calendar { - background: var(--color-calendar-background); -} - -.github-dimmed-dark .react-calendar .react-calendar__navigation button, -.github-dimmed-dark .react-calendar .react-calendar__tile { - color: var(--color-foreground-dimmed); -} - -.github-dimmed-dark .react-calendar .react-calendar__month-view__days__day--weekend { - color: var(--accent-color); -} diff --git a/gui/velociraptor/src/themes/pink-light.css b/gui/velociraptor/src/themes/pink-light.css index 60febde10e..0ab54e97d3 100644 --- a/gui/velociraptor/src/themes/pink-light.css +++ b/gui/velociraptor/src/themes/pink-light.css @@ -614,21 +614,24 @@ body.pink-light { background: var(--color-canvas-background); } -.pink-light .dropdown-item { - color: var(--color-foreground); - background: var(--color-canvas-background); +.pink-light .dropdown-item, +.pink-light .dropdown-item:focus { font-family: var(--font-family-sans-serif); font-size: var(--font-size-base); + background: var(--color-canvas-background); } -.pink-light .dropdown-item:hover { - background: var(--color-btn-default-background-hover); +.pink-light .dropdown-item.active:hover { + background: var(--color-accent-75); } -.pink-light .dropdown-item.active { - background: var(--color-table-row-selected); +.pink-light .dropdown-item.active, +.pink-light .dropdown-item.active:focus { + background: var(--color-accent-50); + color: var(--color-foreground); } + /* Datepicker */ .pink-light .react-datepicker, .pink-light .react-datetime-picker { diff --git a/gui/velociraptor/src/themes/veloci-dark.css b/gui/velociraptor/src/themes/veloci-dark.css index 0f0f6cc854..bec552f99a 100644 --- a/gui/velociraptor/src/themes/veloci-dark.css +++ b/gui/velociraptor/src/themes/veloci-dark.css @@ -77,7 +77,9 @@ --color-card-heading-background: #444444; --color-table-heading-background: #444444; --color-monospace-color: #eeeeee; + --color-calendar-background: #121212; + --color-calendar-tile: #121212; --color-timeline-header: #cdcdcd20; --color-timeline-table-shown: #dd4b3920; @@ -601,20 +603,6 @@ body.veloci-dark { color: var(--color-foreground); } -/* react calendar */ -.veloci-dark .react-calendar { - background: var(--color-calendar-background); -} - -.veloci-dark .react-calendar .react-calendar__navigation button, -.veloci-dark .react-calendar .react-calendar__tile { - color: var(--color-foreground-dimmed); -} - -.veloci-dark .react-calendar .react-calendar__month-view__days__day--weekend { - color: var(--accent-color); -} - /* file tree */ .veloci-dark .file-tree ul { background: var(--color-canvas-background); @@ -635,19 +623,20 @@ body.veloci-dark { background: var(--color-canvas-background); } -.veloci-dark a.dropdown-item { - color: var(--color-canvas-background); +.veloci-dark .dropdown-item { + background: var(--color-canvas-background); + color: var(--color-foreground); font-family: var(--font-family-sans-serif); font-size: var(--font-size-base); } .veloci-dark .dropdown-item:hover, -.veloci-dark .dropdown-item:focus { +.veloci-dark .dropdown-item.active:hover { background: var(--color-btn-default-background-hover); } .veloci-dark .dropdown-item.active { - background: var(--color-table-row-selected); + background: var(--color-accent-50); color: var(--color-foreground); } diff --git a/gui/velociraptor/src/themes/veloci-light.css b/gui/velociraptor/src/themes/veloci-light.css index 78d8d098fb..f5586d4152 100644 --- a/gui/velociraptor/src/themes/veloci-light.css +++ b/gui/velociraptor/src/themes/veloci-light.css @@ -74,6 +74,8 @@ --color-table-row-hover: rgba(0, 0, 0, 0.01); --color-code: #990000; + --background-calendar-tile-active: #5cd00a80; + --color-timeline-header: #cdcdcd20; --color-timeline-table-shown: #5cd00a80; --color-timeline-1: #dff0d820; diff --git a/gui/velociraptor/template.go b/gui/velociraptor/template.go index c1d47fabd1..297aad7a61 100644 --- a/gui/velociraptor/template.go +++ b/gui/velociraptor/template.go @@ -2,17 +2,19 @@ package velociraptor // The template to expand into the index.html page type HTMLtemplateArgs struct { - Timestamp int64 - Heading string - Help_url string - Report_url string - Version string - CsrfToken string - BasePath string - UserTheme string + Timestamp int64 + Heading string + Help_url string + Report_url string + Version string + CsrfToken string + BasePath string + UserTheme string + Applications string // This is a JSON serialized instance of ErrState ErrState string + OrgId string } type AuthenticatorInfo struct { diff --git a/gui/velociraptor/yarn.lock b/gui/velociraptor/yarn.lock index 0d475045a8..44d908f012 100644 --- a/gui/velociraptor/yarn.lock +++ b/gui/velociraptor/yarn.lock @@ -1242,10 +1242,10 @@ "gud" "^1.0.0" "warning" "^4.0.3" -"@interactjs/types@1.10.14": - "integrity" "sha512-ds6wAI9aDzojzr7UBvifUJIgogCL1ZL0nfBrXDv5GVMaW7gBglqejaeiQ1a0cRiHII/8p8s5AwPhhODTDM8RCQ==" - "resolved" "https://registry.npmjs.org/@interactjs/types/-/types-1.10.14.tgz" - "version" "1.10.14" +"@interactjs/types@1.10.17": + "integrity" "sha512-X2JpoM7xUw0p9Me0tMaI0HNfcF/Hd07ZZlzpnpEMpGerUZOLoyeThrV9P+CrBHxZrluWJrigJbcdqXliFd0YMA==" + "resolved" "https://registry.npmjs.org/@interactjs/types/-/types-1.10.17.tgz" + "version" "1.10.17" "@istanbuljs/load-nyc-config@^1.0.0": "integrity" "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==" @@ -2546,10 +2546,10 @@ "mime-types" "~2.1.24" "negotiator" "0.6.2" -"ace-builds@^1.4.13", "ace-builds@1.7.0": - "integrity" "sha512-5sruz5avLYUGRH5iWbpM4vLnAhHEoryviLP0J2uxKd4I2VQ9ImFCJDehSpiukjP745x2ypg/NIfLoWpvmBLDWg==" - "resolved" "https://registry.npmjs.org/ace-builds/-/ace-builds-1.7.0.tgz" - "version" "1.7.0" +"ace-builds@^1.4.13", "ace-builds@1.9.5": + "integrity" "sha512-6iVEUPfqiKIGKsA63InrUhRRASmfuGnJCUBzkz/pL1BCPPEjasBp6fBA7mj4ovihICouopYYZaAKYhg6zypAwg==" + "resolved" "https://registry.npmjs.org/ace-builds/-/ace-builds-1.9.5.tgz" + "version" "1.9.5" "acorn-globals@^6.0.0": "integrity" "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==" @@ -3268,10 +3268,10 @@ "resolved" "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz" "version" "1.0.0" -"bootstrap@^4.6.1": - "integrity" "sha512-0dj+VgI9Ecom+rvvpNZ4MUZJz8dcX7WCX+eTID9+/8HgOkv3dsRzi8BGeZJCQU6flWQVYxwTQnEZFrmJSEO7og==" - "resolved" "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.1.tgz" - "version" "4.6.1" +"bootstrap@^4.6.2": + "integrity" "sha512-51Bbp/Uxr9aTuy6ca/8FbFloBUJZLHwnhTcnjIeRn2suQWsWzcuJhGjKDB5eppVte/8oCdOL3VuwxvZDUggwGQ==" + "resolved" "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.2.tgz" + "version" "4.6.2" "boxen@^5.0.0": "integrity" "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==" @@ -3763,6 +3763,11 @@ dependencies: "mimic-response" "^1.0.0" +"clsx@^1.1.1": + "integrity" "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==" + "resolved" "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz" + "version" "1.2.1" + "co@^4.6.0": "integrity" "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" "resolved" "https://registry.npmjs.org/co/-/co-4.6.0.tgz" @@ -4355,64 +4360,66 @@ "resolved" "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz" "version" "1.0.1" -"d3-array@^2.3.0": - "integrity" "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==" - "resolved" "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz" - "version" "2.12.1" +"d3-array@2 - 3", "d3-array@2.10.0 - 3": + "integrity" "sha512-3yXFQo0oG3QCxbF06rMPFyGRMGJNS7NvsV1+2joOjbBE+9xvWQ8+GcMJAjRCzw06zQ3/arXeJgbPYcjUCuC+3g==" + "resolved" "https://registry.npmjs.org/d3-array/-/d3-array-3.2.0.tgz" + "version" "3.2.0" dependencies: - "internmap" "^1.0.0" + "internmap" "1 - 2" -"d3-color@1 - 2": - "integrity" "sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ==" - "resolved" "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz" - "version" "2.0.0" +"d3-color@1 - 3": + "integrity" "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==" + "resolved" "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz" + "version" "3.1.0" -"d3-format@1 - 2": - "integrity" "sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA==" - "resolved" "https://registry.npmjs.org/d3-format/-/d3-format-2.0.0.tgz" - "version" "2.0.0" +"d3-format@1 - 3": + "integrity" "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==" + "resolved" "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz" + "version" "3.1.0" -"d3-interpolate@^2.0.0", "d3-interpolate@1.2.0 - 2": - "integrity" "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==" - "resolved" "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz" - "version" "2.0.1" +"d3-interpolate@^3.0.1", "d3-interpolate@1.2.0 - 3": + "integrity" "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==" + "resolved" "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz" + "version" "3.0.1" dependencies: - "d3-color" "1 - 2" + "d3-color" "1 - 3" -"d3-path@1 - 2": - "integrity" "sha512-ZwZQxKhBnv9yHaiWd6ZU4x5BtCQ7pXszEV9CU6kRgwIQVQGLMv1oiL4M+MK/n79sYzsj+gcgpPQSctJUsLN7fA==" - "resolved" "https://registry.npmjs.org/d3-path/-/d3-path-2.0.0.tgz" - "version" "2.0.0" +"d3-path@1 - 3": + "integrity" "sha512-gq6gZom9AFZby0YLduxT1qmrp4xpBA1YZr19OI717WIdKE2OM5ETq5qrHLb301IgxhLwcuxvGZVLeeWc/k1I6w==" + "resolved" "https://registry.npmjs.org/d3-path/-/d3-path-3.0.1.tgz" + "version" "3.0.1" -"d3-scale@^3.0.0": - "integrity" "sha512-PG6gtpbPCFqKbvdBEswQcJcTzHC8VEd/XzezF5e68KlkT4/ggELw/nR1tv863jY6ufKTvDlzCMZvhe06codbbA==" - "resolved" "https://registry.npmjs.org/d3-scale/-/d3-scale-3.2.4.tgz" - "version" "3.2.4" +"d3-scale@^4.0.2": + "integrity" "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==" + "resolved" "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz" + "version" "4.0.2" dependencies: - "d3-array" "^2.3.0" - "d3-format" "1 - 2" - "d3-interpolate" "1.2.0 - 2" - "d3-time" "1 - 2" - "d3-time-format" "2 - 3" + "d3-array" "2.10.0 - 3" + "d3-format" "1 - 3" + "d3-interpolate" "1.2.0 - 3" + "d3-time" "2.1.1 - 3" + "d3-time-format" "2 - 4" -"d3-shape@^2.0.0": - "integrity" "sha512-PnjUqfM2PpskbSLTJvAzp2Wv4CZsnAgTfcVRTwW03QR3MkXF8Uo7B1y/lWkAsmbKwuecto++4NlsYcvYpXpTHA==" - "resolved" "https://registry.npmjs.org/d3-shape/-/d3-shape-2.1.0.tgz" - "version" "2.1.0" +"d3-shape@^3.1.0": + "integrity" "sha512-tGDh1Muf8kWjEDT/LswZJ8WF85yDZLvVJpYU9Nq+8+yW1Z5enxrmXOhTArlkaElU+CTn0OTVNli+/i+HP45QEQ==" + "resolved" "https://registry.npmjs.org/d3-shape/-/d3-shape-3.1.0.tgz" + "version" "3.1.0" dependencies: - "d3-path" "1 - 2" + "d3-path" "1 - 3" -"d3-time-format@2 - 3": - "integrity" "sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag==" - "resolved" "https://registry.npmjs.org/d3-time-format/-/d3-time-format-3.0.0.tgz" - "version" "3.0.0" +"d3-time-format@2 - 4": + "integrity" "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==" + "resolved" "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz" + "version" "4.1.0" dependencies: - "d3-time" "1 - 2" + "d3-time" "1 - 3" -"d3-time@1 - 2": - "integrity" "sha512-2mvhstTFcMvwStWd9Tj3e6CEqtOivtD8AUiHT8ido/xmzrI9ijrUUihZ6nHuf/vsScRBonagOdj0Vv+SEL5G3Q==" - "resolved" "https://registry.npmjs.org/d3-time/-/d3-time-2.0.0.tgz" - "version" "2.0.0" +"d3-time@1 - 3", "d3-time@2.1.1 - 3": + "integrity" "sha512-zmV3lRnlaLI08y9IMRXSDshQb5Nj77smnfpnd2LrBa/2K281Jijactokeak14QacHs/kKq0AQ121nidNYlarbQ==" + "resolved" "https://registry.npmjs.org/d3-time/-/d3-time-3.0.0.tgz" + "version" "3.0.0" + dependencies: + "d3-array" "2 - 3" "damerau-levenshtein@^1.0.7": "integrity" "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==" @@ -6620,12 +6627,12 @@ "resolved" "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz" "version" "0.1.1" -"interactjs@^1.10.14", "interactjs@^1.3.4": - "integrity" "sha512-UhwZhuFqmKLSJ1o04LlvFMdxohwvuMjVrQC96TI8/dEhF/dS47Tqm3Po5i4yKXaCMIqI8qdvmyfeIWdGLYSClA==" - "resolved" "https://registry.npmjs.org/interactjs/-/interactjs-1.10.14.tgz" - "version" "1.10.14" +"interactjs@^1.10.17", "interactjs@^1.3.4": + "integrity" "sha512-grjHJgnWkCoQLmAlk2yalNd1r0ztUhXLJNVjSOfWn1wfNNgU2tx1cDEkro9WYerDNC9UG3MZTeD4O6zOM5gbIA==" + "resolved" "https://registry.npmjs.org/interactjs/-/interactjs-1.10.17.tgz" + "version" "1.10.17" dependencies: - "@interactjs/types" "1.10.14" + "@interactjs/types" "1.10.17" "internal-slot@^1.0.3": "integrity" "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==" @@ -6636,10 +6643,10 @@ "has" "^1.0.3" "side-channel" "^1.0.4" -"internmap@^1.0.0": - "integrity" "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==" - "resolved" "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz" - "version" "1.0.1" +"internmap@1 - 2": + "integrity" "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==" + "resolved" "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz" + "version" "2.0.3" "invariant@^2.2.1", "invariant@^2.2.4": "integrity" "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==" @@ -8231,10 +8238,10 @@ "resolved" "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" "version" "1.0.4" -"moment-timezone@^0.5.34": - "integrity" "sha512-3zAEHh2hKUs3EXLESx/wsgw6IQdusOT8Bxm3D9UrHPQR7zlMmzwybC8zHEM1tQ4LJwP7fcxrWr8tuBg05fFCbg==" - "resolved" "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.34.tgz" - "version" "0.5.34" +"moment-timezone@0.5.37": + "integrity" "sha512-uEDzDNFhfaywRl+vwXxffjjq1q0Vzr+fcQpQ1bU0kbzorfS7zVtZnCnGc8mhWmF39d4g4YriF6kwA75mJKE/Zg==" + "resolved" "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.37.tgz" + "version" "0.5.37" dependencies: "moment" ">= 2.9.0" @@ -9891,6 +9898,13 @@ "merge-class-names" "^1.1.1" "prop-types" "^15.6.0" +"react-contexify@5.0.0": + "integrity" "sha512-2FIp7lxJ6dtfGr8EZ4uVV5p5TQjd0n2h/JU7PrejNIMiCeZWvSVPFh4lj1ZvjXosglBvP7q5JQQ8yUCdSaMSaw==" + "resolved" "https://registry.npmjs.org/react-contexify/-/react-contexify-5.0.0.tgz" + "version" "5.0.0" + dependencies: + "clsx" "^1.1.1" + "react-date-picker@^8.4.0": "integrity" "sha512-zocntugDUyiHmV2Nq1qnsk4kDQuhBLUsDTz7akfIEJ0jVX925w0K5Ai5oZzWFNQOzXL/ITxafmDMuSbzlpBt/A==" "resolved" "https://registry.npmjs.org/react-date-picker/-/react-date-picker-8.4.0.tgz" @@ -9964,7 +9978,7 @@ "strip-ansi" "^6.0.1" "text-table" "^0.2.0" -"react-dom@^0.13.0 || ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0", "react-dom@^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react-dom@^15.5.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react-dom@^15.5.x || ^16.x || ^17.x", "react-dom@^16.0.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.14.0", "react-dom@^16.3.0", "react-dom@^16.3.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.8.0 || ^17.0.0", "react-dom@^16.9.0 || ^17", "react-dom@^17.0.0 || ^16.3.0 || ^15.5.4", "react-dom@>= 16.8.0", "react-dom@>=15.0.0", "react-dom@>=16.3", "react-dom@>=16.3.0", "react-dom@>=16.8.0", "react-dom@16.x": +"react-dom@^0.13.0 || ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0", "react-dom@^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react-dom@^15.5.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react-dom@^15.5.x || ^16.x || ^17.x", "react-dom@^16.0.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.14.0", "react-dom@^16.3.0", "react-dom@^16.3.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.8.0 || ^17.0.0", "react-dom@^16.9.0 || ^17", "react-dom@^17.0.0 || ^16.3.0 || ^15.5.4", "react-dom@>= 16.8.0", "react-dom@>=15.0.0", "react-dom@>=16", "react-dom@>=16.3", "react-dom@>=16.3.0", "react-dom@>=16.8.0", "react-dom@16.x": "integrity" "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==" "resolved" "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz" "version" "16.14.0" @@ -10304,7 +10318,7 @@ "shallowequal" "^1.1.0" "velocity-react" "^1.4.1" -"react@*", "react@^0.13.0 || ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0", "react@^0.14 || ^15 || ^16 || ^17", "react@^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0", "react@^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react@^15.0.2 || ^16.0.0 || ^17.0.0", "react@^15.5.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react@^15.5.x || ^16.x || ^17.x", "react@^16.0.0 || ^17.0.0 || ^18.0.0", "react@^16.14.0", "react@^16.3.0", "react@^16.3.0 || ^17.0.0", "react@^16.3.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || ^17.0.0", "react@^16.9.0 || ^17", "react@^17.0.0 || ^16.3.0 || ^15.5.4", "react@>= 16", "react@>= 16.8.0", "react@>=0.14.0", "react@>=15", "react@>=15.0.0", "react@>=15.0.1", "react@>=16.3", "react@>=16.3.0", "react@>=16.8.0", "react@0.14.x || ^15.0.0 || ^16.0.0 || ^17.0.0", "react@16.x": +"react@*", "react@^0.13.0 || ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0", "react@^0.14 || ^15 || ^16 || ^17", "react@^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0", "react@^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react@^15.0.2 || ^16.0.0 || ^17.0.0", "react@^15.5.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react@^15.5.x || ^16.x || ^17.x", "react@^16.0.0 || ^17.0.0 || ^18.0.0", "react@^16.14.0", "react@^16.3.0", "react@^16.3.0 || ^17.0.0", "react@^16.3.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || ^17.0.0", "react@^16.9.0 || ^17", "react@^17.0.0 || ^16.3.0 || ^15.5.4", "react@>= 16", "react@>= 16.8.0", "react@>=0.14.0", "react@>=15", "react@>=15.0.0", "react@>=15.0.1", "react@>=16", "react@>=16.3", "react@>=16.3.0", "react@>=16.8.0", "react@0.14.x || ^15.0.0 || ^16.0.0 || ^17.0.0", "react@16.x": "integrity" "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==" "resolved" "https://registry.npmjs.org/react/-/react-16.14.0.tgz" "version" "16.14.0" @@ -10387,15 +10401,15 @@ dependencies: "decimal.js-light" "^2.4.1" -"recharts@^2.1.12": - "integrity" "sha512-dAzEuc9AjM+IF0A33QzEdBEUnyGKJcGUPa0MYm0vd38P3WouQjrj2egBrCNInE7ZcQwN+z3MoT7Rw03u8nP9HA==" - "resolved" "https://registry.npmjs.org/recharts/-/recharts-2.1.12.tgz" - "version" "2.1.12" +"recharts@^2.1.13": + "integrity" "sha512-9VWu2nzExmfiMFDHKqRFhYlJVmjzQGVKH5rBetXR4EuyEXuu3Y6cVxQuNEdusHhbm4SoPPrVDCwlBdREL3sQPA==" + "resolved" "https://registry.npmjs.org/recharts/-/recharts-2.1.13.tgz" + "version" "2.1.13" dependencies: "classnames" "^2.2.5" - "d3-interpolate" "^2.0.0" - "d3-scale" "^3.0.0" - "d3-shape" "^2.0.0" + "d3-interpolate" "^3.0.1" + "d3-scale" "^4.0.2" + "d3-shape" "^3.1.0" "eventemitter3" "^4.0.1" "lodash" "^4.17.19" "react-is" "^16.10.2" diff --git a/magefile.go b/magefile.go index 06de53f94b..774d89f606 100644 --- a/magefile.go +++ b/magefile.go @@ -381,6 +381,16 @@ func Clean() error { return nil } +// Only build the assets without building the actual code. +func Assets() error { + err := build_gui_files() + if err != nil { + return err + } + + return ensure_assets() +} + func build_gui_files() error { cwd, err := os.Getwd() if err != nil { diff --git a/responder/responder.go b/responder/responder.go index 3cd1e8728f..642e5a827a 100644 --- a/responder/responder.go +++ b/responder/responder.go @@ -84,6 +84,15 @@ func NewResponder( logger: logging.GetLogger(config_obj, &logging.ClientComponent), start_time: time.Now().UnixNano(), } + + if request.VQLClientAction != nil { + for _, q := range request.VQLClientAction.Query { + if q.Name != "" { + result.Artifact = q.Name + } + } + } + return result } @@ -123,6 +132,7 @@ func (self *Responder) getStatus() *crypto_proto.VeloStatus { LogRows: self.log_rows, ResultRows: self.result_rows, Duration: time.Now().UnixNano() - self.start_time, + Artifact: self.Artifact, } if self.request.VQLClientAction != nil { @@ -164,6 +174,8 @@ func (self *Responder) RaiseError(ctx context.Context, message string) { status.Backtrace = string(debug.Stack()) status.ErrorMessage = message status.Status = crypto_proto.VeloStatus_GENERIC_ERROR + status.NamesWithResponse = self.names_with_response + status.Artifact = self.Artifact self.AddResponse(ctx, &crypto_proto.VeloMessage{Status: status}) } diff --git a/server/comms.go b/server/comms.go index ffd5fceaf8..cf988c58b0 100644 --- a/server/comms.go +++ b/server/comms.go @@ -21,17 +21,19 @@ import ( "bytes" "context" "errors" + "html" "io" "io/ioutil" "math/rand" "net/http" - "strings" + "net/url" "sync/atomic" "time" - file_store_accessor "www.velocidex.com/golang/velociraptor/accessors/file_store" "www.velocidex.com/golang/velociraptor/crypto" "www.velocidex.com/golang/velociraptor/file_store" + "www.velocidex.com/golang/velociraptor/file_store/api" + "www.velocidex.com/golang/velociraptor/paths" "www.velocidex.com/golang/velociraptor/services" "www.velocidex.com/golang/velociraptor/utils" @@ -136,10 +138,8 @@ func PrepareFrontendMux( // does not have to be a physical directory - it is served // from the filestore. router.Handle(base+"/public/", GetLoggingHandler(config_obj, "/public")( - http.StripPrefix(base, forceMime(http.FileServer( - file_store_accessor.NewFileSystem(config_obj, - file_store.GetFileStore(config_obj), - "/public/")))))) + http.StripPrefix(base, + downloadPublic(config_obj, []string{"public"})))) return nil } @@ -672,20 +672,44 @@ func GetLoggingHandler(config_obj *config_proto.Config, } } -// Force mime type to binary stream. -func forceMime(parent http.Handler) http.Handler { +func downloadPublic( + config_obj *config_proto.Config, prefix []string) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // Prevent directory listings. - if strings.HasSuffix(r.URL.Path, "/") { - http.NotFound(w, r) + path_spec := paths.FSPathSpecFromClientPath(r.URL.Path) + components := path_spec.Components() + + // make sure the prefix is correct + for i, p := range prefix { + if len(components) <= i || p != components[i] { + returnError(w, 404, "Not Found") + return + } + } + + file_store_factory := file_store.GetFileStore(config_obj) + fd, err := file_store_factory.ReadFile(path_spec) + if err != nil { + returnError(w, 404, err.Error()) return } + // From here on we already sent the headers and we can + // not really report an error to the client. + w.Header().Set("Content-Disposition", "attachment; filename="+ + url.PathEscape(path_spec.Base())+api.GetExtensionForFilestore(path_spec)) + w.Header().Set("Content-Type", "binary/octet-stream") - parent.ServeHTTP(w, r) + w.WriteHeader(200) + + utils.Copy(r.Context(), w, fd) }) } +func returnError(w http.ResponseWriter, code int, message string) { + w.WriteHeader(code) + _, _ = w.Write([]byte(html.EscapeString(message))) +} + // Calculate QPS func init() { utils.RegisterQPSCounter(receiveCounter, receiveQPS) diff --git a/server/server_test.go b/server/server_test.go index 6502eb28de..419df135d3 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -634,7 +634,8 @@ func (self *ServerTestSuite) TestCompletions() { SessionId: flow_id, RequestId: constants.ProcessVQLResponses, Status: &crypto_proto.VeloStatus{ - Status: crypto_proto.VeloStatus_OK, + Status: crypto_proto.VeloStatus_OK, + QueryId: 0, }, }) runner.Close(context.Background()) @@ -658,7 +659,8 @@ func (self *ServerTestSuite) TestCompletions() { SessionId: flow_id, RequestId: constants.ProcessVQLResponses, Status: &crypto_proto.VeloStatus{ - Status: crypto_proto.VeloStatus_OK, + Status: crypto_proto.VeloStatus_OK, + QueryId: 1, }, }) runner.Close(context.Background()) diff --git a/services/frontend/frontend.go b/services/frontend/frontend.go index bfdec55398..42db4fb316 100644 --- a/services/frontend/frontend.go +++ b/services/frontend/frontend.go @@ -383,7 +383,7 @@ func NewFrontendService(ctx context.Context, wg *sync.WaitGroup, return nil, err } - root_org_config, err := org_manager.GetOrgConfig("root") + root_org_config, err := org_manager.GetOrgConfig(services.ROOT_ORG_ID) if err != nil { return nil, err } diff --git a/services/inventory/inventory.go b/services/inventory/inventory.go index 493d2887b9..4172992a01 100644 --- a/services/inventory/inventory.go +++ b/services/inventory/inventory.go @@ -139,7 +139,7 @@ func (self *InventoryService) GetToolInfo( // calls to this function will just retrieve those fields directly. func (self *InventoryService) materializeTool( ctx context.Context, - config_obj *config_proto.Config, + org_config_obj *config_proto.Config, tool *artifacts_proto.Tool) error { if self.Client == nil { @@ -150,7 +150,7 @@ func (self *InventoryService) materializeTool( // verify the binary URL now. if tool.GithubProject != "" { var err error - tool.Url, err = getGithubRelease(ctx, self.Client, config_obj, tool) + tool.Url, err = getGithubRelease(ctx, self.Client, org_config_obj, tool) if err != nil { return errors.Wrap( err, "While resolving github release "+tool.GithubProject) @@ -178,7 +178,7 @@ func (self *InventoryService) materializeTool( // name. We need to write the tool on the root org's public // directory. org_manager, err := services.GetOrgManager() - root_org_config, err := org_manager.GetOrgConfig("root") + root_org_config, err := org_manager.GetOrgConfig(services.ROOT_ORG_ID) if err != nil { return err } @@ -188,7 +188,13 @@ func (self *InventoryService) materializeTool( return errors.New("No filestore configured") } - path_manager := paths.NewInventoryPathManager(config_obj, tool) + // All tools are written to the root org's public directory since + // this is the only one mapped for external access. File names + // should never clash because the names are derived from a hash + // mixed with org id and filename so should be unique to each + // org. Therefore we use the root orgs file store but get a path + // manager specific to each org. + path_manager := paths.NewInventoryPathManager(org_config_obj, tool) fd, err := file_store_factory.WriteFile(path_manager.Path()) if err != nil { return err @@ -200,7 +206,7 @@ func (self *InventoryService) materializeTool( return err } - logger := logging.GetLogger(config_obj, &logging.FrontendComponent) + logger := logging.GetLogger(org_config_obj, &logging.FrontendComponent) logger.Info("Downloading tool %v FROM %v", tool.Name, tool.Url) request, err := http.NewRequestWithContext(ctx, "GET", tool.Url, nil) @@ -226,20 +232,20 @@ func (self *InventoryService) materializeTool( } if tool.ServeLocally { - if config_obj.Client == nil || len(config_obj.Client.ServerUrls) == 0 { + if org_config_obj.Client == nil || len(org_config_obj.Client.ServerUrls) == 0 { return errors.New("No server URLs configured!") } - tool.ServeUrl = config_obj.Client.ServerUrls[0] + "public/" + tool.FilestorePath + tool.ServeUrl = org_config_obj.Client.ServerUrls[0] + "public/" + tool.FilestorePath } else { tool.ServeUrl = tool.Url } - db, err := datastore.GetDB(config_obj) + db, err := datastore.GetDB(org_config_obj) if err != nil { return err } - return db.SetSubject(config_obj, paths.ThirdPartyInventory, self.binaries) + return db.SetSubject(org_config_obj, paths.ThirdPartyInventory, self.binaries) } func (self *InventoryService) RemoveTool( diff --git a/services/launcher/flows.go b/services/launcher/flows.go index bbd9737065..278ad2f5e0 100644 --- a/services/launcher/flows.go +++ b/services/launcher/flows.go @@ -118,6 +118,8 @@ func (self *Launcher) GetFlows( return result, nil } +// Gets more detailed information about the flow context - fills in +// availableDownloads etc. func (self *Launcher) GetFlowDetails( config_obj *config_proto.Config, client_id string, flow_id string) (*api_proto.FlowDetails, error) { @@ -125,20 +127,18 @@ func (self *Launcher) GetFlowDetails( return &api_proto.FlowDetails{}, nil } - db, err := datastore.GetDB(config_obj) + collection_context, err := LoadCollectionContext(config_obj, client_id, flow_id) if err != nil { return nil, err } - flow_path_manager := paths.NewFlowPathManager(client_id, flow_id) - collection_context := &flows_proto.ArtifactCollectorContext{} - err = db.GetSubject(config_obj, - flow_path_manager.Path(), collection_context) + ping := &flows_proto.PingContext{} + db, err := datastore.GetDB(config_obj) if err != nil { return nil, err } - ping := &flows_proto.PingContext{} + flow_path_manager := paths.NewFlowPathManager(client_id, flow_id) err = db.GetSubject(config_obj, flow_path_manager.Ping(), ping) if err == nil && ping.ActiveTime > collection_context.ActiveTime { collection_context.ActiveTime = ping.ActiveTime @@ -226,6 +226,7 @@ func LoadCollectionContext( if collection_context.SessionId == "" { return nil, errors.New("Unknown flow " + client_id + " " + flow_id) } + return collection_context, nil } @@ -333,12 +334,5 @@ func (self *Launcher) GetFlowRequests( } result.Items = flow_details.Items[offset:end] - - // Remove unimportant fields - for _, item := range result.Items { - item.SessionId = "" - item.RequestId = 0 - } - return result, nil } diff --git a/services/launcher/launcher.go b/services/launcher/launcher.go index 0eb2618e0b..04e68f0fbf 100644 --- a/services/launcher/launcher.go +++ b/services/launcher/launcher.go @@ -582,6 +582,7 @@ func (self *Launcher) ScheduleArtifactCollectionFromCollectorArgs( State: flows_proto.ArtifactCollectorContext_RUNNING, Request: collector_request, ClientId: client_id, + TotalRequests: int64(len(tasks)), OutstandingRequests: int64(len(tasks)), } diff --git a/services/notebook/notebook.go b/services/notebook/notebook.go index aca14c26ed..0117ac9e25 100644 --- a/services/notebook/notebook.go +++ b/services/notebook/notebook.go @@ -4,6 +4,7 @@ import ( "context" "encoding/base64" "errors" + "net/url" "os" "strings" "sync" @@ -12,6 +13,7 @@ import ( api_proto "www.velocidex.com/golang/velociraptor/api/proto" config_proto "www.velocidex.com/golang/velociraptor/config/proto" "www.velocidex.com/golang/velociraptor/services" + "www.velocidex.com/golang/velociraptor/utils" ) type NotebookManager struct { @@ -149,7 +151,8 @@ func (self *NotebookManager) UploadNotebookAttachment(ctx context.Context, } result := &api_proto.NotebookFileUploadResponse{ - Url: full_path.AsClientPath(), + Url: full_path.AsClientPath() + "?org_id=" + + url.QueryEscape(utils.NormalizedOrgId(self.config_obj.OrgId)), } return result, nil } diff --git a/services/orgs.go b/services/orgs.go index 078998dd74..e67ee224a3 100644 --- a/services/orgs.go +++ b/services/orgs.go @@ -9,6 +9,10 @@ import ( config_proto "www.velocidex.com/golang/velociraptor/config/proto" ) +const ( + ROOT_ORG_ID = "root" +) + var ( mu sync.Mutex org_manager OrgManager @@ -61,6 +65,7 @@ type OrgManager interface { CreateNewOrg(name, id string) (*api_proto.OrgRecord, error) ListOrgs() []*api_proto.OrgRecord GetOrg(org_id string) (*api_proto.OrgRecord, error) + DeleteOrg(org_id string) error // The manager is responsible for running multiple services - one // for each org. This ensures org services are separated out and diff --git a/services/orgs/delete.go b/services/orgs/delete.go new file mode 100644 index 0000000000..b453d3010e --- /dev/null +++ b/services/orgs/delete.go @@ -0,0 +1,102 @@ +package orgs + +import ( + "errors" + "fmt" + "os" + + api_proto "www.velocidex.com/golang/velociraptor/api/proto" + "www.velocidex.com/golang/velociraptor/datastore" + "www.velocidex.com/golang/velociraptor/file_store" + "www.velocidex.com/golang/velociraptor/file_store/api" + "www.velocidex.com/golang/velociraptor/paths" + "www.velocidex.com/golang/velociraptor/services" + "www.velocidex.com/golang/velociraptor/utils" +) + +func RemoveOrgFromUsers(org_id string) error { + // Remove the org from all the users. + user_manager := services.GetUserManager() + users, err := user_manager.ListUsers() + if err != nil { + return err + } + + for _, u := range users { + record, err := user_manager.GetUserWithHashes(u.Name) + if err == nil { + new_orgs := []*api_proto.Org{} + for _, org := range record.Orgs { + if org.Id != org_id { + new_orgs = append(new_orgs, org) + } + } + if len(new_orgs) != len(record.Orgs) { + record.Orgs = new_orgs + _ = user_manager.SetUser(record) + } + } + } + + return nil +} + +func (self *OrgManager) DeleteOrg(org_id string) error { + if utils.IsRootOrg(org_id) { + return errors.New("Can not remove root org.") + } + + err := RemoveOrgFromUsers(org_id) + if err != nil { + return err + } + + org_path_manager := paths.NewOrgPathManager(org_id) + db, err := datastore.GetDB(self.config_obj) + if err != nil { + return err + } + + err = db.DeleteSubject(self.config_obj, org_path_manager.Path()) + if err != nil { + return err + } + + // Remove the org from the manager and cancel all its services. + self.mu.Lock() + org_context, pres := self.orgs[org_id] + self.mu.Unlock() + + if !pres { + return fmt.Errorf("Org %v does not exist.", org_id) + } + + // Shut down the org's services + org_context.sm.Close() + + self.mu.Lock() + delete(self.orgs, org_id) + delete(self.org_id_by_nonce, org_id) + self.mu.Unlock() + + // Wait a bit for the services to shut down so we can remove files + // safely. + go func() { + datastore.Walk(self.config_obj, db, org_path_manager.Path(), + datastore.WalkWithoutDirectories, + func(path api.DSPathSpec) error { + _ = db.DeleteSubject(self.config_obj, path) + return nil + }) + + file_store_factory := file_store.GetFileStore(self.config_obj) + api.Walk(file_store_factory, + org_path_manager.Path().AsFilestorePath(), + func(path api.FSPathSpec, info os.FileInfo) error { + file_store_factory.Delete(path) + return nil + }) + }() + + return nil +} diff --git a/services/orgs/orgs.go b/services/orgs/orgs.go index cca97f8ba3..9f8dcd3219 100644 --- a/services/orgs/orgs.go +++ b/services/orgs/orgs.go @@ -15,19 +15,31 @@ import ( "www.velocidex.com/golang/velociraptor/logging" "www.velocidex.com/golang/velociraptor/paths" "www.velocidex.com/golang/velociraptor/services" + "www.velocidex.com/golang/velociraptor/utils" ) type OrgContext struct { record *api_proto.OrgRecord config_obj *config_proto.Config service services.ServiceContainer + + // Manages the lifetime of the org's services. + sm *services.Service } type OrgManager struct { mu sync.Mutex + // Sync the scan + scan_mu sync.Mutex + + // The root org's ctx and wg ctx context.Context - wg *sync.WaitGroup + + // We keep track of each org's services using its own wg and + // control overall lifetime using our parent's wg. This allows us + // to cancel each org's sevices independently. + parent_wg *sync.WaitGroup // The base global config object config_obj *config_proto.Config @@ -43,7 +55,12 @@ func (self *OrgManager) ListOrgs() []*api_proto.OrgRecord { defer self.mu.Unlock() for _, item := range self.orgs { - result = append(result, proto.Clone(item.record).(*api_proto.OrgRecord)) + copy := proto.Clone(item.record).(*api_proto.OrgRecord) + if utils.IsRootOrg(copy.OrgId) { + copy.OrgId = "root" + copy.Name = "" + } + result = append(result, copy) } // Sort orgs by names @@ -58,12 +75,8 @@ func (self *OrgManager) GetOrgConfig(org_id string) (*config_proto.Config, error self.mu.Lock() defer self.mu.Unlock() - if org_id == "root" { - org_id = "" - } - // An empty org id corresponds to the root org. - if org_id == "" { + if utils.IsRootOrg(org_id) { return self.config_obj, nil } @@ -123,25 +136,27 @@ func (self *OrgManager) CreateNewOrg(name, id string) ( self.mu.Lock() _, pres := self.orgs[id] self.mu.Unlock() + if pres { return nil, errors.New("Org ID already exists") } - err := self.startOrg(org_record) + org_path_manager := paths.NewOrgPathManager( + org_record.OrgId) + db, err := datastore.GetDB(self.config_obj) if err != nil { return nil, err } - org_path_manager := paths.NewOrgPathManager( - org_record.OrgId) - db, err := datastore.GetDB(self.config_obj) + // Must appear immediately to ensure the org appears before we can + // scan for it. + err = db.SetSubjectWithCompletion(self.config_obj, + org_path_manager.Path(), org_record, utils.SyncCompleter) if err != nil { return nil, err } - err = db.SetSubject(self.config_obj, - org_path_manager.Path(), org_record) - return org_record, err + return org_record, self.startOrg(org_record) } func (self *OrgManager) makeNewConfigObj( @@ -173,19 +188,24 @@ func (self *OrgManager) makeNewConfigObj( } func (self *OrgManager) Scan() error { + existing := make(map[string]bool) + for _, o := range self.ListOrgs() { + existing[o.OrgId] = true + } + db, err := datastore.GetDB(self.config_obj) if err != nil { - return nil + return err } - children, err := db.ListChildren( - self.config_obj, paths.ORGS_ROOT) + children, err := db.ListChildren(self.config_obj, paths.ORGS_ROOT) if err != nil { return err } for _, org_path := range children { org_id := org_path.Base() + org_path_manager := paths.NewOrgPathManager(org_id) org_record := &api_proto.OrgRecord{} err := db.GetSubject(self.config_obj, @@ -194,6 +214,8 @@ func (self *OrgManager) Scan() error { continue } + delete(existing, org_id) + _, err = self.GetOrgConfig(org_id) if err != nil { err = self.startOrg(org_record) @@ -203,6 +225,29 @@ func (self *OrgManager) Scan() error { } } + // Now shut down the orgs that were removed + for org_id := range existing { + // Do not remove the root org + if utils.IsRootOrg(org_id) { + continue + } + + self.mu.Lock() + org_context, pres := self.orgs[org_id] + self.mu.Unlock() + if pres { + org_context.sm.Close() + + logger := logging.GetLogger(self.config_obj, &logging.FrontendComponent) + logger.Info("Removing org %v", org_id) + + self.mu.Lock() + delete(self.orgs, org_id) + delete(self.org_id_by_nonce, org_id) + self.mu.Unlock() + } + } + return nil } @@ -268,7 +313,7 @@ func NewOrgManager( service := &OrgManager{ config_obj: config_obj, ctx: ctx, - wg: wg, + parent_wg: wg, orgs: make(map[string]*OrgContext), org_id_by_nonce: make(map[string]string), diff --git a/services/orgs/services.go b/services/orgs/services.go index 1bc60f6f8d..b4774b334b 100644 --- a/services/orgs/services.go +++ b/services/orgs/services.go @@ -1,12 +1,14 @@ package orgs import ( + "context" "errors" "sync" api_proto "www.velocidex.com/golang/velociraptor/api/proto" config_proto "www.velocidex.com/golang/velociraptor/config/proto" "www.velocidex.com/golang/velociraptor/datastore" + "www.velocidex.com/golang/velociraptor/file_store" "www.velocidex.com/golang/velociraptor/logging" "www.velocidex.com/golang/velociraptor/services" "www.velocidex.com/golang/velociraptor/services/broadcast" @@ -30,6 +32,7 @@ import ( "www.velocidex.com/golang/velociraptor/services/server_monitoring" "www.velocidex.com/golang/velociraptor/services/users" "www.velocidex.com/golang/velociraptor/services/vfs_service" + "www.velocidex.com/golang/velociraptor/utils" ) type ServiceContainer struct { @@ -125,7 +128,6 @@ func (self *ServiceContainer) Launcher() (services.Launcher, error) { } func (self *ServiceContainer) HuntDispatcher() (services.IHuntDispatcher, error) { - self.mu.Lock() defer self.mu.Unlock() @@ -137,7 +139,6 @@ func (self *ServiceContainer) HuntDispatcher() (services.IHuntDispatcher, error) } func (self *ServiceContainer) Indexer() (services.Indexer, error) { - self.mu.Lock() defer self.mu.Unlock() @@ -149,7 +150,6 @@ func (self *ServiceContainer) Indexer() (services.Indexer, error) { } func (self *ServiceContainer) RepositoryManager() (services.RepositoryManager, error) { - self.mu.Lock() defer self.mu.Unlock() @@ -161,7 +161,6 @@ func (self *ServiceContainer) RepositoryManager() (services.RepositoryManager, e } func (self *ServiceContainer) VFSService() (services.VFSService, error) { - self.mu.Lock() defer self.mu.Unlock() @@ -173,7 +172,6 @@ func (self *ServiceContainer) VFSService() (services.VFSService, error) { } func (self *ServiceContainer) Labeler() (services.Labeler, error) { - self.mu.Lock() defer self.mu.Unlock() @@ -236,8 +234,19 @@ func (self *OrgManager) startOrg(org_record *api_proto.OrgRecord) (err error) { record: org_record, config_obj: org_config, service: &ServiceContainer{}, + sm: services.NewServiceManager(self.ctx, org_config), } + // Make our parent waits for all the services to properly + // exit. Each org service can be stopped independently but we can + // not exit the org manager until they all shut down properly. + self.parent_wg.Add(1) + go func() { + <-org_ctx.sm.Ctx.Done() + org_ctx.sm.Wg.Wait() + self.parent_wg.Done() + }() + self.mu.Lock() self.orgs[org_record.OrgId] = org_ctx self.org_id_by_nonce[org_record.Nonce] = org_record.OrgId @@ -247,13 +256,20 @@ func (self *OrgManager) startOrg(org_record *api_proto.OrgRecord) (err error) { } func (self *OrgManager) startRootOrgServices( + ctx context.Context, + wg *sync.WaitGroup, spec *config_proto.ServerServicesConfig, org_config *config_proto.Config, service_container *ServiceContainer) (err error) { + // The MemcacheFileDataStore service + err = datastore.StartMemcacheFileService(ctx, wg, org_config) + if err != nil { + return err + } + if spec.ReplicationService { - j, err := journal.NewReplicationService( - self.ctx, self.wg, org_config) + j, err := journal.NewReplicationService(ctx, wg, org_config) if err != nil { return err } @@ -265,21 +281,20 @@ func (self *OrgManager) startRootOrgServices( // The user manager is global across all orgs. if spec.UserManager { - err := users.StartUserManager( - self.ctx, self.wg, org_config) + err := users.StartUserManager(ctx, wg, org_config) if err != nil { return err } } err = ddclient.StartDynDNSService( - self.ctx, self.wg, org_config) + ctx, wg, org_config) if err != nil { return err } err = datastore.StartRemoteDatastore( - self.ctx, self.wg, org_config) + ctx, wg, org_config) if err != nil { return err } @@ -290,6 +305,8 @@ func (self *OrgManager) startRootOrgServices( func (self *OrgManager) startOrgFromContext(org_ctx *OrgContext) (err error) { org_id := org_ctx.record.OrgId org_config := org_ctx.config_obj + ctx := org_ctx.sm.Ctx + wg := org_ctx.sm.Wg service_container := org_ctx.service.(*ServiceContainer) // If there is no frontend defined we are running as a client. @@ -300,25 +317,18 @@ func (self *OrgManager) startOrgFromContext(org_ctx *OrgContext) (err error) { } if spec.FrontendServer { - f, err := frontend.NewFrontendService( - self.ctx, self.wg, org_config) + f, err := frontend.NewFrontendService(ctx, wg, org_config) if err != nil { return err } service_container.mu.Lock() service_container.frontend = f service_container.mu.Unlock() - - err = datastore.StartMemcacheFileService( - self.ctx, self.wg, org_config) - if err != nil { - return err - } } // Now start service on the root org - if org_id == "" { - err := self.startRootOrgServices(spec, org_config, service_container) + if utils.IsRootOrg(org_id) { + err := self.startRootOrgServices(ctx, wg, spec, org_config, service_container) if err != nil { return err } @@ -328,8 +338,7 @@ func (self *OrgManager) startOrgFromContext(org_ctx *OrgContext) (err error) { // services so they need to be accessible as soon as they are // ready. if spec.JournalService { - j, err := journal.NewJournalService( - self.ctx, self.wg, org_config) + j, err := journal.NewJournalService(ctx, wg, org_config) if err != nil { return err } @@ -340,8 +349,7 @@ func (self *OrgManager) startOrgFromContext(org_ctx *OrgContext) (err error) { } if spec.NotificationService { - n, err := notifications.NewNotificationService( - self.ctx, self.wg, org_config) + n, err := notifications.NewNotificationService(ctx, wg, org_config) if err != nil { return err } @@ -352,7 +360,7 @@ func (self *OrgManager) startOrgFromContext(org_ctx *OrgContext) (err error) { if spec.TestRepositoryManager { repo_manager, err := repository.NewRepositoryManager( - self.ctx, self.wg, org_config) + ctx, wg, org_config) if err != nil { return err } @@ -367,9 +375,21 @@ func (self *OrgManager) startOrgFromContext(org_ctx *OrgContext) (err error) { service_container.mu.Unlock() } + if spec.Launcher { + launch, err := launcher.NewLauncherService( + ctx, wg, org_config) + if err != nil { + return err + } + + service_container.mu.Lock() + service_container.launcher = launch + service_container.mu.Unlock() + } + if spec.RepositoryManager { repo_manager, err := repository.NewRepositoryManager( - self.ctx, self.wg, org_config) + ctx, wg, org_config) if err != nil { return err } @@ -383,7 +403,7 @@ func (self *OrgManager) startOrgFromContext(org_ctx *OrgContext) (err error) { if org_id == "" { // Assume the built in artifacts are OK so we dont need to // validate them at runtime. - err = repository.LoadBuiltInArtifacts(self.ctx, org_config, + err = repository.LoadBuiltInArtifacts(ctx, org_config, repo_manager.(*repository.RepositoryManager), false /* validate */) if err != nil { return err @@ -405,7 +425,7 @@ func (self *OrgManager) startOrgFromContext(org_ctx *OrgContext) (err error) { return err } - _, err = repository.InitializeGlobalRepositoryFromFilestore(self.ctx, org_config, global_repository) + _, err = repository.InitializeGlobalRepositoryFromFilestore(ctx, org_config, global_repository) if err != nil { return err } @@ -418,7 +438,7 @@ func (self *OrgManager) startOrgFromContext(org_ctx *OrgContext) (err error) { if spec.InventoryService { i, err := inventory.NewInventoryService( - self.ctx, self.wg, org_config) + ctx, wg, org_config) if err != nil { return err } @@ -430,7 +450,7 @@ func (self *OrgManager) startOrgFromContext(org_ctx *OrgContext) (err error) { if spec.HuntDispatcher { hd, err := hunt_dispatcher.NewHuntDispatcher( - self.ctx, self.wg, org_config) + ctx, wg, org_config) if err != nil { return err } @@ -442,7 +462,7 @@ func (self *OrgManager) startOrgFromContext(org_ctx *OrgContext) (err error) { if spec.HuntManager { err = hunt_manager.NewHuntManager( - self.ctx, self.wg, org_config) + ctx, wg, org_config) if err != nil { return err } @@ -450,7 +470,7 @@ func (self *OrgManager) startOrgFromContext(org_ctx *OrgContext) (err error) { if spec.Interrogation { err = interrogation.NewInterrogationService( - self.ctx, self.wg, org_config) + ctx, wg, org_config) if err != nil { return err @@ -459,7 +479,7 @@ func (self *OrgManager) startOrgFromContext(org_ctx *OrgContext) (err error) { if spec.ClientInfo { c := client_info.NewClientInfoManager(org_config) - err = c.Start(self.ctx, org_config, self.wg) + err = c.Start(ctx, org_config, wg) if err != nil { return err } @@ -470,7 +490,7 @@ func (self *OrgManager) startOrgFromContext(org_ctx *OrgContext) (err error) { } if spec.IndexServer { - inv, err := indexing.NewIndexingService(self.ctx, self.wg, org_config) + inv, err := indexing.NewIndexingService(ctx, wg, org_config) if err != nil { return err } @@ -482,7 +502,7 @@ func (self *OrgManager) startOrgFromContext(org_ctx *OrgContext) (err error) { if spec.VfsService { vfs, err := vfs_service.NewVFSService( - self.ctx, self.wg, org_config) + ctx, wg, org_config) if err != nil { return err } @@ -494,7 +514,7 @@ func (self *OrgManager) startOrgFromContext(org_ctx *OrgContext) (err error) { if spec.Label { l, err := labels.NewLabelerService( - self.ctx, self.wg, org_config) + ctx, wg, org_config) if err != nil { return err } @@ -504,20 +524,8 @@ func (self *OrgManager) startOrgFromContext(org_ctx *OrgContext) (err error) { service_container.mu.Unlock() } - if spec.Launcher { - launch, err := launcher.NewLauncherService( - self.ctx, self.wg, org_config) - if err != nil { - return err - } - - service_container.mu.Lock() - service_container.launcher = launch - service_container.mu.Unlock() - } - if spec.NotebookService { - nb, err := notebook.NewNotebookManagerService(self.ctx, self.wg, org_config) + nb, err := notebook.NewNotebookManagerService(ctx, wg, org_config) if err != nil { return err } @@ -527,22 +535,15 @@ func (self *OrgManager) startOrgFromContext(org_ctx *OrgContext) (err error) { service_container.mu.Unlock() } - if spec.SanityChecker { - err = sanity.NewSanityCheckService(self.ctx, self.wg, org_config) - if err != nil { - return err - } - } - if spec.ServerArtifacts { - err = server_artifacts.NewServerArtifactService(self.ctx, self.wg, org_config) + err = server_artifacts.NewServerArtifactService(ctx, wg, org_config) if err != nil { return err } } if spec.ClientMonitoring { - client_event_manager, err := client_monitoring.NewClientMonitoringService(self.ctx, self.wg, org_config) + client_event_manager, err := client_monitoring.NewClientMonitoringService(ctx, wg, org_config) if err != nil { return err } @@ -553,7 +554,7 @@ func (self *OrgManager) startOrgFromContext(org_ctx *OrgContext) (err error) { } if spec.MonitoringService { - server_event_manager, err := server_monitoring.NewServerMonitoringService(self.ctx, self.wg, org_config) + server_event_manager, err := server_monitoring.NewServerMonitoringService(ctx, wg, org_config) if err != nil { return err } @@ -562,7 +563,60 @@ func (self *OrgManager) startOrgFromContext(org_ctx *OrgContext) (err error) { service_container.server_event_manager = server_event_manager service_container.mu.Unlock() } - return err + + // Must be run after all the other services are up + if spec.SanityChecker { + err = sanity.NewSanityCheckService(ctx, wg, org_config) + if err != nil { + return err + } + } + + return maybeFlushFilesOnClose(ctx, wg, org_config) +} + +// Flush the datastore if possible when the org is closed to ensure +// all its data is flushed to disk. Some data stores delay writes so +// we need to make sure all the datastore files hit the disk before we +// close the org - for example if we delete the org subsequently we +// need to ensure no file writes are still in flight while we delete. +func maybeFlushFilesOnClose( + ctx context.Context, + wg *sync.WaitGroup, + org_config *config_proto.Config) error { + if org_config.Datastore == nil { + return nil + } + + // Flush the filestore if needed. Not all filestores need + // flushing. + file_store_factory := file_store.GetFileStore(org_config) + flusher, ok := file_store_factory.(Flusher) + if ok { + wg.Add(1) + go func() { + defer wg.Done() + <-ctx.Done() + flusher.Flush() + }() + } + + db, err := datastore.GetDB(org_config) + if err != nil { + return err + } + + flusher, ok = db.(Flusher) + if ok { + wg.Add(1) + go func() { + defer wg.Done() + <-ctx.Done() + flusher.Flush() + }() + } + + return nil } func (self *OrgManager) Services(org_id string) services.ServiceContainer { @@ -575,3 +629,7 @@ func (self *OrgManager) Services(org_id string) services.ServiceContainer { } return service_container.service } + +type Flusher interface { + Flush() +} diff --git a/services/orgs/tests.go b/services/orgs/tests.go index e76207012f..2987ef3ade 100644 --- a/services/orgs/tests.go +++ b/services/orgs/tests.go @@ -32,6 +32,7 @@ func (self *TestOrgManager) Start( record: &api_proto.OrgRecord{}, config_obj: org_config, service: service_container, + sm: services.NewServiceManager(ctx, org_config), } self.orgs[""] = org_context self.mu.Unlock() @@ -50,7 +51,7 @@ func StartTestOrgManager( OrgManager: &OrgManager{ config_obj: config_obj, ctx: ctx, - wg: wg, + parent_wg: wg, orgs: make(map[string]*OrgContext), org_id_by_nonce: make(map[string]string), diff --git a/services/sanity/sanity.go b/services/sanity/sanity.go index 0e12230645..635e575911 100644 --- a/services/sanity/sanity.go +++ b/services/sanity/sanity.go @@ -27,7 +27,8 @@ import ( // conditions. type SanityChecks struct{} -func (self *SanityChecks) Check( +// Check sanity of general server state - this is only done for the root org. +func (self *SanityChecks) CheckRootOrg( ctx context.Context, config_obj *config_proto.Config) error { if config_obj.Logging != nil && config_obj.Logging.OutputDirectory != "" { @@ -89,6 +90,23 @@ func (self *SanityChecks) Check( } } + err := maybeStartInitialArtifacts(ctx, config_obj) + if err != nil { + return err + } + + return checkForServerUpgrade(ctx, config_obj) +} + +func (self *SanityChecks) Check( + ctx context.Context, config_obj *config_proto.Config) error { + if utils.IsRootOrg(config_obj.OrgId) { + err := self.CheckRootOrg(ctx, config_obj) + if err != nil { + return err + } + } + // Reindex all the notebooks. notebooks, err := notebook.GetAllNotebooks(config_obj) if err != nil { @@ -119,12 +137,7 @@ func (self *SanityChecks) Check( return err } - err = maybeStartInitialArtifacts(ctx, config_obj) - if err != nil { - return err - } - - return checkForServerUpgrade(ctx, config_obj) + return nil } // Sets the server metadata to defaults. @@ -242,10 +255,8 @@ func checkForServerUpgrade( if !pres { seen[tool_definition.Name] = true - // If the existing tool - // definition was overridden - // by the admin do not alter - // it. + // If the existing tool definition was overridden + // by the admin do not alter it. tool, err := inventory.ProbeToolInfo(tool_definition.Name) if err == nil && tool.AdminOverride { logger.Info("Skipping update of tool %v because an admin manually overrode its definition.", @@ -261,9 +272,8 @@ func checkForServerUpgrade( tool_definition = proto.Clone( tool_definition).(*artifacts_proto.Tool) - // Re-add the tool to force - // hashes to be taken when the - // tool is used next. + // Re-add the tool to force hashes to be taken + // when the tool is used next. tool_definition.Hash = "" err = inventory.AddTool( diff --git a/services/sanity/server_artifacts.go b/services/sanity/server_artifacts.go index 5e2bcd79f9..20df3996a3 100644 --- a/services/sanity/server_artifacts.go +++ b/services/sanity/server_artifacts.go @@ -36,6 +36,7 @@ func maybeStartInitialArtifacts( if err != nil { return err } + // Start any initial artifact collections. if config_obj.Frontend != nil && len(config_obj.Frontend.InitialServerArtifacts) > 0 { diff --git a/services/server_artifacts/logger.go b/services/server_artifacts/logger.go index df0a3fab97..97431e557a 100644 --- a/services/server_artifacts/logger.go +++ b/services/server_artifacts/logger.go @@ -37,6 +37,12 @@ func (self *serverLogger) Write(b []byte) (int, error) { // Increment the log count. self.collection_context.Modify(func(context *flows_proto.ArtifactCollectorContext) { context.TotalLogs++ + + // If an error occured mark the collection failed. + if level == "ERROR" { + context.State = flows_proto.ArtifactCollectorContext_ERROR + context.Status = msg + } }) return len(b), nil diff --git a/services/spec.go b/services/spec.go index 85231e2494..1fc080be8a 100644 --- a/services/spec.go +++ b/services/spec.go @@ -15,6 +15,7 @@ func GenericToolServices() *config_proto.ServerServicesConfig { return &config_proto.ServerServicesConfig{ RepositoryManager: true, InventoryService: true, + Launcher: true, JournalService: true, UserManager: true, NotificationService: true, @@ -28,9 +29,8 @@ func ClientServicesSpec() *config_proto.ServerServicesConfig { InventoryService: true, NotificationService: true, Launcher: true, - - HttpCommunicator: true, - ClientEventTable: true, + HttpCommunicator: true, + ClientEventTable: true, } } diff --git a/services/users.go b/services/users.go index 998828ed5f..4908933068 100644 --- a/services/users.go +++ b/services/users.go @@ -47,6 +47,8 @@ type UserManager interface { // Favorites are stored per org. GetFavorites(config_obj *config_proto.Config, principal, fav_type string) (*api_proto.Favorites, error) + + DeleteUser(config_obj *config_proto.Config, username string) error } func RegisterUserManager(dispatcher UserManager) { diff --git a/services/users/delete.go b/services/users/delete.go new file mode 100644 index 0000000000..580a55113d --- /dev/null +++ b/services/users/delete.go @@ -0,0 +1,50 @@ +package users + +import ( + config_proto "www.velocidex.com/golang/velociraptor/config/proto" + datastore "www.velocidex.com/golang/velociraptor/datastore" + "www.velocidex.com/golang/velociraptor/paths" + "www.velocidex.com/golang/velociraptor/services" +) + +func (self *UserManager) DeleteUser( + org_config_obj *config_proto.Config, username string) error { + + org_manager, err := services.GetOrgManager() + if err != nil { + return err + } + + // Get the root org config because users are managed in the root + // org. + root_config_obj, err := org_manager.GetOrgConfig(services.ROOT_ORG_ID) + if err != nil { + return err + } + + db, err := datastore.GetDB(root_config_obj) + if err != nil { + return err + } + + user_path_manager := paths.NewUserPathManager(username) + err = db.DeleteSubject(root_config_obj, user_path_manager.Path()) + if err != nil { + return err + } + + // Also remove the ACLs for the user from all orgs. + for _, org_record := range org_manager.ListOrgs() { + org_config_obj, err := org_manager.GetOrgConfig(org_record.OrgId) + if err != nil { + continue + } + + err = db.DeleteSubject(org_config_obj, user_path_manager.ACL()) + if err != nil { + continue + } + } + + return nil +} diff --git a/services/users/grpc.go b/services/users/grpc.go index 4346a4c01e..19ac89826b 100644 --- a/services/users/grpc.go +++ b/services/users/grpc.go @@ -13,6 +13,7 @@ import ( crypto_utils "www.velocidex.com/golang/velociraptor/crypto/utils" "www.velocidex.com/golang/velociraptor/logging" "www.velocidex.com/golang/velociraptor/services" + "www.velocidex.com/golang/velociraptor/utils" ) func (self UserManager) GetUserFromContext(ctx context.Context) ( @@ -88,7 +89,7 @@ func GetGRPCUserInfo( org_id := md.Get("OrgId") if len(org_id) > 0 { result.CurrentOrg = org_id[0] - if result.CurrentOrg == "root" { + if utils.IsRootOrg(result.CurrentOrg) { result.CurrentOrg = "" } } diff --git a/services/users/links.go b/services/users/links.go new file mode 100644 index 0000000000..07a527a4a4 --- /dev/null +++ b/services/users/links.go @@ -0,0 +1,50 @@ +package users + +import config_proto "www.velocidex.com/golang/velociraptor/config/proto" + +var ( + DefaultLinks = []*config_proto.GUILink{ + { + Text: "Google", + Url: "https://www.google.com", + Type: "context", + Parameter: "q", + IconUrl: "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8ZyB0cmFuc2Zvcm09Im1hdHJpeCgxLCAwLCAwLCAxLCAyNy4wMDkwMDEsIC0zOS4yMzg5OTgpIj4KICAgIDxwYXRoIGZpbGw9IiM0Mjg1RjQiIGQ9Ik0gLTMuMjY0IDUxLjUwOSBDIC0zLjI2NCA1MC43MTkgLTMuMzM0IDQ5Ljk2OSAtMy40NTQgNDkuMjM5IEwgLTE0Ljc1NCA0OS4yMzkgTCAtMTQuNzU0IDUzLjc0OSBMIC04LjI4NCA1My43NDkgQyAtOC41NzQgNTUuMjI5IC05LjQyNCA1Ni40NzkgLTEwLjY4NCA1Ny4zMjkgTCAtMTAuNjg0IDYwLjMyOSBMIC02LjgyNCA2MC4zMjkgQyAtNC41NjQgNTguMjM5IC0zLjI2NCA1NS4xNTkgLTMuMjY0IDUxLjUwOSBaIi8+CiAgICA8cGF0aCBmaWxsPSIjMzRBODUzIiBkPSJNIC0xNC43NTQgNjMuMjM5IEMgLTExLjUxNCA2My4yMzkgLTguODA0IDYyLjE1OSAtNi44MjQgNjAuMzI5IEwgLTEwLjY4NCA1Ny4zMjkgQyAtMTEuNzY0IDU4LjA0OSAtMTMuMTM0IDU4LjQ4OSAtMTQuNzU0IDU4LjQ4OSBDIC0xNy44ODQgNTguNDg5IC0yMC41MzQgNTYuMzc5IC0yMS40ODQgNTMuNTI5IEwgLTI1LjQ2NCA1My41MjkgTCAtMjUuNDY0IDU2LjYxOSBDIC0yMy40OTQgNjAuNTM5IC0xOS40NDQgNjMuMjM5IC0xNC43NTQgNjMuMjM5IFoiLz4KICAgIDxwYXRoIGZpbGw9IiNGQkJDMDUiIGQ9Ik0gLTIxLjQ4NCA1My41MjkgQyAtMjEuNzM0IDUyLjgwOSAtMjEuODY0IDUyLjAzOSAtMjEuODY0IDUxLjIzOSBDIC0yMS44NjQgNTAuNDM5IC0yMS43MjQgNDkuNjY5IC0yMS40ODQgNDguOTQ5IEwgLTIxLjQ4NCA0NS44NTkgTCAtMjUuNDY0IDQ1Ljg1OSBDIC0yNi4yODQgNDcuNDc5IC0yNi43NTQgNDkuMjk5IC0yNi43NTQgNTEuMjM5IEMgLTI2Ljc1NCA1My4xNzkgLTI2LjI4NCA1NC45OTkgLTI1LjQ2NCA1Ni42MTkgTCAtMjEuNDg0IDUzLjUyOSBaIi8+CiAgICA8cGF0aCBmaWxsPSIjRUE0MzM1IiBkPSJNIC0xNC43NTQgNDMuOTg5IEMgLTEyLjk4NCA0My45ODkgLTExLjQwNCA0NC41OTkgLTEwLjE1NCA0NS43ODkgTCAtNi43MzQgNDIuMzY5IEMgLTguODA0IDQwLjQyOSAtMTEuNTE0IDM5LjIzOSAtMTQuNzU0IDM5LjIzOSBDIC0xOS40NDQgMzkuMjM5IC0yMy40OTQgNDEuOTM5IC0yNS40NjQgNDUuODU5IEwgLTIxLjQ4NCA0OC45NDkgQyAtMjAuNTM0IDQ2LjA5OSAtMTcuODg0IDQzLjk4OSAtMTQuNzU0IDQzLjk4OSBaIi8+CiAgPC9nPgo8L3N2Zz4=", + }, { + Text: "VirusTotal", + Url: "https://www.virustotal.com/gui/search/", + IconUrl: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwIiBoZWlnaHQ9Ijg5IiB2aWV3Qm94PSIwIDAgMTAwIDg5IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik00NS4yOTIgNDQuNUwwIDg5aDEwMFYwSDBsNDUuMjkyIDQ0LjV6TTkwIDgwSDIybDM1Ljk4Ny0zNS4yTDIyIDloNjh2NzF6IiBmaWxsPSIjNEI2M0ZCIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4K", + Type: "context", + }, { + Text: "CyberChef", + Url: "https://gchq.github.io/CyberChef/#", + Type: "context", + Encode: "base64", + Parameter: "input", + IconUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAXGUlEQVR4Ae1dBVRVWRceRVowaPiHkA67i7C7uyewu7t1RgU7x+5uBTspYeygyw6cFBRHOP93WPuu9aTeE99D7uOetb6J967B3d/Ze59d57titEoAJYFSgCagBWgTtABNggY9Ky01EboGCVYXKA2UA0wAc8CSYAGYAkaAIaAHaElkEL/gtQEDwBj4vlq1apXWrFkz4MiRIwsOHjy47cSJE0dPnjx5Cv+/f9euXSuXLl06vFmzZrXxrA1gRmTQIa1RIm+tkgMlvhFxpEUC0CLBmzs4OLjv2bNnyt27d8OePHmS/vz5c5acnPzv77//znJDRERE5uXLl6O2bt3q36hRo1r4PayAMkQmDRlyaZGmKE0wIJTOpkEKcUlLg1S9sZ2dnTN2+C+JiYlvudBlgc9SSeD54saNG2n79+/fXr9+/RqkEQxIIxjQ/9taWFi4Nm7cuGafPn28OWGaNm3Kn7Wj7/VJe0irEFR+Kdp9lrNnz+4SHR0dKwi8oAQQEBISkuLn5zdGEKyOjo7dpUuXQsPDwz/koUX+u3jxYgj5F7qSOfgqwQJ521gBmmSvrXfv3j1VUPV5ISEhIe1LCEDIPHDgwG49Pb3qgwcPHqDIr/nhhx8akfmQTEEBjmpatHv0c7Gx+vSdNqBDL9kmMDBwjSBkpROAcOzYsaAlS5ZsUuTZ5cuXT6AThyZQIjdHlUCklrx2LRJweTqmWQP2np6eVX/++Wdv7Cgva2trN/4ZfWdFatYB9n4pCVh1BCCEhoZ+UOQ5aKOt9HfUziZgDRlfwpAIrUVEKHZLOK4ZkuNUwd/fvw9s7OYHDx7chcf+d3YBJiUl/R0ZGRmFZ3bg2WHYkVOePXv2SaUEKABOnTp1jTuKdCooSdAUTiijRo1qimPo2oYNG7oR6bWLDwnIdtOON3V1dfXAy1gcFxf3hASlMhQWAa5cuZKEn80NKEfC1SVB223atGkhnMUsTXL16tXY1q1b1yNzQSQoHmf1soDtzp07x0MobwQBqQsBcEr4aG5u7kMmyxywqlGjRq2AgIAr2Z8FCRJatGjRgIJWak2CkmT/jCti4ax9UhCMuhGAjpB/IxC1q23btu3hx/S7du3as7yeBQnifXx8alNImvwG9RO+NmDSq1cvz5iYmDgSitoSQAYZXCPIew7xgwfu7u6VyWxoqpXNJ+Eb9ejRoyFs/VMSiMgIoHqcPXs2qEyZMnYyzqNaLE2gXNWqVStHRUVF5yEciQAEhKB/JR9JQ12OevqArWI2XyLAihUrRpAZoEyk+FW/6fr164fKF5BEAMQPrvJ4CB2RNdRh9xvyCJ58uy8RICgo6GX16tUb8A2jLicBLcAcNm0WCUAiQD5xgxEjRvzIi1fUxQEsSbbfHqHbaIkA+QMVSSvwrlyAsqK3/bRKAeUmTpzYQb5gJAL4+voOptyBvjrUI5YQ1D/StKslAsjHoUOHTvPMplCCJvZUcQlKftjcunUrVCKAfISFhb1HFNCHtIAJEaE0hc41iQyis/+O8fHxL4sSAZBOpnx+0QMyouEoSF3HS9AGDRrUysDAwAnv8H9AeSJCSTERwMDMzKwicvWZRYkAT58+LTpCl1+Y+h5p5XtIKM2kJJGmqM7/qJKtX3BhSQQQEBwc/JSqoERTZKoBlOnWrZuPRICvB8rQ/iUHUR8oKRoNYGNjU00igFIcxHcUIygtDgKQDwC4okz7vUSAr/YF0vi7pHdaUlSnAKR/k4onASQC6AK2SHAESARQig8gKgIIaWCLvXv3LpAI8NW1hX/iXToLPoCYcgHl0XLtiZf+USLAVxHgNdUI6IsqGESMtUeq86pEgAKliD+hkjgJRSIHqbScagTElRAyQ/fOICkXoFAzyQsMrziLkrAlKCPvY2RkVIuOf1aAgfiyhBQPAJxu3rwZIhEgX0//Q82aNTvhXXlQQsgCMKakkK5YawQEZ9B86NChnRAT+CgRIM9m0qN4T+6UCSxN701THdLCGvQD2e3bt2+xRIDc0bFjx/7k6BmIdbfL8wXKAS5IbJyTCJATyPgd4qZSZqhECXXsDDIpV65cJRxrLkgEyIFMDJWYSg6fLlBSXRtDTTkJECEMlAiQM+Tbr1+/luT8aalrg6guOTou6JOf+fjx43cSAQgABl88MDQ0zJb6VU9NUA6ogNEv7eEXXKLKIak1DEBZ2AyhNUzdJ4QY0Hm34o8//jgQI2FSn0sEYJhItorqAGnAlHrP99MlEtRA+1hKcSfAhQsX7vABlBRA0ygug6LKAu6oIH6jjgSAc/cfzNy/8p7DmNpE0fQGqqB6yEXdCIDY/vMNGzZsrF27dnug87lz5x7l9ez169dftmrVqgWNvhN1b6BEANr1pUqVakyTwqwBOwyNqolkz8lc5gM9adOmTSvqAVCH1jCJANjRr/AzVQFMZSaemgGuaPyYiULPVFL7cU2wSPil1SQMLBEAs37uUhWPAaBBEI6/Ni1btvTavn37L2gHq0JOsL4aCV8iwNGjRy9mr+LJNiCzPGBMDrCumql9iQAYLH2e2/0cDh1lSGWGYpdSQ4dPIsDx48fPZZsVnHMVsx0vEUBaEgGkJRFAWhIBpCURQFoSAaQlEUBaEgGkJfQQOqoTAXCT2Vlhro98AkgE0ANsIZzXqiYAupMyCoMAp0+fDqAkj7ZEAAWbSH/99Vdf1MPdQCEFUxVQcvVh9erVTJWYP3/+qWHDhnUURrtJIV/FZgmUAVzQGXsMAxOZqnD48OE03C/MVIm+ffuuFGb+S7v/y2YK2a1ateqw2AnQv3//pVTgoSPt/i8jgK1EgOK5NOgo6Lhy5cqjamACVnAyK97dIy0twHjt2rUDUUkTjno6pirgbr70devWMVVi0aJFARMmTOgsc/mDtBQYLf99YmJiYRwDMwvjGBiA9WVzfaRAkENh3CEMkr0vpNHvZzmp5Y95l4SvTeflSiBASiEQoLAigeekSKBi18eb0GSMJg8f3H8JAaXLQ1JS4ocvQXJS0vskQnRU1F8YUPFelcBkzzQ4m4E04bt07iZA2vXldXS+qzDGx2bqrx3dIvcMa5pxZnpndmxie3ZoXFt2cKzycGXvLnY7MDALN44fT0WwiQlYtmwZGzBgAPPy8lIaGjVqxDAgM6Nx48YJdevWnUIkkJbMbAATL7tyDVd2dL63sV8NFrGwN7u9uC8L/6U3C13QkwXP78mC5vVQCq7M682SQ0PY27t3s/A8IiIV83iYgF27djF47Az39ysNaPpg6PNjaPdiuDqe4eKMq7g9xRT4riihUP8wmTlBxp2qmLf+rZvbmw29qrCbi3qz+/792T2//uyuXz92d4lyEbR8PPv30SP2KSEhC+8iI1ORqmUEXr/PNm7cyAXFBaY8kPAFQBtcorhAMV10g7irpV61DV3dkkAAdm5KOy58leLR6UPsv/h4xpKTs5AWHZ2WPTiEK9u4GSBhqQ7169cfTXGBYhvqtfFv73xma08PtqlPNZULP2TlBPbXgwck/LwJwDUBJnSxdu3aqZQAMA/xlPoulrvfuH8Ny57benpkbu7hzvYM9lKp8CP8fFlS0FWu9uUSQNACuOVU5VqgYsWKLsB3RQGF84fA9hPrbZZ1cL62rZcH4wTY9mNdFji5LQuZ110lwo88c5Klx8WR4OUTAOd2hrsNGEbaqkQTwClMbd68OZ8AUrt4HQvpBrGqVgZ1t/by+MgJsBXYAB9gZScX5t/BmS3tWoUFTlKOPxC2dBiLOh/IPsTGktAVI4BAAn4yGDt2rNJIAMEzDIHeindQlTKEWjKxkJLkE2gSNNRV/ZuM97adxYUvQCDCFvgDa7u4slkt7NmRqX0gxAEFEvwdvx9YyMZf2NOwMGHnfzEBBBJgpjEbs3wMa9mrZcEETycKfiTs1asXw/yHXykqqC8jcG2KD5SjNvHywvfqFvHTAawWtnE8SILPQYKN3d2ZX3tndmD+WBaxbyML8x+qsOCvzevJpvbwYc29G7DfAwIEm18wAhAGhg1k1lHW7H+h/2MuK1yYV18vhQXPNUePHj1Yz549Wffu3RnG33ESBNEkcDPKEBrRLCAHT0/PXnh2F2oIzsmOiFG3gk87qPub+RFgKUxB4NLpLDUqigdr2P1Th1notmUsaPU0FrRiHAteNpoF+w1je8d3Zit8W7DJ3X1YW8+arF7duuz8+fP8bj3WFy89V9VPyEhMZH/ev8/DtPz8z3d7DuHPuTaH2STaAEC8DbN7ZMeOJRxjZ6+eZS0XQiMMaMtwISbr1KlTFrp27coFnXWMHD16NMPlGGznzp1s+PDhrE+fPuynn35iAwcOZB06dNimp6dXg88Mqly5cpsuXbpsBjle8O8IXGtMpwyimhSSkP0HXFd1domUR4Azy6YLgspS4/8ggPPHvXvs9a1b7BVwfMsWVqlSJYYXyKpUqcKqVq3Kpk6dyjIzMxkWz8Oz0zt25Cp8rhkgfBaLeoAFCxYwTO/iUzxyEMDrkRcRAAC8nnqxjIwMlp6eznY838EqhVZiO/BnYLyLAC7wLN8BBa389+TE4mSQJQAH/+8/MBmVhJ4T+D7F0tKymrrUEQhhX4sGFcq1+a2729+KEiAvbPb3Z/CiZcHDrjzHz169esVn7jP/2bNz3fmcSG+Cgtj7Gzf4y+bhX27rcxDAPsH+MwLYJdqxff/uY5Hpkazd83ZZnx0IOCC38ig7ARQFNMMWbjJFrQVkw74NbMt6r+/m+pQE/lUE2LFyJQk+b6zC7s7+697HxLDka9cYu32bvQsNzXrRQ4YM4bs3hxlwinci4ecO20Rbdvj0YZURAHcF/UNagIZLiTjs62GhV2Mdwr4k7K8mwMOLF+USIAS2PfvuT7lzh73ORgAOFKDmMANt7rXJlwAwEfSsaghAWsBPzMOihQJPu6Xtnc6ToL+eAIRxQ4fmKXzffv1YZlLSZ89/RB4gEcLPhPCzE2DOnDkMgxs/E9zq86tZhYQKue/+BFu25PIShQgwYsSI5717984sAAEykEruL+MHlBDjsc9ichPb2SRkpRIgNTo6VxIMxXEre9yfg3/29PJlxogA/4aECC+aB3y485bDDCy4soC5xbp9JnxuGmZcn6Fw9TF+/1UODg6jUSH8WFHh+/r6fkS0cCqVkomvopgYW9bFWK/6pu7uf6qCALLmYBdUOPcLbp85k6fn/wQ7Pj0iIlcCDB48OKcfQDhw+gCbeX0mGx42nE0Pms72Buyl7xQDyDUf76I27Hlb8vzl2f5UxARG8Ys26eSkKdbdbzW3pf0GErDKCKAIeEwhiXZ/DgIQeC8f+QFKxeTJk2dQqZsLqoSm5Cd8ECQFR9s+NFewrDiviyHbb6Sl5bqph/tf35oA3Bd4A4HD+cuXALNmzRL8AKUC8YlppMqtNDU1a/IYQB5q/xNiG/2z73zRpnwH1/t+CAn3mxKAF4E8hrAzbt3KlwBjxoyR9QOUhmnTpgk3gJkA7jgR3M2NAPg8ihJFJsLOF3XM/9e2joeLAgEQ82eJpP7zIwD5AaomgBsEfT83AsBJfITvK8teESPumH9nl7vfnADk/T++dCl/AhBQHUx+gNIJ8D1ggRxAdZiAd3k4f+nOzs7tiSx6gIaYS76cIMy/igIBKPijEAFmzpypdD9gypQp08muO+BoN1eOE/gYxTOtZMbGa4i1vctlSw+PtKJAgJc3b7I/g4MVIgCidkr3A8aPHz+X23YXF5dO2P1/KXAM/AvHwB8pTUwkECEBNvfwSC0KBODZw5Tr13MQgCKBOfwA3NWnVAIg17AM9wTNQZr47RcEgtKR3JooxpSwYAIc13d1e1IUCMCzf48vXpRPAAKqgpXqB4waNeqfguQCQIJMmIy+wrVxYrsS1haFn9e/OQEoCBR14QL7BFMghwAF8ANUngxaQqcCygWIJ/1rNa2p3YpvTgAKA/NCkocBAVk1AAIBUsPCcr50igegPoDMwLcjADRAmr29fX0KCpUSWyDIqKFD+ea89r8ohIJ5VRH3BR6cO5dFhPizZ1lsQMAnXq4lC2TueE9AkSAAysy2i3XCqIYw6GFZB5eQokAAigjyfsAsbfAEuz/y0qX3vBdQFps3b+ZlXYIPoDICwCF8gcBPLA//5lES9hbJo3pUJSzKZJAWYN6hkllWB1BRIICQF+AmgdcG/PXwYRoXdHZQkaiqCJDZunXrTbhIsiG/I9nGxqZ1+/btt+L8/0qWAGggnUjBI9r94i0GsV/Q2uFgUSFAtvKw/+QLULkEQBXxFbyTaoA1lYZbUJCoCs7+w1A2fgbVxZtouGSZ7M6fGLWAkbGeZrU1XVxjixwBUDZe2ARAY8g8susGgDahtNAfQLvenIRPCSE1qAauaV2myTrEBVRBgP+g0j/AyUuPj1cYqRD+n/AHeF8AgZdyp6HMO3nTpk3x2YHS8VjUDUZjdmEM8gVx6B18WxACoB5gKO18QbgcGjIdQnr0zmjnq087uFVdW8Pmqzu7RiubAHFw6I4cOcLv3s1qCrmJ8z7HrVu3csVtHAHvID/An/X29lYIEByDimb16tVjtWrVyti2bdvzghDA0dGxad5FntQjSMRQp5awUkQCS5iD6gtaORwlx1BpJuAWQr3h4eEsFjv76dOn7OXLl+z169fszZs3WUhJSfkMb9++5T0E+Y53QRQuCyjM5Kqb+fj4cCJ8hBaIKogJgKP3jqeDRRPZUwEJ9ABTwKlLJdN+aBG7oxQCkHd/79Chvy/4+T25sXp18v1Nm5Ji9+6NTThwIDrp0KGoJ0eOfIZnJ048jDly5BE8cpYdvIsXcXhOAlnhZ8A7fwAz8bqgPgAqg29mv0K2uJFAg+xcGcp5u7WvaNaLa4T13dxeKMMJ/BNFnxGo7bswfjy7PmkSC582jd1GaPceuoQeoPT74dy57BHhJkrAuLBJ4DmEjglfvMPoGULDtxAaflMgJ5DKwjt37nwXv/8M2gA5nLviqA10yRZaAA6AR20bw1Y/1LSa0q+GxfqTq36N/CoPH72E8TjL/w4yXJkxg10cN45dQQsYJ0Xw5MksBLiE/+eCJmFzfILAn48cOfKOv7//nf37979QxikAgyb4xPBash2/0nBIGoiQrTfejI5INc/v3r1bmUe+j2gJS0Hy5xmSQgkgRjyCPVFI+KxZteoRvPxohH6fYT7QR1UcAxFankWq31C6NSRv0yCQwQCwCT9xYoOq4wBpkZGFEgfA2PiJihV6Sqsk7ZDyv06a1BIt3DEqjgSmqlr4UGS30OtfV/08f9XXE5iZmppWCjp8eCOaOj+qggDChBBVgJsTXHy1XktLy4N2/xeOipdMgp4wPHrm6NF9kcGLFAsBsOtjMBqGV/I4AsbSlPCvPzJ+j46ayvvXrJn9LirqTVElADKJqQsXLlyN0u+qlOwpI90VqLwoojFgV71y5QZwEHcinZtaVAgAdf8JV9ycbNCgQQvK7JkA+sqP50vawIACKQ41K1b0vH7o0Kb02Nh334oAqBn49Ntvv11EIKkzr4KmmIYh/V01JOGrjgiGlDJ1qFWpUsMzO3f6o/I3vrAIAFWfhk7iY4gYduBDryiqWfbbZPEkjWBGQZaK/tOn+947e/YI/ITXSj0Gkle/ZcuWsOnTp8+nQk0nwJIErysJ/tsSoTSVTluR5115wYQJA2AiNiSHhNz4EBPzT24EwOfv8hF6JnL+iXynT5o0aaaHh4c37XZbMkOGwo6XnLyiQQRN2okGMtU1FUholft16dJm3fz5wwO3b18SduzYFlwZc+DeuXPHcbffaX5DKa6L2Y9z+1oIezqmdfaxtrbmu9yDCGUtM9lTH9CSbHxRJAKRgQSkQ8IqQ4QwIw1hQ8RwIOEKsAfsSNgW5MmXI0Lp0e9ZShK8yMhA0CQB6pIw9clsGAig/9en77WzCbykugv9/46UImUMsLf8AAAAAElFTkSuQmCC", + }, + } +) + +func contains(name string, config_links []*config_proto.GUILink) bool { + for _, i := range config_links { + if i.Text == name { + return true + } + } + return false +} + +// Merge the user's links with the default built-in links but do not +// override them! +func MergeGUILinks( + config_links []*config_proto.GUILink, + source []*config_proto.GUILink) []*config_proto.GUILink { + for _, link := range source { + if !contains(link.Text, config_links) { + config_links = append(config_links, link) + } + } + + return config_links +} diff --git a/services/users/users.go b/services/users/users.go index bbf6eab746..2e248817ef 100644 --- a/services/users/users.go +++ b/services/users/users.go @@ -33,6 +33,7 @@ import ( api_proto "www.velocidex.com/golang/velociraptor/api/proto" config_proto "www.velocidex.com/golang/velociraptor/config/proto" datastore "www.velocidex.com/golang/velociraptor/datastore" + "www.velocidex.com/golang/velociraptor/logging" "www.velocidex.com/golang/velociraptor/paths" "www.velocidex.com/golang/velociraptor/services" ) @@ -258,6 +259,10 @@ func (self UserManager) SetUserOptions(username string, old_options = &api_proto.SetGUIOptionsRequest{} } + // For now we do not allow the user to set the links in their + // profile. + old_options.Links = nil + if options.Lang != "" { old_options.Lang = options.Lang } @@ -299,6 +304,19 @@ func (self UserManager) GetUserOptions(username string) ( options.Options = default_user_options } + // Add any links in the config file to the user's preferences. + if self.config_obj.GUI != nil { + options.Links = MergeGUILinks(options.Links, self.config_obj.GUI.Links) + } + + // Add the defaults. + options.Links = MergeGUILinks(options.Links, DefaultLinks) + + // NOTE: It is possible for a user to disable one of the default + // targets by simply adding an entry with disabled: true - we will + // not override the configured link from the default and it will + // be ignored. + return options, err } @@ -307,6 +325,9 @@ func StartUserManager( wg *sync.WaitGroup, config_obj *config_proto.Config) error { + logger := logging.GetLogger(config_obj, &logging.FrontendComponent) + logger.Info("Starting user manager service for org %v", config_obj.OrgId) + CA_Pool := x509.NewCertPool() if config_obj.Client != nil { CA_Pool.AppendCertsFromPEM([]byte(config_obj.Client.CaCertificate)) @@ -324,7 +345,8 @@ func StartUserManager( // Make sure there is always something available. func init() { service := &UserManager{ - ca_pool: x509.NewCertPool(), + ca_pool: x509.NewCertPool(), + config_obj: &config_proto.Config{}, } services.RegisterUserManager(service) } diff --git a/utils/orgs.go b/utils/orgs.go index 731091ca90..a2b5c4d138 100644 --- a/utils/orgs.go +++ b/utils/orgs.go @@ -34,3 +34,20 @@ func OrgIdFromClientId(client_id string) string { } return "" } + +func IsRootOrg(org_id string) bool { + return org_id == "" || org_id == "root" +} + +func NormalizedOrgId(org_id string) string { + if IsRootOrg(org_id) { + return "root" + } + return org_id +} +func CompareOrgIds(a, b string) bool { + if IsRootOrg(a) && IsRootOrg(b) { + return true + } + return a == b +} diff --git a/vql/parsers/event_logs/watcher.go b/vql/parsers/event_logs/watcher.go index e6c03340d2..51016579a5 100644 --- a/vql/parsers/event_logs/watcher.go +++ b/vql/parsers/event_logs/watcher.go @@ -92,9 +92,10 @@ func (self *EventLogWatcherService) StartMonitoring( scope.Log("StartMonitoring") defer utils.CheckForPanic("StartMonitoring") - // By default check every 3 seconds. + // By default check every 15 seconds. Event logs are not flushed + // that often so checking more frequently does not help much. if frequency == 0 { - frequency = 3 + frequency = 15 } // A resolver for messages diff --git a/vql/readers/paged_reader_test.go b/vql/readers/paged_reader_test.go index 186a49692d..17bed55bf5 100644 --- a/vql/readers/paged_reader_test.go +++ b/vql/readers/paged_reader_test.go @@ -145,7 +145,12 @@ func (self *TestSuite) TestPagedReader() { self.scope.Close() // Destoying the scope should close the readers. - assert.Nil(self.T(), reader.reader) + vtesting.WaitUntil(time.Second, self.T(), func() bool { + reader.mu.Lock() + defer reader.mu.Unlock() + + return reader.reader == nil + }) // No outstanding readers assert.Equal(self.T(), int64(0), self.pool.lru.Size()) diff --git a/vql/server/orgs/create.go b/vql/server/orgs/create.go index 4e495f5d11..5fa7f17b9a 100644 --- a/vql/server/orgs/create.go +++ b/vql/server/orgs/create.go @@ -36,6 +36,11 @@ func (self OrgCreateFunction) Call( return vfilter.Null{} } + if arg.OrgName == "" { + scope.Log("ERROR:org_create: An Org name must be specified") + return vfilter.Null{} + } + org_manager, err := services.GetOrgManager() if err != nil { scope.Log("org_create: %s", err) diff --git a/vql/server/orgs/delete.go b/vql/server/orgs/delete.go new file mode 100644 index 0000000000..d077a904a2 --- /dev/null +++ b/vql/server/orgs/delete.go @@ -0,0 +1,78 @@ +package orgs + +import ( + "context" + + "github.com/Velocidex/ordereddict" + "github.com/sirupsen/logrus" + "www.velocidex.com/golang/velociraptor/acls" + "www.velocidex.com/golang/velociraptor/logging" + "www.velocidex.com/golang/velociraptor/services" + vql_subsystem "www.velocidex.com/golang/velociraptor/vql" + "www.velocidex.com/golang/vfilter" + "www.velocidex.com/golang/vfilter/arg_parser" +) + +type OrgDeleteFunctionArgs struct { + OrgId string `vfilter:"required,field=org,doc=The org ID to delete."` +} + +type OrgDeleteFunction struct{} + +func (self OrgDeleteFunction) Call( + ctx context.Context, + scope vfilter.Scope, + args *ordereddict.Dict) vfilter.Any { + + err := vql_subsystem.CheckAccess(scope, acls.SERVER_ADMIN) + if err != nil { + scope.Log("org_delete: %s", err) + return vfilter.Null{} + } + + config_obj, ok := vql_subsystem.GetServerConfig(scope) + if !ok { + scope.Log("org_delete: Command can only run on the server") + return vfilter.Null{} + } + + arg := &OrgDeleteFunctionArgs{} + err = arg_parser.ExtractArgsWithContext(ctx, scope, args, arg) + if err != nil { + scope.Log("org_delete: %s", err) + return vfilter.Null{} + } + + org_manager, err := services.GetOrgManager() + if err != nil { + scope.Log("org_delete: %s", err) + return vfilter.Null{} + } + + principal := vql_subsystem.GetPrincipal(scope) + logger := logging.GetLogger(config_obj, &logging.Audit) + logger.WithFields(logrus.Fields{ + "OrgId": arg.OrgId, + "Principal": principal, + }).Info("org_delete") + + err = org_manager.DeleteOrg(arg.OrgId) + if err != nil { + scope.Log("org_delete: %s", err) + return vfilter.Null{} + } + + return arg.OrgId +} + +func (self OrgDeleteFunction) Info(scope vfilter.Scope, type_map *vfilter.TypeMap) *vfilter.FunctionInfo { + return &vfilter.FunctionInfo{ + Name: "org_delete", + Doc: "Deletes an Org from the server.", + ArgType: type_map.AddType(scope, &OrgDeleteFunctionArgs{}), + } +} + +func init() { + vql_subsystem.RegisterFunction(&OrgDeleteFunction{}) +} diff --git a/vql/server/users/delete.go b/vql/server/users/delete.go index 1957f57223..273c7db37d 100644 --- a/vql/server/users/delete.go +++ b/vql/server/users/delete.go @@ -6,9 +6,7 @@ import ( "github.com/Velocidex/ordereddict" "github.com/sirupsen/logrus" "www.velocidex.com/golang/velociraptor/acls" - "www.velocidex.com/golang/velociraptor/datastore" "www.velocidex.com/golang/velociraptor/logging" - "www.velocidex.com/golang/velociraptor/paths" "www.velocidex.com/golang/velociraptor/services" vql_subsystem "www.velocidex.com/golang/velociraptor/vql" "www.velocidex.com/golang/vfilter" @@ -45,11 +43,7 @@ func (self UserDeleteFunction) Call( return vfilter.Null{} } - db, err := datastore.GetDB(config_obj) - if err != nil { - scope.Log("user_delete: %s", err) - return vfilter.Null{} - } + user_manager := services.GetUserManager() principal := vql_subsystem.GetPrincipal(scope) logger := logging.GetLogger(config_obj, &logging.Audit) @@ -58,31 +52,12 @@ func (self UserDeleteFunction) Call( "Principal": principal, }).Info("user_delete") - user_path_manager := paths.NewUserPathManager(arg.Username) - err = db.DeleteSubject(config_obj, user_path_manager.Path()) + err = user_manager.DeleteUser(config_obj, arg.Username) if err != nil { scope.Log("user_delete: %s", err) return vfilter.Null{} } - // Also remove the ACLs for the user from all orgs. - org_manager, err := services.GetOrgManager() - if err != nil { - scope.Log("user_delete: %v", err) - return vfilter.Null{} - } - - for _, org_record := range org_manager.ListOrgs() { - org_config_obj, err := org_manager.GetOrgConfig(org_record.OrgId) - if err != nil { - continue - } - - err = db.DeleteSubject(org_config_obj, user_path_manager.ACL()) - if err != nil { - continue - } - } return arg.Username } diff --git a/vql/server/users/users.go b/vql/server/users/users.go index a73680d1f1..2e3dcfda23 100644 --- a/vql/server/users/users.go +++ b/vql/server/users/users.go @@ -9,6 +9,7 @@ import ( api_proto "www.velocidex.com/golang/velociraptor/api/proto" "www.velocidex.com/golang/velociraptor/json" "www.velocidex.com/golang/velociraptor/services" + "www.velocidex.com/golang/velociraptor/utils" vql_subsystem "www.velocidex.com/golang/velociraptor/vql" "www.velocidex.com/golang/vfilter" "www.velocidex.com/golang/vfilter/arg_parser" @@ -80,7 +81,7 @@ func (self UsersPlugin) Call( for _, org_record := range user_details.Orgs { // Only display users that belong to the current org - if !arg.AllOrgs && org_record.Id != current_org { + if !arg.AllOrgs && !utils.CompareOrgIds(org_record.Id, current_org) { continue }