From 9fd23842058589cbcce33f5cd10052f4aeb3a9ff Mon Sep 17 00:00:00 2001 From: sadath-12 Date: Tue, 9 Jan 2024 17:29:01 +0530 Subject: [PATCH] parent 8802fd69d7202d577fe77b9c8ad160cc9ea6ca4e author sadath-12 1704801541 +0530 committer sadath-12 1704914706 +0530 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit parent 8802fd69d7202d577fe77b9c8ad160cc9ea6ca4e author sadath-12 1704801541 +0530 committer sadath-12 1704914704 +0530 parent 8802fd69d7202d577fe77b9c8ad160cc9ea6ca4e author sadath-12 1704801541 +0530 committer sadath-12 1704914701 +0530 parent 8802fd69d7202d577fe77b9c8ad160cc9ea6ca4e author sadath-12 1704801541 +0530 committer sadath-12 1704914698 +0530 parent 8802fd69d7202d577fe77b9c8ad160cc9ea6ca4e author sadath-12 1704801541 +0530 committer sadath-12 1704914694 +0530 parent 8802fd69d7202d577fe77b9c8ad160cc9ea6ca4e author sadath-12 1704801541 +0530 committer sadath-12 1704914657 +0530 Fix: monitoring BPF maps solving all monitoring issues exposed at issue #1774 Signed-off-by: sadath-12 make: Introduce install/kubernetes/Makefile Signed-off-by: sadath-12 workflows: bump bom version for race condition fix We experienced #1894, which made me create kubernetes-sigs/bom#385 only to fix the race condition and realize that it was already patched but no release existed. Signed-off-by: Mahe Tardy tetragon: Remove early binary filter bpf code We can move the binary path matching early in the filter program, so it's invoked just one tailcall from where it is now. This won't make much difference wrt early binary filter invocation, so we can remove it. As a side effect we free some (~60) instructions in filter_arg program for small kernels. Signed-off-by: Jiri Olsa tetragon: Remove early binary filter config code Now that we do not have bpf support for early filter et's remove the go config code for that as well. Signed-off-by: Jiri Olsa tetragon: Split filter_tailcall_index in two values And make the index names more appropriate. Signed-off-by: Jiri Olsa tetragon: Use selidx name for selector index The selidx is used in other parts of the code and fits more than just generic index. Signed-off-by: Jiri Olsa tracingpolicy: add a message field to inform users what is happening Right now all fields in Tetragon events are generated from code, the only exception is the policy_name which does not inform users what is going on. This optional "message" field if present will be copied and printed in the final generated event. We want to inform users what is really happening, why this event was generated? it is not obvious to non technical users. An optional abstracted could be easy to read something like: "message": "Kernel module being loaded" As we want to capture new users, the policy_name is not enough and strictly speaking it has its own purpose, using abstracted messages or logs appeals to more users. The down side of this is our generated events may grow in size, thus the new "message" field will be chopped to 256 characters only. In future if the event size is really a problem, we can start shipping default field filters, that hide these fields from the source before even constructing the event. Signed-off-by: Djalal Harouni api:proto: add short message to print Tracing Policy message Signed-off-by: Djalal Harouni events: include the tracing policy message in events If a tracing policy has the message field set, then include it into the reported events. It is optional. The message field is properly escaped. Signed-off-by: Djalal Harouni tests: ensure that message field is reported Signed-off-by: Djalal Harouni policylibrary: add message field to module tracing policy This adds the message field to the module tracing library as an example of what the event is about. Signed-off-by: Djalal Harouni test: add message testing Signed-off-by: Djalal Harouni metrics: Do not return when we cannot find a _stats map In Tetragon, we have maps ending with _stats that contain metadata about the main maps. An example is that we have execve_map and execve_map_stats that contains errors and other information related to execve_map map. Now when we fail to open the _stats map, we just stop the loop and we can possibly miss to check for other maps. This patch change that and tries for the next map. Additionally we do not try to collect stats for maps that already end up with _stats as this would result in _stats_stats map names. Signed-off-by: Anastasios Papagiannis fix(deps): update module golang.org/x/sync to v0.6.0 Signed-off-by: cilium-renovate[bot] <134692979+cilium-renovate[bot]@users.noreply.github.com> tester-progs: compile killer-tester-32 statically Signed-off-by: Kornilios Kourtis vmtests: make a note when all tests skipped Currently, if all tests are skipped we print success, which is misleading. Print a better message. Signed-off-by: Kornilios Kourtis vmtests: listTests now accepts a pattern Previously, we always used "." to list tests in listTests. This patch adds it as an argument to be used in a later patch. Signed-off-by: Kornilios Kourtis vmtests: improve running tests from a file This patch improves loading tests form a file. First, it allows for having comments with lines starting with '#'. Second, it lists the tests based on the provided user pattern instead of using it as it is. Previously, the test name was defined by the user pattern. This lead to inconsistent reporting. This patch fixes this because now we report per-test results rather than per-pattern results. Signed-off-by: Kornilios Kourtis vmtests: use a strict pattern for test execution It is possible that a test is a substring of another. Use a strict pattern so that we execute only the specified test. Signed-off-by: Kornilios Kourtis tetragon-vmtests-run: support for detailed results There are two ways to skip a test in our CI: 1. add it to CiBlacklist in split-tetragon-gotests 2. use t.Skip() CI results report 1., but they do not report 2. This means that skipped tests can go easily unnoticed. To report tests skipped with (2), we need to parse the result files. This patch does exactly that. It adds a new option --enable-detailed-results. If this option is set, we set KeepAllLogs because we need to parse all logs after the tests are finished. The tests we skip with (1) are marked with ⏭️. We introduce a new symbol for the tests that are skipped with (2): ⚡ Parsing the detailed results allows us to also report sub-tests (i.e., tests executed with t.Run()). Here's an output example: ``` ✅ pkg.sensors.tracing.Test_Kprobe_DisableEnablePolicy (total:3 failed:0 skipped:0) 2.680496982s 1m33.952671893s ├─✅ Test_Kprobe_DisableEnablePolicy/sensor 1.05s (1.05s) ├─✅ Test_Kprobe_DisableEnablePolicy/tracing-policy 1.09s (2.14s) └─✅ Test_Kprobe_DisableEnablePolicy 2.56s (4.7s) ⚡ pkg.sensors.tracing.TestKillerOverride32 (total:1 failed:0 skipped:1) 130.759191ms 1m34.083431084s ⚡ pkg.sensors.tracing.TestKillerSignal32 (total:1 failed:0 skipped:1) 132.393451ms 1m34.215824535s ⚡ pkg.sensors.tracing.TestKillerOverrideBothBits (total:1 failed:0 skipped:1) 119.455061ms 1m34.335279596s ⚡ pkg.sensors.tracing.TestKillerOverride (total:1 failed:0 skipped:1) 121.255148ms 1m34.456534744s ⚡ pkg.sensors.tracing.TestKillerSignal (total:1 failed:0 skipped:1) 136.665421ms 1m34.593200165s ✅ pkg.sensors.tracing.TestKillerMulti (total:1 failed:0 skipped:0) 132.761861ms 1m34.725962026s ``` Signed-off-by: Kornilios Kourtis gh: add --enable-detailed-results to vmtests Signed-off-by: Kornilios Kourtis chore(deps): update all lvh-images main Signed-off-by: cilium-renovate[bot] <134692979+cilium-renovate[bot]@users.noreply.github.com> tests: Unload policy after load Unload the policy that was loaded during the test Signed-off-by: sadath-12 api: detect binary execution that raise process privileges Add ProcessPrivilegesChanged to note reasons why the process privileges changed, and start using it in the binary_properties to indicate why the binary execution changed or raised privileges. For now we handle only elevating privileges, in future depending on user's requests we may do privilege changes or dropping. The ProcessPrivilegesChanged is an enum able to handle different values. The new `binary_properties.privileges_changed` contains the reasons why this binary execution gained new capabilities or elevated its privileges. Usually this happens due: 1. File capability sets on the binary. 2. set-user-ID to root bit is set on the binary. Details of ProcessPrivilegesChanged: 1. PRIVILEGES_RAISED_EXEC_FILE_CAP - The File capability sets on binary: The kernel supports associating capability sets with an executable file using `setcap` command. The file capability sets are stored in an extended attribute named `security.capability`. The file capability sets, in conjunction with the capability sets of the process, determine the process capabilities and privileges after the `execve` system call. For further reference, please check sections `File capability extended attribute versioning` and `Namespaced file capabilities` of the capabilities man pages: https://man7.org/linux/man-pages/man7/capabilities.7.html. 2. PRIVILEGES_RAISED_EXEC_FILE_SETUID - set-user-ID to root bit is set on the binary: When a process with nonzero UIDs executes a binary with a set-user-ID to root also known as suid-root executable, then the kernel switches the effective user ID to 0 (root) which is a privilege elevation operation since it grants access to resources owned by the root user. The effective user ID is listed inside the `process_credentials` part of the `process` object. For further reading, section `Capabilities and execution of programs by root` of https://man7.org/linux/man-pages/man7/capabilities.7.html. Afterward the kernel recalculates the capability sets of the process and grants all capabilities in the permitted and effective capability sets, except those masked out by the capability bounding set. If the binary also have file capability sets then these bits are honored and the process gains just the capabilities granted by the file capability sets (i.e., not all capabilities, as it would occur when executing a set-user-ID to root binary that does not have any associated file capabilities). This is described in section `Set-user-ID-root programs that have file capabilities` of https://man7.org/linux/man-pages/man7/capabilities.7.html. The new granted capabilities can be listed inside the `process` object. There is one exception for the special treatments of set-user-ID to root execution receiving all capabilities, if the `SecBitNoRoot` bit of the Secure bits is set, then the kernel does not grant any capability. The secure bits are already exposed part of the `process_credentials` object. Please check section: `The securebits flags: establishing a capabilities-only environment` of the capabilities man pages: https://man7.org/linux/man-pages/man7/capabilities.7.html The new privileges_changed contains the reasons, no need to encode again the full capabilities there, let's just indicate to the user and if they are interested they can inspect other fields that contain the permitted and effective capabilities of the current execution. *Limitations:* 1. We do not handle the case of an unprivileged user id that is _mapped_ to user id root 0 inside its own namespace then performs a setuid to root execution. Current eBPF infrastructure does not support user id translation into target user namespace. Plus current Tetragon design deals with global uids, so it is not clear at this moment how to handle this corner case. For this the binary_properties.privileges_changed is an array that can hold extra values in the future. 2. We do not handle the case of a binary having both setuid to root bit set and file capability sets on the binary. Right now we report in the `privileges_changed` only `PRIVILEGES_RAISED_EXEC_FILE_SETUID` where we should also add `PRIVILEGES_RAISED_EXEC_FILE_CAP`. This is left for the future as we have to read the `security.capability` field of the extended attributes of the binary and parse the capabilities that are actually set to ensure that new capabilities received are not only due to the set-user-ID root exection. Signed-off-by: Djalal Harouni tetragon: detect binary execution that raise process privileges From a higher level: Populate binary_properties.privileges_changed with the the reasons why this binary execution gained new capabilities or elevated its privileges. Usually this happens due: 1. File capability sets on the binary. 2. set-user-ID to root bit is set on the binary. Details of ProcessPrivilegesChanged: 1. PRIVILEGES_RAISED_EXEC_FILE_CAP - The File capability sets on binary: The kernel supports associating capability sets with an executable file using `setcap` command. The file capability sets are stored in an extended attribute named `security.capability`. The file capability sets, in conjunction with the capability sets of the process, determine the process capabilities and privileges after the `execve` system call. For further reference, please check sections `File capability extended attribute versioning` and `Namespaced file capabilities` of the capabilities man pages: https://man7.org/linux/man-pages/man7/capabilities.7.html. 2. PRIVILEGES_RAISED_EXEC_FILE_SETUID - set-user-ID to root bit is set on the binary: When a process with nonzero UIDs executes a binary with a set-user-ID to root also known as suid-root executable, then the kernel switches the effective user ID to 0 (root) which is a privilege elevation operation since it grants access to resources owned by the root user. The effective user ID is listed inside the `process_credentials` part of the `process` object. For further reading, section `Capabilities and execution of programs by root` of https://man7.org/linux/man-pages/man7/capabilities.7.html. Afterward the kernel recalculates the capability sets of the process and grants all capabilities in the permitted and effective capability sets, except those masked out by the capability bounding set. If the binary also have file capability sets then these bits are honored and the process gains just the capabilities granted by the file capability sets (i.e., not all capabilities, as it would occur when executing a set-user-ID to root binary that does not have any associated file capabilities). This is described in section `Set-user-ID-root programs that have file capabilities` of https://man7.org/linux/man-pages/man7/capabilities.7.html. The new granted capabilities can be listed inside the `process` object. There is one exception for the special treatments of set-user-ID to root execution receiving all capabilities, if the `SecBitNoRoot` bit of the Secure bits is set, then the kernel does not grant any capability. The secure bits are already exposed part of the `process_credentials` object. Please check section: `The securebits flags: establishing a capabilities-only environment` of the capabilities man pages: https://man7.org/linux/man-pages/man7/capabilities.7.html The new privileges_changed contains the reasons, no need to encode again the full capabilities there, let's just indicate to the user and if they are interested they can inspect other fields that contain the permitted and effective capabilities of the current execution. Implementation: The capabilities are re-calculated by the capability LSM during execve, so let's avoid trying to be smart and calculate or guess them... we just display the final results. To display these fields, Tetragon must be run with enable-process-cred. 1. If the setuid bit is set we check if it is a privileged root and if it's real uid is not global root and effective uid is global root, if so then this a suid binary execution which is already enough for Tetragon to report as a privilege change execution. 2. Check if the setuid bit is not set and the new permitted capability sets is higher then the previous one then is is a file capability sets execution. *Limitations:* 1. We do not handle the case of an unprivileged user id that is _mapped_ to user id root 0 inside its own namespace then performs a setuid to root execution. Current eBPF infrastructure does not support user id translation into target user namespace. Plus current Tetragon design deals with global uids, so it is not clear at this moment how to handle this corner case. For this the binary_properties.privileges_changed is an array that can hold extra values in the future. 2. We do not handle the case of a binary having both setuid to root bit set and file capability sets on the binary. Right now we report in the `privileges_changed` only `PRIVILEGES_RAISED_EXEC_FILE_SETUID` where we should also add `PRIVILEGES_RAISED_EXEC_FILE_CAP`. This is left for the future as we have to read the `security.capability` field of the extended attributes of the binary and parse the capabilities that are actually set to ensure that new capabilities received are not only due to the set-user-ID root exection. Example output event: File capabilities execution: "process_exec": { "process": { "exec_id": "OjIwMTAxOTMxNzAzMjc4OjE0MDUwOA==", "pid": 140508, "uid": 1000, "cwd": "/home/tixxdz/work/station/code/src/github.com/tixxdz/tetragon", "binary": "/usr/bin/ping", "arguments": "ebpf.io", "flags": "execve clone", "start_time": "2023-11-23T14:32:53.227623175Z", "auid": 1000, "parent_exec_id": "OjI5NjYzNzAwMDAwMDA6NDQ4NTk=", "refcnt": 1, "cap": { "permitted": [ "CAP_NET_RAW" ], "effective": [ "CAP_NET_RAW" ] }, "tid": 140508, "process_credentials": { "uid": 1000, "gid": 1000, "euid": 1000, "egid": 1000, "suid": 1000, "sgid": 1000, "fsuid": 1000, "fsgid": 1000 }, "binary_properties": { "privileges_changed": [ "PRIVILEGES_RAISED_EXEC_FILE_CAP" ] } }, Setuid suid execution (from non uid 0 -> to global uid 0 in root user namespace): "process_exec": { "process": { "exec_id": "OjMyMTg1ODY1MDcxNTQ6Mjg5NTU=", "pid": 28955, "uid": 1000, "cwd": "/home/tixxdz/work/station/code/src/github.com/tixxdz/tetragon", "binary": "/usr/bin/su", "arguments": "--help", "flags": "execve clone", "start_time": "2023-12-11T14:59:24.735197753Z", "auid": 1000, "parent_exec_id": "OjE0MjI5NzAwMDAwMDA6MTI4NjE=", "refcnt": 1, "cap": { "permitted": [ "CAP_CHOWN", "DAC_OVERRIDE", "CAP_DAC_READ_SEARCH", "CAP_FOWNER", "CAP_FSETID", "CAP_KILL", "CAP_SETGID", "CAP_SETUID", "CAP_SETPCAP", "CAP_LINUX_IMMUTABLE", "CAP_NET_BIND_SERVICE", "CAP_NET_BROADCAST", "CAP_NET_ADMIN", "CAP_NET_RAW", "CAP_IPC_LOCK", "CAP_IPC_OWNER", "CAP_SYS_MODULE", "CAP_SYS_RAWIO", "CAP_SYS_CHROOT", "CAP_SYS_PTRACE", "CAP_SYS_PACCT", "CAP_SYS_ADMIN", "CAP_SYS_BOOT", "CAP_SYS_NICE", "CAP_SYS_RESOURCE", "CAP_SYS_TIME", "CAP_SYS_TTY_CONFIG", "CAP_MKNOD", "CAP_LEASE", "CAP_AUDIT_WRITE", "CAP_AUDIT_CONTROL", "CAP_SETFCAP", "CAP_MAC_OVERRIDE", "CAP_MAC_ADMIN", "CAP_SYSLOG", "CAP_WAKE_ALARM", "CAP_BLOCK_SUSPEND", "CAP_AUDIT_READ", "CAP_PERFMON", "CAP_BPF", "CAP_CHECKPOINT_RESTORE" ], "effective": [ "CAP_CHOWN", "DAC_OVERRIDE", "CAP_DAC_READ_SEARCH", "CAP_FOWNER", "CAP_FSETID", "CAP_KILL", "CAP_SETGID", "CAP_SETUID", "CAP_SETPCAP", "CAP_LINUX_IMMUTABLE", "CAP_NET_BIND_SERVICE", "CAP_NET_BROADCAST", "CAP_NET_ADMIN", "CAP_NET_RAW", "CAP_IPC_LOCK", "CAP_IPC_OWNER", "CAP_SYS_MODULE", "CAP_SYS_RAWIO", "CAP_SYS_CHROOT", "CAP_SYS_PTRACE", "CAP_SYS_PACCT", "CAP_SYS_ADMIN", "CAP_SYS_BOOT", "CAP_SYS_NICE", "CAP_SYS_RESOURCE", "CAP_SYS_TIME", "CAP_SYS_TTY_CONFIG", "CAP_MKNOD", "CAP_LEASE", "CAP_AUDIT_WRITE", "CAP_AUDIT_CONTROL", "CAP_SETFCAP", "CAP_MAC_OVERRIDE", "CAP_MAC_ADMIN", "CAP_SYSLOG", "CAP_WAKE_ALARM", "CAP_BLOCK_SUSPEND", "CAP_AUDIT_READ", "CAP_PERFMON", "CAP_BPF", "CAP_CHECKPOINT_RESTORE" ] }, "tid": 28955, "process_credentials": { "uid": 1000, "gid": 1000, "euid": 0, "egid": 1000, "suid": 0, "sgid": 1000, "fsuid": 0, "fsgid": 1000 }, "binary_properties": { "setuid": 0, "privileges_changed": [ "PRIVILEGES_RAISED_EXEC_FILE_SETUID" ] } }, Signed-off-by: Djalal Harouni api: detect set-group-ID to root as privileges execution Make Tetragon treat a binary exec with set-group-ID to root as a privileged execution since it changes the effective group ID to root which allows access to resources owned by group root. Signed-off-by: Djalal Harouni tetragon: detect setgid execution to root as privileged execution Execution of a binary with set-group-ID to root is handled as a privileged execution. The PRIVILEGES_RAISED_EXEC_FILE_SETGID will be set. Signed-off-by: Djalal Harouni tests: split exec suid tests Signed-off-by: Djalal Harouni tests: add suid root and setuid to non root execution tests Signed-off-by: Djalal Harouni tests: detect privileged execution of file caps binaries We use the ping binary if it is available to detect privileged execution through file caps on binaries. Signed-off-by: Djalal Harouni fix(deps): update module golang.org/x/sys to v0.16.0 Signed-off-by: cilium-renovate[bot] <134692979+cilium-renovate[bot]@users.noreply.github.com> make: Introduce install/kubernetes/Makefile Signed-off-by: sadath-12 workflows: bump bom version for race condition fix We experienced #1894, which made me create kubernetes-sigs/bom#385 only to fix the race condition and realize that it was already patched but no release existed. Signed-off-by: Mahe Tardy tetragon: Remove early binary filter config code Now that we do not have bpf support for early filter et's remove the go config code for that as well. Signed-off-by: Jiri Olsa tetragon: Use selidx name for selector index The selidx is used in other parts of the code and fits more than just generic index. Signed-off-by: Jiri Olsa tracingpolicy: add a message field to inform users what is happening Right now all fields in Tetragon events are generated from code, the only exception is the policy_name which does not inform users what is going on. This optional "message" field if present will be copied and printed in the final generated event. We want to inform users what is really happening, why this event was generated? it is not obvious to non technical users. An optional abstracted could be easy to read something like: "message": "Kernel module being loaded" As we want to capture new users, the policy_name is not enough and strictly speaking it has its own purpose, using abstracted messages or logs appeals to more users. The down side of this is our generated events may grow in size, thus the new "message" field will be chopped to 256 characters only. In future if the event size is really a problem, we can start shipping default field filters, that hide these fields from the source before even constructing the event. Signed-off-by: Djalal Harouni events: include the tracing policy message in events If a tracing policy has the message field set, then include it into the reported events. It is optional. The message field is properly escaped. Signed-off-by: Djalal Harouni tests: ensure that message field is reported Signed-off-by: Djalal Harouni policylibrary: add message field to module tracing policy This adds the message field to the module tracing library as an example of what the event is about. Signed-off-by: Djalal Harouni test: add message testing Signed-off-by: Djalal Harouni tester-progs: compile killer-tester-32 statically Signed-off-by: Kornilios Kourtis vmtests: make a note when all tests skipped Currently, if all tests are skipped we print success, which is misleading. Print a better message. Signed-off-by: Kornilios Kourtis vmtests: listTests now accepts a pattern Previously, we always used "." to list tests in listTests. This patch adds it as an argument to be used in a later patch. Signed-off-by: Kornilios Kourtis vmtests: improve running tests from a file This patch improves loading tests form a file. First, it allows for having comments with lines starting with '#'. Second, it lists the tests based on the provided user pattern instead of using it as it is. Previously, the test name was defined by the user pattern. This lead to inconsistent reporting. This patch fixes this because now we report per-test results rather than per-pattern results. Signed-off-by: Kornilios Kourtis vmtests: use a strict pattern for test execution It is possible that a test is a substring of another. Use a strict pattern so that we execute only the specified test. Signed-off-by: Kornilios Kourtis tetragon-vmtests-run: support for detailed results There are two ways to skip a test in our CI: 1. add it to CiBlacklist in split-tetragon-gotests 2. use t.Skip() CI results report 1., but they do not report 2. This means that skipped tests can go easily unnoticed. To report tests skipped with (2), we need to parse the result files. This patch does exactly that. It adds a new option --enable-detailed-results. If this option is set, we set KeepAllLogs because we need to parse all logs after the tests are finished. The tests we skip with (1) are marked with ⏭️. We introduce a new symbol for the tests that are skipped with (2): ⚡ Parsing the detailed results allows us to also report sub-tests (i.e., tests executed with t.Run()). Here's an output example: ``` ✅ pkg.sensors.tracing.Test_Kprobe_DisableEnablePolicy (total:3 failed:0 skipped:0) 2.680496982s 1m33.952671893s ├─✅ Test_Kprobe_DisableEnablePolicy/sensor 1.05s (1.05s) ├─✅ Test_Kprobe_DisableEnablePolicy/tracing-policy 1.09s (2.14s) └─✅ Test_Kprobe_DisableEnablePolicy 2.56s (4.7s) ⚡ pkg.sensors.tracing.TestKillerOverride32 (total:1 failed:0 skipped:1) 130.759191ms 1m34.083431084s ⚡ pkg.sensors.tracing.TestKillerSignal32 (total:1 failed:0 skipped:1) 132.393451ms 1m34.215824535s ⚡ pkg.sensors.tracing.TestKillerOverrideBothBits (total:1 failed:0 skipped:1) 119.455061ms 1m34.335279596s ⚡ pkg.sensors.tracing.TestKillerOverride (total:1 failed:0 skipped:1) 121.255148ms 1m34.456534744s ⚡ pkg.sensors.tracing.TestKillerSignal (total:1 failed:0 skipped:1) 136.665421ms 1m34.593200165s ✅ pkg.sensors.tracing.TestKillerMulti (total:1 failed:0 skipped:0) 132.761861ms 1m34.725962026s ``` Signed-off-by: Kornilios Kourtis gh: add --enable-detailed-results to vmtests Signed-off-by: Kornilios Kourtis chore(deps): update all lvh-images main Signed-off-by: cilium-renovate[bot] <134692979+cilium-renovate[bot]@users.noreply.github.com> tests: Unload policy after load Unload the policy that was loaded during the test Signed-off-by: sadath-12 api: detect set-group-ID to root as privileges execution Make Tetragon treat a binary exec with set-group-ID to root as a privileged execution since it changes the effective group ID to root which allows access to resources owned by group root. Signed-off-by: Djalal Harouni tetragon: detect setgid execution to root as privileged execution Execution of a binary with set-group-ID to root is handled as a privileged execution. The PRIVILEGES_RAISED_EXEC_FILE_SETGID will be set. Signed-off-by: Djalal Harouni tests: detect privileged execution of file caps binaries We use the ping binary if it is available to detect privileged execution through file caps on binaries. Signed-off-by: Djalal Harouni fix(deps): update module golang.org/x/sys to v0.16.0 Signed-off-by: cilium-renovate[bot] <134692979+cilium-renovate[bot]@users.noreply.github.com> --- .github/ISSUE_TEMPLATE/release_template.md | 2 +- .github/renovate.json5 | 4 +- .github/workflows/build-clang-image.yaml | 2 +- .github/workflows/build-images-ci.yml | 2 +- .github/workflows/build-images-releases.yml | 2 +- .github/workflows/lint-helm.yaml | 6 +- .github/workflows/vmtests.yml | 14 +- api/go.mod | 2 +- api/go.sum | 4 +- api/v1/README.md | 19 + api/v1/tetragon/capabilities.pb.go | 105 +- api/v1/tetragon/capabilities.proto | 41 + .../codegen/eventchecker/eventchecker.pb.go | 218 +++- api/v1/tetragon/tetragon.pb.go | 1030 +++++++++-------- api/v1/tetragon/tetragon.proto | 10 + api/vendor/golang.org/x/sys/unix/mkerrors.sh | 37 +- .../golang.org/x/sys/unix/zerrors_linux.go | 54 + .../x/sys/unix/zsyscall_openbsd_386.go | 2 - .../x/sys/unix/zsyscall_openbsd_amd64.go | 2 - .../x/sys/unix/zsyscall_openbsd_arm.go | 2 - .../x/sys/unix/zsyscall_openbsd_arm64.go | 2 - .../x/sys/unix/zsyscall_openbsd_mips64.go | 2 - .../x/sys/unix/zsyscall_openbsd_ppc64.go | 2 - .../x/sys/unix/zsyscall_openbsd_riscv64.go | 2 - .../x/sys/windows/syscall_windows.go | 1 + .../x/sys/windows/zsyscall_windows.go | 9 + api/vendor/modules.txt | 2 +- bpf/lib/bpf_cred.h | 34 + bpf/lib/generic.h | 3 +- bpf/lib/process.h | 4 - bpf/process/bpf_execve_bprm_commit_creds.c | 67 +- bpf/process/bpf_generic_kprobe.c | 5 +- bpf/process/bpf_generic_tracepoint.c | 6 +- bpf/process/bpf_generic_uprobe.c | 5 +- bpf/process/generic_calls.h | 6 +- bpf/process/pfilter.h | 4 + bpf/process/types/basic.h | 44 +- cmd/tetragon-vmtests-run/conf.go | 2 + cmd/tetragon-vmtests-run/main.go | 14 +- cmd/tetragon-vmtests-run/run_tests.go | 163 ++- .../api/v1/tetragon/capabilities.pb.go | 70 +- .../api/v1/tetragon/capabilities.proto | 11 + .../tetragon/api/v1/tetragon/tetragon.pb.go | 14 +- .../tetragon/api/v1/tetragon/tetragon.proto | 4 + contrib/tester-progs/Makefile | 9 +- contrib/tester-progs/drop-privileges.c | 30 + docs/content/en/docs/reference/grpc-api.md | 16 + examples/policylibrary/modules.yaml | 7 +- go.mod | 4 +- go.sum | 8 +- install/kubernetes/Makefile | 19 + install/kubernetes/test.sh | 18 - pkg/api/processapi/processapi.go | 4 + pkg/eventcache/eventcache.go | 4 - pkg/eventcache/metrics.go | 30 - pkg/grpc/tracing/tracing.go | 6 + .../v1alpha1/cilium.io_tracingpolicies.yaml | 15 + .../cilium.io_tracingpoliciesnamespaced.yaml | 15 + pkg/k8s/apis/cilium.io/v1alpha1/types.go | 12 + pkg/k8s/apis/cilium.io/v1alpha1/version.go | 2 +- pkg/k8s/go.mod | 2 +- pkg/k8s/go.sum | 4 +- .../golang.org/x/sync/errgroup/errgroup.go | 3 + pkg/k8s/vendor/modules.txt | 2 +- .../eventcachemetrics/eventcachemetrics.go | 15 + pkg/metrics/mapmetrics/mapmetrics.go | 17 +- pkg/metrics/metricsconfig/initmetrics.go | 4 - pkg/observer/observer_stats.go | 26 +- pkg/process/cache.go | 3 +- pkg/process/metrics.go | 31 - pkg/process/process.go | 17 +- pkg/reader/caps/caps.go | 26 + pkg/selectors/kernel.go | 20 - pkg/sensors/exec/exec_test.go | 320 ++++- pkg/sensors/tracing/generickprobe.go | 32 +- pkg/sensors/tracing/generictracepoint.go | 19 +- pkg/sensors/tracing/genericuprobe.go | 19 +- pkg/sensors/tracing/kprobe_test.go | 10 +- pkg/sensors/tracing/message.go | 57 + pkg/sensors/tracing/message_test.go | 29 + pkg/sensors/tracing/tracepoint_test.go | 10 +- pkg/sensors/tracing/uprobe_test.go | 7 +- pkg/vmtests/list.go | 45 +- pkg/vmtests/vmtests.go | 8 +- .../tests/policyfilter/policyfilter_test.go | 16 + tests/e2e/tests/skeleton/skeleton_test.go | 8 + .../api/v1/tetragon/capabilities.pb.go | 105 +- .../api/v1/tetragon/capabilities.proto | 41 + .../codegen/eventchecker/eventchecker.pb.go | 218 +++- .../tetragon/api/v1/tetragon/tetragon.pb.go | 1030 +++++++++-------- .../tetragon/api/v1/tetragon/tetragon.proto | 10 + .../v1alpha1/cilium.io_tracingpolicies.yaml | 15 + .../cilium.io_tracingpoliciesnamespaced.yaml | 15 + .../pkg/k8s/apis/cilium.io/v1alpha1/types.go | 12 + .../k8s/apis/cilium.io/v1alpha1/version.go | 2 +- vendor/golang.org/x/sync/errgroup/errgroup.go | 3 + vendor/golang.org/x/sys/unix/mkerrors.sh | 37 +- vendor/golang.org/x/sys/unix/zerrors_linux.go | 54 + .../x/sys/unix/zsyscall_openbsd_386.go | 2 - .../x/sys/unix/zsyscall_openbsd_amd64.go | 2 - .../x/sys/unix/zsyscall_openbsd_arm.go | 2 - .../x/sys/unix/zsyscall_openbsd_arm64.go | 2 - .../x/sys/unix/zsyscall_openbsd_mips64.go | 2 - .../x/sys/unix/zsyscall_openbsd_ppc64.go | 2 - .../x/sys/unix/zsyscall_openbsd_riscv64.go | 2 - .../x/sys/windows/syscall_windows.go | 1 + .../x/sys/windows/zsyscall_windows.go | 9 + vendor/modules.txt | 4 +- 108 files changed, 3152 insertions(+), 1401 deletions(-) create mode 100644 contrib/tester-progs/drop-privileges.c create mode 100644 install/kubernetes/Makefile delete mode 100755 install/kubernetes/test.sh delete mode 100644 pkg/eventcache/metrics.go delete mode 100644 pkg/process/metrics.go create mode 100644 pkg/sensors/tracing/message.go create mode 100644 pkg/sensors/tracing/message_test.go diff --git a/.github/ISSUE_TEMPLATE/release_template.md b/.github/ISSUE_TEMPLATE/release_template.md index cd7ef62152a..4e515094318 100644 --- a/.github/ISSUE_TEMPLATE/release_template.md +++ b/.github/ISSUE_TEMPLATE/release_template.md @@ -18,7 +18,7 @@ assignees: '' git checkout -b pr/prepare-$RELEASE ./contrib/update-helm-chart.sh $RELEASE - ./install/kubernetes/test.sh + make -C install/kubernetes git add install/kubernetes/tetragon/ # update hugo version sed -i "s/^version =.*/version = \"${RELEASE}\"/" docs/hugo.toml diff --git a/.github/renovate.json5 b/.github/renovate.json5 index d88e5a9c8ac..35bc574582e 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -13,7 +13,7 @@ "^make codegen$", "^make generate$", "^make vendor$", - "^install/kubernetes/test.sh$", + "^make -C install/kubernetes$", "^go mod vendor$", "^install-tool golang \\$\\(grep -oP '\\^go \\\\K\\.\\+' go\\.mod\\)$" ], @@ -240,7 +240,7 @@ ], // lint and generate files for helm chart "postUpgradeTasks": { - "commands": ["install/kubernetes/test.sh"], + "commands": ["make -C install/kubernetes"], "fileFilters": ["**/**"], "executionMode": "branch" } diff --git a/.github/workflows/build-clang-image.yaml b/.github/workflows/build-clang-image.yaml index a370c05b6aa..04e0cca20a5 100644 --- a/.github/workflows/build-clang-image.yaml +++ b/.github/workflows/build-clang-image.yaml @@ -127,7 +127,7 @@ jobs: shell: bash env: # renovate: datasource=github-releases depName=kubernetes-sigs/bom - BOM_VERSION: v0.5.1 + BOM_VERSION: f0ff48f9a202abfddf656056bbeeb8efe29920ab run: | go install sigs.k8s.io/bom/cmd/bom@${{ env.BOM_VERSION }} diff --git a/.github/workflows/build-images-ci.yml b/.github/workflows/build-images-ci.yml index 8254da37f9c..889657cbc19 100644 --- a/.github/workflows/build-images-ci.yml +++ b/.github/workflows/build-images-ci.yml @@ -100,7 +100,7 @@ jobs: shell: bash env: # renovate: datasource=github-releases depName=kubernetes-sigs/bom - BOM_VERSION: v0.5.1 + BOM_VERSION: f0ff48f9a202abfddf656056bbeeb8efe29920ab run: | go install sigs.k8s.io/bom/cmd/bom@${{ env.BOM_VERSION }} diff --git a/.github/workflows/build-images-releases.yml b/.github/workflows/build-images-releases.yml index 156a015cc4d..0c0414188b6 100644 --- a/.github/workflows/build-images-releases.yml +++ b/.github/workflows/build-images-releases.yml @@ -98,7 +98,7 @@ jobs: shell: bash env: # renovate: datasource=github-releases depName=kubernetes-sigs/bom - BOM_VERSION: v0.5.1 + BOM_VERSION: f0ff48f9a202abfddf656056bbeeb8efe29920ab run: | go install sigs.k8s.io/bom/cmd/bom@${{ env.BOM_VERSION }} diff --git a/.github/workflows/lint-helm.yaml b/.github/workflows/lint-helm.yaml index 6e09163891d..d320dbedac5 100644 --- a/.github/workflows/lint-helm.yaml +++ b/.github/workflows/lint-helm.yaml @@ -15,13 +15,13 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - - name: Run install/kubernetes/test.sh + - name: Run install/kubernetes run: | - install/kubernetes/test.sh + make -C install/kubernetes - name: Validate generated files run: | test -z "$(git status --porcelain)" if [ $? != 0 ]; then git status --porcelain - echo "Please run 'install/kubernetes/test.sh' and submit your changes."; exit 1 + echo "Please run 'make -C install/kubernetes' and submit your changes."; exit 1 fi diff --git a/.github/workflows/vmtests.yml b/.github/workflows/vmtests.yml index 644d4f451ed..ddaf84a0c2f 100644 --- a/.github/workflows/vmtests.yml +++ b/.github/workflows/vmtests.yml @@ -66,17 +66,17 @@ jobs: matrix: kernel: # renovate: datasource=docker depName=quay.io/lvh-images/kernel-images - - 'bpf-next-20231215.012940' + - 'bpf-next-20240108.012952' # renovate: datasource=docker depName=quay.io/lvh-images/kernel-images - - '6.1-20231128.100518' + - '6.1-20231220.153727' # renovate: datasource=docker depName=quay.io/lvh-images/kernel-images - - '5.15-20231128.100518' + - '5.15-20231220.153727' # renovate: datasource=docker depName=quay.io/lvh-images/kernel-images - - '5.10-20231128.100518' + - '5.10-20231220.153727' # renovate: datasource=docker depName=quay.io/lvh-images/kernel-images - - '5.4-20231128.100518' + - '5.4-20231220.153727' # renovate: datasource=docker depName=quay.io/lvh-images/kernel-images - - '4.19-20231128.100518' + - '4.19-20231220.153727' group: - 0 concurrency: @@ -119,6 +119,7 @@ jobs: --kernel ${kimage} \ --kernel-ver ${{ matrix.kernel }} \ --base tests/vmtests/test-data/images/base.qcow2 \ + --enable-detailed-results \ --testsfile ./tests/vmtests/test-group-${{ matrix.group }} - name: test kernel ${{ matrix.kernel }} with btf file @@ -134,6 +135,7 @@ jobs: --kernel-ver ${{ matrix.kernel }} \ --btf-file ${btf} \ --base tests/vmtests/test-data/images/base.qcow2 \ + --enable-detailed-results \ --testsfile ./tests/vmtests/test-group-${{ matrix.group }} - name: Chmod test results on failure or cancelation diff --git a/api/go.mod b/api/go.mod index 05db814a27e..29a4de6ab3d 100644 --- a/api/go.mod +++ b/api/go.mod @@ -17,7 +17,7 @@ require ( github.com/golang/protobuf v1.5.3 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect golang.org/x/net v0.19.0 // indirect - golang.org/x/sys v0.15.0 // indirect + golang.org/x/sys v0.16.0 // indirect golang.org/x/text v0.14.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20231127180814-3a041ad873d4 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect diff --git a/api/go.sum b/api/go.sum index db1d1386557..4b8cfc6413b 100644 --- a/api/go.sum +++ b/api/go.sum @@ -30,8 +30,8 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/api/v1/README.md b/api/v1/README.md index 5a3a00be65a..4352fa6ba01 100644 --- a/api/v1/README.md +++ b/api/v1/README.md @@ -5,6 +5,7 @@ - [tetragon/capabilities.proto](#tetragon_capabilities-proto) - [CapabilitiesType](#tetragon-CapabilitiesType) + - [ProcessPrivilegesChanged](#tetragon-ProcessPrivilegesChanged) - [SecureBitsType](#tetragon-SecureBitsType) - [tetragon/tetragon.proto](#tetragon_tetragon-proto) @@ -163,6 +164,20 @@ + + +### ProcessPrivilegesChanged +Reasons of why the process privileges changed. + +| Name | Number | Description | +| ---- | ------ | ----------- | +| PRIVILEGES_CHANGED_UNSET | 0 | | +| PRIVILEGES_RAISED_EXEC_FILE_CAP | 1 | A privilege elevation happened due to the execution of a binary with file capability sets. The kernel supports associating capability sets with an executable file using `setcap` command. The file capability sets are stored in an extended attribute (see https://man7.org/linux/man-pages/man7/xattr.7.html) named `security.capability`. The file capability sets, in conjunction with the capability sets of the process, determine the process capabilities and privileges after the `execve` system call. For further reference, please check sections `File capability extended attribute versioning` and `Namespaced file capabilities` of the capabilities man pages: https://man7.org/linux/man-pages/man7/capabilities.7.html. The new granted capabilities can be listed inside the `process` object. | +| PRIVILEGES_RAISED_EXEC_FILE_SETUID | 2 | A privilege elevation happened due to the execution of a binary with set-user-ID to root. When a process with nonzero UIDs executes a binary with a set-user-ID to root also known as suid-root executable, then the kernel switches the effective user ID to 0 (root) which is a privilege elevation operation since it grants access to resources owned by the root user. The effective user ID is listed inside the `process_credentials` part of the `process` object. For further reading, section `Capabilities and execution of programs by root` of https://man7.org/linux/man-pages/man7/capabilities.7.html. Afterward the kernel recalculates the capability sets of the process and grants all capabilities in the permitted and effective capability sets, except those masked out by the capability bounding set. If the binary also have file capability sets then these bits are honored and the process gains just the capabilities granted by the file capability sets (i.e., not all capabilities, as it would occur when executing a set-user-ID to root binary that does not have any associated file capabilities). This is described in section `Set-user-ID-root programs that have file capabilities` of https://man7.org/linux/man-pages/man7/capabilities.7.html. The new granted capabilities can be listed inside the `process` object. There is one exception for the special treatments of set-user-ID to root execution receiving all capabilities, if the `SecBitNoRoot` bit of the Secure bits is set, then the kernel does not grant any capability. Please check section: `The securebits flags: establishing a capabilities-only environment` of the capabilities man pages: https://man7.org/linux/man-pages/man7/capabilities.7.html | +| PRIVILEGES_RAISED_EXEC_FILE_SETGID | 3 | A privilege elevation happened due to the execution of a binary with set-group-ID to root. When a process with nonzero GIDs executes a binary with a set-group-ID to root, the kernel switches the effective group ID to 0 (root) which is a privilege elevation operation since it grants access to resources owned by the root group. The effective group ID is listed inside the `process_credentials` part of the `process` object. | + + + ### SecureBitsType @@ -206,6 +221,7 @@ | ----- | ---- | ----- | ----------- | | setuid | [google.protobuf.UInt32Value](#google-protobuf-UInt32Value) | | If set then this is the set user ID used for execution | | setgid | [google.protobuf.UInt32Value](#google-protobuf-UInt32Value) | | If set then this is the set group ID used for execution | +| privileges_changed | [ProcessPrivilegesChanged](#tetragon-ProcessPrivilegesChanged) | repeated | The reasons why this binary execution changed privileges. Usually this happens when the process executes a binary with the set-user-ID to root or file capability sets. The final granted privileges can be listed inside the `process_credentials` or capabilities fields part of of the `process` object. | @@ -793,6 +809,7 @@ https://github.com/opencontainers/runtime-spec/blob/main/config.md#createcontain | stack_trace | [StackTraceEntry](#tetragon-StackTraceEntry) | repeated | Kernel stack trace to the call. | | policy_name | [string](#string) | | Name of the Tracing Policy that created that kprobe. | | return_action | [KprobeAction](#tetragon-KprobeAction) | | Action performed when the return kprobe executed. | +| message | [string](#string) | | Short message of the Tracing Policy to inform users what is going on. | @@ -831,6 +848,7 @@ loader sensor event triggered for loaded binary/library | args | [KprobeArgument](#tetragon-KprobeArgument) | repeated | Arguments definition of the observed tracepoint. TODO: once we implement all we want, rename KprobeArgument to GenericArgument | | policy_name | [string](#string) | | Name of the policy that created that tracepoint. | | action | [KprobeAction](#tetragon-KprobeAction) | | Action performed when the tracepoint matched. | +| message | [string](#string) | | Short message of the Tracing Policy to inform users what is going on. | @@ -850,6 +868,7 @@ loader sensor event triggered for loaded binary/library | path | [string](#string) | | | | symbol | [string](#string) | | | | policy_name | [string](#string) | | Name of the policy that created that uprobe. | +| message | [string](#string) | | Short message of the Tracing Policy to inform users what is going on. | diff --git a/api/v1/tetragon/capabilities.pb.go b/api/v1/tetragon/capabilities.pb.go index be5ac6df28b..2663ed583b5 100644 --- a/api/v1/tetragon/capabilities.pb.go +++ b/api/v1/tetragon/capabilities.pb.go @@ -373,6 +373,89 @@ func (SecureBitsType) EnumDescriptor() ([]byte, []int) { return file_tetragon_capabilities_proto_rawDescGZIP(), []int{1} } +// Reasons of why the process privileges changed. +type ProcessPrivilegesChanged int32 + +const ( + ProcessPrivilegesChanged_PRIVILEGES_CHANGED_UNSET ProcessPrivilegesChanged = 0 + // A privilege elevation happened due to the execution of a binary with file capability sets. + // The kernel supports associating capability sets with an executable file using `setcap` command. + // The file capability sets are stored in an extended attribute (see https://man7.org/linux/man-pages/man7/xattr.7.html) + // named `security.capability`. The file capability sets, in conjunction with the capability sets + // of the process, determine the process capabilities and privileges after the `execve` system call. + // For further reference, please check sections `File capability extended attribute versioning` and + // `Namespaced file capabilities` of the capabilities man pages: https://man7.org/linux/man-pages/man7/capabilities.7.html. + // The new granted capabilities can be listed inside the `process` object. + ProcessPrivilegesChanged_PRIVILEGES_RAISED_EXEC_FILE_CAP ProcessPrivilegesChanged = 1 + // A privilege elevation happened due to the execution of a binary with set-user-ID to root. + // When a process with nonzero UIDs executes a binary with a set-user-ID to root also + // known as suid-root executable, then the kernel switches the effective user ID to 0 (root) which + // is a privilege elevation operation since it grants access to resources owned by the root user. + // The effective user ID is listed inside the `process_credentials` part of the `process` object. + // For further reading, section `Capabilities and execution of programs by root` of https://man7.org/linux/man-pages/man7/capabilities.7.html. + // Afterward the kernel recalculates the capability sets of the process and grants all capabilities + // in the permitted and effective capability sets, except those masked out by the capability bounding set. + // If the binary also have file capability sets then these bits are honored and the process gains just + // the capabilities granted by the file capability sets (i.e., not all capabilities, as it would occur + // when executing a set-user-ID to root binary that does not have any associated file capabilities). This + // is described in section `Set-user-ID-root programs that have file capabilities` of https://man7.org/linux/man-pages/man7/capabilities.7.html. + // The new granted capabilities can be listed inside the `process` object. + // There is one exception for the special treatments of set-user-ID to root execution receiving all + // capabilities, if the `SecBitNoRoot` bit of the Secure bits is set, then the kernel does not grant + // any capability. Please check section: `The securebits flags: establishing a capabilities-only environment` + // of the capabilities man pages: https://man7.org/linux/man-pages/man7/capabilities.7.html + ProcessPrivilegesChanged_PRIVILEGES_RAISED_EXEC_FILE_SETUID ProcessPrivilegesChanged = 2 + // A privilege elevation happened due to the execution of a binary with set-group-ID to root. + // When a process with nonzero GIDs executes a binary with a set-group-ID to root, the kernel switches + // the effective group ID to 0 (root) which is a privilege elevation operation since it grants access to + // resources owned by the root group. + // The effective group ID is listed inside the `process_credentials` part of the `process` object. + ProcessPrivilegesChanged_PRIVILEGES_RAISED_EXEC_FILE_SETGID ProcessPrivilegesChanged = 3 +) + +// Enum value maps for ProcessPrivilegesChanged. +var ( + ProcessPrivilegesChanged_name = map[int32]string{ + 0: "PRIVILEGES_CHANGED_UNSET", + 1: "PRIVILEGES_RAISED_EXEC_FILE_CAP", + 2: "PRIVILEGES_RAISED_EXEC_FILE_SETUID", + 3: "PRIVILEGES_RAISED_EXEC_FILE_SETGID", + } + ProcessPrivilegesChanged_value = map[string]int32{ + "PRIVILEGES_CHANGED_UNSET": 0, + "PRIVILEGES_RAISED_EXEC_FILE_CAP": 1, + "PRIVILEGES_RAISED_EXEC_FILE_SETUID": 2, + "PRIVILEGES_RAISED_EXEC_FILE_SETGID": 3, + } +) + +func (x ProcessPrivilegesChanged) Enum() *ProcessPrivilegesChanged { + p := new(ProcessPrivilegesChanged) + *p = x + return p +} + +func (x ProcessPrivilegesChanged) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ProcessPrivilegesChanged) Descriptor() protoreflect.EnumDescriptor { + return file_tetragon_capabilities_proto_enumTypes[2].Descriptor() +} + +func (ProcessPrivilegesChanged) Type() protoreflect.EnumType { + return &file_tetragon_capabilities_proto_enumTypes[2] +} + +func (x ProcessPrivilegesChanged) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ProcessPrivilegesChanged.Descriptor instead. +func (ProcessPrivilegesChanged) EnumDescriptor() ([]byte, []int) { + return file_tetragon_capabilities_proto_rawDescGZIP(), []int{2} +} + var File_tetragon_capabilities_proto protoreflect.FileDescriptor var file_tetragon_capabilities_proto_rawDesc = []byte{ @@ -444,7 +527,18 @@ var file_tetragon_capabilities_proto_rawDesc = []byte{ 0x61, 0x70, 0x41, 0x6d, 0x62, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x61, 0x69, 0x73, 0x65, 0x10, 0x40, 0x12, 0x22, 0x0a, 0x1d, 0x53, 0x65, 0x63, 0x42, 0x69, 0x74, 0x4e, 0x6f, 0x43, 0x61, 0x70, 0x41, 0x6d, 0x62, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x61, 0x69, 0x73, 0x65, 0x4c, 0x6f, 0x63, 0x6b, 0x65, - 0x64, 0x10, 0x80, 0x01, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x64, 0x10, 0x80, 0x01, 0x2a, 0xad, 0x01, 0x0a, 0x18, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, + 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x64, 0x12, 0x1c, 0x0a, 0x18, 0x50, 0x52, 0x49, 0x56, 0x49, 0x4c, 0x45, 0x47, 0x45, 0x53, 0x5f, + 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x45, 0x54, 0x10, 0x00, 0x12, + 0x23, 0x0a, 0x1f, 0x50, 0x52, 0x49, 0x56, 0x49, 0x4c, 0x45, 0x47, 0x45, 0x53, 0x5f, 0x52, 0x41, + 0x49, 0x53, 0x45, 0x44, 0x5f, 0x45, 0x58, 0x45, 0x43, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x5f, 0x43, + 0x41, 0x50, 0x10, 0x01, 0x12, 0x26, 0x0a, 0x22, 0x50, 0x52, 0x49, 0x56, 0x49, 0x4c, 0x45, 0x47, + 0x45, 0x53, 0x5f, 0x52, 0x41, 0x49, 0x53, 0x45, 0x44, 0x5f, 0x45, 0x58, 0x45, 0x43, 0x5f, 0x46, + 0x49, 0x4c, 0x45, 0x5f, 0x53, 0x45, 0x54, 0x55, 0x49, 0x44, 0x10, 0x02, 0x12, 0x26, 0x0a, 0x22, + 0x50, 0x52, 0x49, 0x56, 0x49, 0x4c, 0x45, 0x47, 0x45, 0x53, 0x5f, 0x52, 0x41, 0x49, 0x53, 0x45, + 0x44, 0x5f, 0x45, 0x58, 0x45, 0x43, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x5f, 0x53, 0x45, 0x54, 0x47, + 0x49, 0x44, 0x10, 0x03, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -459,10 +553,11 @@ func file_tetragon_capabilities_proto_rawDescGZIP() []byte { return file_tetragon_capabilities_proto_rawDescData } -var file_tetragon_capabilities_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_tetragon_capabilities_proto_enumTypes = make([]protoimpl.EnumInfo, 3) var file_tetragon_capabilities_proto_goTypes = []interface{}{ - (CapabilitiesType)(0), // 0: tetragon.CapabilitiesType - (SecureBitsType)(0), // 1: tetragon.SecureBitsType + (CapabilitiesType)(0), // 0: tetragon.CapabilitiesType + (SecureBitsType)(0), // 1: tetragon.SecureBitsType + (ProcessPrivilegesChanged)(0), // 2: tetragon.ProcessPrivilegesChanged } var file_tetragon_capabilities_proto_depIdxs = []int32{ 0, // [0:0] is the sub-list for method output_type @@ -482,7 +577,7 @@ func file_tetragon_capabilities_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_tetragon_capabilities_proto_rawDesc, - NumEnums: 2, + NumEnums: 3, NumMessages: 0, NumExtensions: 0, NumServices: 0, diff --git a/api/v1/tetragon/capabilities.proto b/api/v1/tetragon/capabilities.proto index 9b097083a2f..c453a534f44 100644 --- a/api/v1/tetragon/capabilities.proto +++ b/api/v1/tetragon/capabilities.proto @@ -306,3 +306,44 @@ enum SecureBitsType { /* Make bit-6 SecBitNoCapAmbientRaise immutable */ SecBitNoCapAmbientRaiseLocked = 128; } + +// Reasons of why the process privileges changed. +enum ProcessPrivilegesChanged { + PRIVILEGES_CHANGED_UNSET = 0; + + // A privilege elevation happened due to the execution of a binary with file capability sets. + // The kernel supports associating capability sets with an executable file using `setcap` command. + // The file capability sets are stored in an extended attribute (see https://man7.org/linux/man-pages/man7/xattr.7.html) + // named `security.capability`. The file capability sets, in conjunction with the capability sets + // of the process, determine the process capabilities and privileges after the `execve` system call. + // For further reference, please check sections `File capability extended attribute versioning` and + // `Namespaced file capabilities` of the capabilities man pages: https://man7.org/linux/man-pages/man7/capabilities.7.html. + // The new granted capabilities can be listed inside the `process` object. + PRIVILEGES_RAISED_EXEC_FILE_CAP = 1; + + // A privilege elevation happened due to the execution of a binary with set-user-ID to root. + // When a process with nonzero UIDs executes a binary with a set-user-ID to root also + // known as suid-root executable, then the kernel switches the effective user ID to 0 (root) which + // is a privilege elevation operation since it grants access to resources owned by the root user. + // The effective user ID is listed inside the `process_credentials` part of the `process` object. + // For further reading, section `Capabilities and execution of programs by root` of https://man7.org/linux/man-pages/man7/capabilities.7.html. + // Afterward the kernel recalculates the capability sets of the process and grants all capabilities + // in the permitted and effective capability sets, except those masked out by the capability bounding set. + // If the binary also have file capability sets then these bits are honored and the process gains just + // the capabilities granted by the file capability sets (i.e., not all capabilities, as it would occur + // when executing a set-user-ID to root binary that does not have any associated file capabilities). This + // is described in section `Set-user-ID-root programs that have file capabilities` of https://man7.org/linux/man-pages/man7/capabilities.7.html. + // The new granted capabilities can be listed inside the `process` object. + // There is one exception for the special treatments of set-user-ID to root execution receiving all + // capabilities, if the `SecBitNoRoot` bit of the Secure bits is set, then the kernel does not grant + // any capability. Please check section: `The securebits flags: establishing a capabilities-only environment` + // of the capabilities man pages: https://man7.org/linux/man-pages/man7/capabilities.7.html + PRIVILEGES_RAISED_EXEC_FILE_SETUID = 2; + + // A privilege elevation happened due to the execution of a binary with set-group-ID to root. + // When a process with nonzero GIDs executes a binary with a set-group-ID to root, the kernel switches + // the effective group ID to 0 (root) which is a privilege elevation operation since it grants access to + // resources owned by the root group. + // The effective group ID is listed inside the `process_credentials` part of the `process` object. + PRIVILEGES_RAISED_EXEC_FILE_SETGID = 3; +} diff --git a/api/v1/tetragon/codegen/eventchecker/eventchecker.pb.go b/api/v1/tetragon/codegen/eventchecker/eventchecker.pb.go index f7767721367..e2eb02f785f 100644 --- a/api/v1/tetragon/codegen/eventchecker/eventchecker.pb.go +++ b/api/v1/tetragon/codegen/eventchecker/eventchecker.pb.go @@ -706,6 +706,7 @@ type ProcessKprobeChecker struct { StackTrace *StackTraceEntryListMatcher `json:"stackTrace,omitempty"` PolicyName *stringmatcher.StringMatcher `json:"policyName,omitempty"` ReturnAction *KprobeActionChecker `json:"returnAction,omitempty"` + Message *stringmatcher.StringMatcher `json:"message,omitempty"` } // CheckEvent checks a single event and implements the EventChecker interface @@ -792,6 +793,11 @@ func (checker *ProcessKprobeChecker) Check(event *tetragon.ProcessKprobe) error return fmt.Errorf("ReturnAction check failed: %w", err) } } + if checker.Message != nil { + if err := checker.Message.Match(event.Message); err != nil { + return fmt.Errorf("Message check failed: %w", err) + } + } return nil } if err := fieldChecks(); err != nil { @@ -856,6 +862,12 @@ func (checker *ProcessKprobeChecker) WithReturnAction(check tetragon.KprobeActio return checker } +// WithMessage adds a Message check to the ProcessKprobeChecker +func (checker *ProcessKprobeChecker) WithMessage(check *stringmatcher.StringMatcher) *ProcessKprobeChecker { + checker.Message = check + return checker +} + //FromProcessKprobe populates the ProcessKprobeChecker using data from a ProcessKprobe event func (checker *ProcessKprobeChecker) FromProcessKprobe(event *tetragon.ProcessKprobe) *ProcessKprobeChecker { if event == nil { @@ -900,6 +912,7 @@ func (checker *ProcessKprobeChecker) FromProcessKprobe(event *tetragon.ProcessKp } checker.PolicyName = stringmatcher.Full(event.PolicyName) checker.ReturnAction = NewKprobeActionChecker(event.ReturnAction) + checker.Message = stringmatcher.Full(event.Message) return checker } @@ -1113,6 +1126,7 @@ type ProcessTracepointChecker struct { Args *KprobeArgumentListMatcher `json:"args,omitempty"` PolicyName *stringmatcher.StringMatcher `json:"policyName,omitempty"` Action *KprobeActionChecker `json:"action,omitempty"` + Message *stringmatcher.StringMatcher `json:"message,omitempty"` } // CheckEvent checks a single event and implements the EventChecker interface @@ -1189,6 +1203,11 @@ func (checker *ProcessTracepointChecker) Check(event *tetragon.ProcessTracepoint return fmt.Errorf("Action check failed: %w", err) } } + if checker.Message != nil { + if err := checker.Message.Match(event.Message); err != nil { + return fmt.Errorf("Message check failed: %w", err) + } + } return nil } if err := fieldChecks(); err != nil { @@ -1240,6 +1259,12 @@ func (checker *ProcessTracepointChecker) WithAction(check tetragon.KprobeAction) return checker } +// WithMessage adds a Message check to the ProcessTracepointChecker +func (checker *ProcessTracepointChecker) WithMessage(check *stringmatcher.StringMatcher) *ProcessTracepointChecker { + checker.Message = check + return checker +} + //FromProcessTracepoint populates the ProcessTracepointChecker using data from a ProcessTracepoint event func (checker *ProcessTracepointChecker) FromProcessTracepoint(event *tetragon.ProcessTracepoint) *ProcessTracepointChecker { if event == nil { @@ -1268,6 +1293,7 @@ func (checker *ProcessTracepointChecker) FromProcessTracepoint(event *tetragon.P } checker.PolicyName = stringmatcher.Full(event.PolicyName) checker.Action = NewKprobeActionChecker(event.Action) + checker.Message = stringmatcher.Full(event.Message) return checker } @@ -1279,6 +1305,7 @@ type ProcessUprobeChecker struct { Path *stringmatcher.StringMatcher `json:"path,omitempty"` Symbol *stringmatcher.StringMatcher `json:"symbol,omitempty"` PolicyName *stringmatcher.StringMatcher `json:"policyName,omitempty"` + Message *stringmatcher.StringMatcher `json:"message,omitempty"` } // CheckEvent checks a single event and implements the EventChecker interface @@ -1345,6 +1372,11 @@ func (checker *ProcessUprobeChecker) Check(event *tetragon.ProcessUprobe) error return fmt.Errorf("PolicyName check failed: %w", err) } } + if checker.Message != nil { + if err := checker.Message.Match(event.Message); err != nil { + return fmt.Errorf("Message check failed: %w", err) + } + } return nil } if err := fieldChecks(); err != nil { @@ -1383,6 +1415,12 @@ func (checker *ProcessUprobeChecker) WithPolicyName(check *stringmatcher.StringM return checker } +// WithMessage adds a Message check to the ProcessUprobeChecker +func (checker *ProcessUprobeChecker) WithMessage(check *stringmatcher.StringMatcher) *ProcessUprobeChecker { + checker.Message = check + return checker +} + //FromProcessUprobe populates the ProcessUprobeChecker using data from a ProcessUprobe event func (checker *ProcessUprobeChecker) FromProcessUprobe(event *tetragon.ProcessUprobe) *ProcessUprobeChecker { if event == nil { @@ -1397,6 +1435,7 @@ func (checker *ProcessUprobeChecker) FromProcessUprobe(event *tetragon.ProcessUp checker.Path = stringmatcher.Full(event.Path) checker.Symbol = stringmatcher.Full(event.Symbol) checker.PolicyName = stringmatcher.Full(event.PolicyName) + checker.Message = stringmatcher.Full(event.Message) return checker } @@ -2943,8 +2982,9 @@ nextCheck: // BinaryPropertiesChecker implements a checker struct to check a BinaryProperties field type BinaryPropertiesChecker struct { - Setuid *uint32 `json:"setuid,omitempty"` - Setgid *uint32 `json:"setgid,omitempty"` + Setuid *uint32 `json:"setuid,omitempty"` + Setgid *uint32 `json:"setgid,omitempty"` + PrivilegesChanged *ProcessPrivilegesChangedListMatcher `json:"privilegesChanged,omitempty"` } // NewBinaryPropertiesChecker creates a new BinaryPropertiesChecker @@ -2980,6 +3020,11 @@ func (checker *BinaryPropertiesChecker) Check(event *tetragon.BinaryProperties) return fmt.Errorf("Setgid has value %v which does not match expected value %v", event.Setgid.Value, *checker.Setgid) } } + if checker.PrivilegesChanged != nil { + if err := checker.PrivilegesChanged.Check(event.PrivilegesChanged); err != nil { + return fmt.Errorf("PrivilegesChanged check failed: %w", err) + } + } return nil } if err := fieldChecks(); err != nil { @@ -3000,6 +3045,12 @@ func (checker *BinaryPropertiesChecker) WithSetgid(check uint32) *BinaryProperti return checker } +// WithPrivilegesChanged adds a PrivilegesChanged check to the BinaryPropertiesChecker +func (checker *BinaryPropertiesChecker) WithPrivilegesChanged(check *ProcessPrivilegesChangedListMatcher) *BinaryPropertiesChecker { + checker.PrivilegesChanged = check + return checker +} + //FromBinaryProperties populates the BinaryPropertiesChecker using data from a BinaryProperties field func (checker *BinaryPropertiesChecker) FromBinaryProperties(event *tetragon.BinaryProperties) *BinaryPropertiesChecker { if event == nil { @@ -3013,9 +3064,120 @@ func (checker *BinaryPropertiesChecker) FromBinaryProperties(event *tetragon.Bin val := event.Setgid.Value checker.Setgid = &val } + { + var checks []*ProcessPrivilegesChangedChecker + for _, check := range event.PrivilegesChanged { + var convertedCheck *ProcessPrivilegesChangedChecker + convertedCheck = NewProcessPrivilegesChangedChecker(check) + checks = append(checks, convertedCheck) + } + lm := NewProcessPrivilegesChangedListMatcher().WithOperator(listmatcher.Ordered). + WithValues(checks...) + checker.PrivilegesChanged = lm + } return checker } +// ProcessPrivilegesChangedListMatcher checks a list of tetragon.ProcessPrivilegesChanged fields +type ProcessPrivilegesChangedListMatcher struct { + Operator listmatcher.Operator `json:"operator"` + Values []*ProcessPrivilegesChangedChecker `json:"values"` +} + +// NewProcessPrivilegesChangedListMatcher creates a new ProcessPrivilegesChangedListMatcher. The checker defaults to a subset checker unless otherwise specified using WithOperator() +func NewProcessPrivilegesChangedListMatcher() *ProcessPrivilegesChangedListMatcher { + return &ProcessPrivilegesChangedListMatcher{ + Operator: listmatcher.Subset, + } +} + +// WithOperator sets the match kind for the ProcessPrivilegesChangedListMatcher +func (checker *ProcessPrivilegesChangedListMatcher) WithOperator(operator listmatcher.Operator) *ProcessPrivilegesChangedListMatcher { + checker.Operator = operator + return checker +} + +// WithValues sets the checkers that the ProcessPrivilegesChangedListMatcher should use +func (checker *ProcessPrivilegesChangedListMatcher) WithValues(values ...*ProcessPrivilegesChangedChecker) *ProcessPrivilegesChangedListMatcher { + checker.Values = values + return checker +} + +// Check checks a list of tetragon.ProcessPrivilegesChanged fields +func (checker *ProcessPrivilegesChangedListMatcher) Check(values []tetragon.ProcessPrivilegesChanged) error { + switch checker.Operator { + case listmatcher.Ordered: + return checker.orderedCheck(values) + case listmatcher.Unordered: + return checker.unorderedCheck(values) + case listmatcher.Subset: + return checker.subsetCheck(values) + default: + return fmt.Errorf("Unhandled ListMatcher operator %s", checker.Operator) + } +} + +// orderedCheck checks a list of ordered tetragon.ProcessPrivilegesChanged fields +func (checker *ProcessPrivilegesChangedListMatcher) orderedCheck(values []tetragon.ProcessPrivilegesChanged) error { + innerCheck := func(check *ProcessPrivilegesChangedChecker, value tetragon.ProcessPrivilegesChanged) error { + if err := check.Check(&value); err != nil { + return fmt.Errorf("PrivilegesChanged check failed: %w", err) + } + return nil + } + + if len(checker.Values) != len(values) { + return fmt.Errorf("ProcessPrivilegesChangedListMatcher: Wanted %d elements, got %d", len(checker.Values), len(values)) + } + + for i, check := range checker.Values { + value := values[i] + if err := innerCheck(check, value); err != nil { + return fmt.Errorf("ProcessPrivilegesChangedListMatcher: Check failed on element %d: %w", i, err) + } + } + + return nil +} + +// unorderedCheck checks a list of unordered tetragon.ProcessPrivilegesChanged fields +func (checker *ProcessPrivilegesChangedListMatcher) unorderedCheck(values []tetragon.ProcessPrivilegesChanged) error { + if len(checker.Values) != len(values) { + return fmt.Errorf("ProcessPrivilegesChangedListMatcher: Wanted %d elements, got %d", len(checker.Values), len(values)) + } + + return checker.subsetCheck(values) +} + +// subsetCheck checks a subset of tetragon.ProcessPrivilegesChanged fields +func (checker *ProcessPrivilegesChangedListMatcher) subsetCheck(values []tetragon.ProcessPrivilegesChanged) error { + innerCheck := func(check *ProcessPrivilegesChangedChecker, value tetragon.ProcessPrivilegesChanged) error { + if err := check.Check(&value); err != nil { + return fmt.Errorf("PrivilegesChanged check failed: %w", err) + } + return nil + } + + numDesired := len(checker.Values) + numMatched := 0 + +nextCheck: + for _, check := range checker.Values { + for _, value := range values { + if err := innerCheck(check, value); err == nil { + numMatched += 1 + continue nextCheck + } + } + } + + if numMatched < numDesired { + return fmt.Errorf("ProcessPrivilegesChangedListMatcher: Check failed, only matched %d elements but wanted %d", numMatched, numDesired) + } + + return nil +} + // ProcessChecker implements a checker struct to check a Process field type ProcessChecker struct { ExecId *stringmatcher.StringMatcher `json:"execId,omitempty"` @@ -5428,6 +5590,58 @@ func (enum *SecureBitsTypeChecker) Check(val *tetragon.SecureBitsType) error { return nil } +// ProcessPrivilegesChangedChecker checks a tetragon.ProcessPrivilegesChanged +type ProcessPrivilegesChangedChecker tetragon.ProcessPrivilegesChanged + +// MarshalJSON implements json.Marshaler interface +func (enum ProcessPrivilegesChangedChecker) MarshalJSON() ([]byte, error) { + if name, ok := tetragon.ProcessPrivilegesChanged_name[int32(enum)]; ok { + name = strings.TrimPrefix(name, "PRIVILEGES_") + return json.Marshal(name) + } + + return nil, fmt.Errorf("Unknown ProcessPrivilegesChanged %d", enum) +} + +// UnmarshalJSON implements json.Unmarshaler interface +func (enum *ProcessPrivilegesChangedChecker) UnmarshalJSON(b []byte) error { + var str string + if err := yaml.UnmarshalStrict(b, &str); err != nil { + return err + } + + // Convert to uppercase if not already + str = strings.ToUpper(str) + + // Look up the value from the enum values map + if n, ok := tetragon.ProcessPrivilegesChanged_value[str]; ok { + *enum = ProcessPrivilegesChangedChecker(n) + } else if n, ok := tetragon.ProcessPrivilegesChanged_value["PRIVILEGES_"+str]; ok { + *enum = ProcessPrivilegesChangedChecker(n) + } else { + return fmt.Errorf("Unknown ProcessPrivilegesChanged %s", str) + } + + return nil +} + +// NewProcessPrivilegesChangedChecker creates a new ProcessPrivilegesChangedChecker +func NewProcessPrivilegesChangedChecker(val tetragon.ProcessPrivilegesChanged) *ProcessPrivilegesChangedChecker { + enum := ProcessPrivilegesChangedChecker(val) + return &enum +} + +// Check checks a ProcessPrivilegesChanged against the checker +func (enum *ProcessPrivilegesChangedChecker) Check(val *tetragon.ProcessPrivilegesChanged) error { + if val == nil { + return fmt.Errorf("ProcessPrivilegesChangedChecker: ProcessPrivilegesChanged is nil and does not match expected value %s", tetragon.ProcessPrivilegesChanged(*enum)) + } + if *enum != ProcessPrivilegesChangedChecker(*val) { + return fmt.Errorf("ProcessPrivilegesChangedChecker: ProcessPrivilegesChanged has value %s which does not match expected value %s", (*val), tetragon.ProcessPrivilegesChanged(*enum)) + } + return nil +} + // KprobeActionChecker checks a tetragon.KprobeAction type KprobeActionChecker tetragon.KprobeAction diff --git a/api/v1/tetragon/tetragon.pb.go b/api/v1/tetragon/tetragon.pb.go index 4aa6cac53ac..99bfda02d31 100644 --- a/api/v1/tetragon/tetragon.pb.go +++ b/api/v1/tetragon/tetragon.pb.go @@ -1027,6 +1027,10 @@ type BinaryProperties struct { Setuid *wrapperspb.UInt32Value `protobuf:"bytes,1,opt,name=setuid,proto3" json:"setuid,omitempty"` // If set then this is the set group ID used for execution Setgid *wrapperspb.UInt32Value `protobuf:"bytes,2,opt,name=setgid,proto3" json:"setgid,omitempty"` + // The reasons why this binary execution changed privileges. Usually this happens when the process executes + // a binary with the set-user-ID to root or file capability sets. + // The final granted privileges can be listed inside the `process_credentials` or capabilities fields part of of the `process` object. + PrivilegesChanged []ProcessPrivilegesChanged `protobuf:"varint,3,rep,packed,name=privileges_changed,json=privilegesChanged,proto3,enum=tetragon.ProcessPrivilegesChanged" json:"privileges_changed,omitempty"` } func (x *BinaryProperties) Reset() { @@ -1075,6 +1079,13 @@ func (x *BinaryProperties) GetSetgid() *wrapperspb.UInt32Value { return nil } +func (x *BinaryProperties) GetPrivilegesChanged() []ProcessPrivilegesChanged { + if x != nil { + return x.PrivilegesChanged + } + return nil +} + type Process struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2705,6 +2716,8 @@ type ProcessKprobe struct { PolicyName string `protobuf:"bytes,8,opt,name=policy_name,json=policyName,proto3" json:"policy_name,omitempty"` // Action performed when the return kprobe executed. ReturnAction KprobeAction `protobuf:"varint,9,opt,name=return_action,json=returnAction,proto3,enum=tetragon.KprobeAction" json:"return_action,omitempty"` + // Short message of the Tracing Policy to inform users what is going on. + Message string `protobuf:"bytes,10,opt,name=message,proto3" json:"message,omitempty"` } func (x *ProcessKprobe) Reset() { @@ -2802,6 +2815,13 @@ func (x *ProcessKprobe) GetReturnAction() KprobeAction { return KprobeAction_KPROBE_ACTION_UNKNOWN } +func (x *ProcessKprobe) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + type ProcessTracepoint struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2822,6 +2842,8 @@ type ProcessTracepoint struct { PolicyName string `protobuf:"bytes,7,opt,name=policy_name,json=policyName,proto3" json:"policy_name,omitempty"` // Action performed when the tracepoint matched. Action KprobeAction `protobuf:"varint,8,opt,name=action,proto3,enum=tetragon.KprobeAction" json:"action,omitempty"` + // Short message of the Tracing Policy to inform users what is going on. + Message string `protobuf:"bytes,9,opt,name=message,proto3" json:"message,omitempty"` } func (x *ProcessTracepoint) Reset() { @@ -2905,6 +2927,13 @@ func (x *ProcessTracepoint) GetAction() KprobeAction { return KprobeAction_KPROBE_ACTION_UNKNOWN } +func (x *ProcessTracepoint) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + type ProcessUprobe struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2916,6 +2945,8 @@ type ProcessUprobe struct { Symbol string `protobuf:"bytes,4,opt,name=symbol,proto3" json:"symbol,omitempty"` // Name of the policy that created that uprobe. PolicyName string `protobuf:"bytes,5,opt,name=policy_name,json=policyName,proto3" json:"policy_name,omitempty"` + // Short message of the Tracing Policy to inform users what is going on. + Message string `protobuf:"bytes,6,opt,name=message,proto3" json:"message,omitempty"` } func (x *ProcessUprobe) Reset() { @@ -2985,6 +3016,13 @@ func (x *ProcessUprobe) GetPolicyName() string { return "" } +func (x *ProcessUprobe) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + type KernelModule struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3729,442 +3767,452 @@ var file_tetragon_tetragon_proto_rawDesc = []byte{ 0x74, 0x69, 0x65, 0x73, 0x52, 0x04, 0x63, 0x61, 0x70, 0x73, 0x12, 0x30, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x73, 0x22, 0x7e, 0x0a, 0x10, - 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, - 0x12, 0x34, 0x0a, 0x06, 0x73, 0x65, 0x74, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, - 0x73, 0x65, 0x74, 0x75, 0x69, 0x64, 0x12, 0x34, 0x0a, 0x06, 0x73, 0x65, 0x74, 0x67, 0x69, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x73, 0x65, 0x74, 0x67, 0x69, 0x64, 0x22, 0xdc, 0x05, 0x0a, - 0x07, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x65, 0x78, 0x65, 0x63, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x65, 0x78, 0x65, 0x63, 0x49, - 0x64, 0x12, 0x2e, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x03, 0x70, 0x69, - 0x64, 0x12, 0x2e, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x03, 0x75, 0x69, - 0x64, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x77, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x63, 0x77, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x61, - 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, - 0x67, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x12, - 0x39, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, - 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x30, 0x0a, 0x04, 0x61, 0x75, - 0x69, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, - 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x04, 0x61, 0x75, 0x69, 0x64, 0x12, 0x1f, 0x0a, 0x03, - 0x70, 0x6f, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x74, 0x65, 0x74, 0x72, - 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x6f, 0x64, 0x52, 0x03, 0x70, 0x6f, 0x64, 0x12, 0x16, 0x0a, - 0x06, 0x64, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, - 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, - 0x65, 0x78, 0x65, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, - 0x61, 0x72, 0x65, 0x6e, 0x74, 0x45, 0x78, 0x65, 0x63, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x72, - 0x65, 0x66, 0x63, 0x6e, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x72, 0x65, 0x66, - 0x63, 0x6e, 0x74, 0x12, 0x28, 0x0a, 0x03, 0x63, 0x61, 0x70, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x70, 0x61, - 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x03, 0x63, 0x61, 0x70, 0x12, 0x24, 0x0a, - 0x02, 0x6e, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x65, 0x74, 0x72, - 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, - 0x02, 0x6e, 0x73, 0x12, 0x2e, 0x0a, 0x03, 0x74, 0x69, 0x64, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x03, - 0x74, 0x69, 0x64, 0x12, 0x4d, 0x0a, 0x13, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, - 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1c, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, - 0x65, 0x73, 0x73, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x52, 0x12, - 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, - 0x6c, 0x73, 0x12, 0x47, 0x0a, 0x11, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x5f, 0x70, 0x72, 0x6f, - 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, - 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x50, - 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x52, 0x10, 0x62, 0x69, 0x6e, 0x61, 0x72, - 0x79, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0x96, 0x01, 0x0a, 0x0b, - 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, 0x65, 0x63, 0x12, 0x2b, 0x0a, 0x07, 0x70, - 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, - 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, - 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x29, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, - 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, - 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, - 0x65, 0x6e, 0x74, 0x12, 0x2f, 0x0a, 0x09, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, - 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, - 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x09, 0x61, 0x6e, 0x63, 0x65, 0x73, - 0x74, 0x6f, 0x72, 0x73, 0x22, 0xc5, 0x01, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, - 0x45, 0x78, 0x69, 0x74, 0x12, 0x2b, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, - 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, - 0x73, 0x12, 0x29, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, - 0x63, 0x65, 0x73, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, - 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x69, - 0x67, 0x6e, 0x61, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2e, 0x0a, 0x04, - 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x8a, 0x02, 0x0a, - 0x0a, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x53, 0x6f, 0x63, 0x6b, 0x12, 0x16, 0x0a, 0x06, 0x66, - 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x61, 0x6d, - 0x69, 0x6c, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x63, 0x6f, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x63, 0x6f, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x61, 0x72, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x04, 0x6d, 0x61, 0x72, 0x6b, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, - 0x69, 0x74, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, - 0x69, 0x74, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x61, 0x64, 0x64, 0x72, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x73, 0x61, 0x64, 0x64, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x61, 0x64, - 0x64, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x64, 0x61, 0x64, 0x64, 0x72, 0x12, - 0x14, 0x0a, 0x05, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, - 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x09, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x64, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x63, - 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x63, 0x6f, 0x6f, - 0x6b, 0x69, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x0b, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0xc9, 0x02, 0x0a, 0x09, 0x4b, 0x70, - 0x72, 0x6f, 0x62, 0x65, 0x53, 0x6b, 0x62, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x10, 0x0a, 0x03, 0x6c, - 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6c, 0x65, 0x6e, 0x12, 0x1a, 0x0a, - 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x61, 0x72, - 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x6d, 0x61, 0x72, 0x6b, 0x12, 0x14, 0x0a, - 0x05, 0x73, 0x61, 0x64, 0x64, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x61, - 0x64, 0x64, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x61, 0x64, 0x64, 0x72, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x64, 0x61, 0x64, 0x64, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x70, 0x6f, - 0x72, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, - 0x14, 0x0a, 0x05, 0x64, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, - 0x64, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x18, 0x09, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x20, 0x0a, 0x0c, 0x73, - 0x65, 0x63, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x6c, 0x65, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x0a, 0x73, 0x65, 0x63, 0x50, 0x61, 0x74, 0x68, 0x4c, 0x65, 0x6e, 0x12, 0x22, 0x0a, - 0x0d, 0x73, 0x65, 0x63, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x6f, 0x6c, 0x65, 0x6e, 0x18, 0x0b, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x73, 0x65, 0x63, 0x50, 0x61, 0x74, 0x68, 0x4f, 0x6c, 0x65, - 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x0c, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x16, 0x0a, - 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, - 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x22, 0x4c, 0x0a, 0x0a, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x50, - 0x61, 0x74, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, - 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x14, 0x0a, - 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x66, 0x6c, - 0x61, 0x67, 0x73, 0x22, 0x4c, 0x0a, 0x0a, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x46, 0x69, 0x6c, - 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x66, - 0x6c, 0x61, 0x67, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, - 0x73, 0x22, 0x50, 0x0a, 0x14, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x54, 0x72, 0x75, 0x6e, 0x63, - 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x79, 0x74, - 0x65, 0x73, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x62, 0x79, - 0x74, 0x65, 0x73, 0x41, 0x72, 0x67, 0x12, 0x1b, 0x0a, 0x09, 0x6f, 0x72, 0x69, 0x67, 0x5f, 0x73, - 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x6f, 0x72, 0x69, 0x67, 0x53, - 0x69, 0x7a, 0x65, 0x22, 0xbe, 0x01, 0x0a, 0x0a, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x43, 0x72, - 0x65, 0x64, 0x12, 0x38, 0x0a, 0x09, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, - 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x54, 0x79, 0x70, - 0x65, 0x52, 0x09, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x12, 0x38, 0x0a, 0x09, - 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0e, 0x32, - 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, - 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, 0x09, 0x65, 0x66, 0x66, - 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x3c, 0x0a, 0x0b, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x65, - 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, - 0x69, 0x65, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x22, 0x59, 0x0a, 0x10, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x43, 0x61, - 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x31, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, - 0xd5, 0x01, 0x0a, 0x13, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x61, - 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x31, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x32, 0x0a, 0x05, 0x6f, 0x77, - 0x6e, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, - 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x32, - 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x67, 0x72, 0x6f, - 0x75, 0x70, 0x12, 0x23, 0x0a, 0x02, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, - 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x52, 0x02, 0x6e, 0x73, 0x22, 0x61, 0x0a, 0x0d, 0x4b, 0x70, 0x72, 0x6f, 0x62, - 0x65, 0x42, 0x70, 0x66, 0x41, 0x74, 0x74, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x67, - 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x67, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x49, 0x6e, 0x73, 0x6e, 0x43, 0x6e, 0x74, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x49, 0x6e, 0x73, 0x6e, 0x43, 0x6e, 0x74, 0x12, 0x1a, - 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x50, 0x72, 0x6f, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x7f, 0x0a, 0x0f, 0x4b, 0x70, - 0x72, 0x6f, 0x62, 0x65, 0x50, 0x65, 0x72, 0x66, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1e, 0x0a, - 0x0a, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x46, 0x75, 0x6e, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0a, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x46, 0x75, 0x6e, 0x63, 0x12, 0x12, 0x0a, - 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x16, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x20, 0x0a, 0x0b, 0x50, 0x72, 0x6f, - 0x62, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, - 0x50, 0x72, 0x6f, 0x62, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x22, 0x9a, 0x01, 0x0a, 0x0c, - 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x42, 0x70, 0x66, 0x4d, 0x61, 0x70, 0x12, 0x18, 0x0a, 0x07, - 0x4d, 0x61, 0x70, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x4d, - 0x61, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x7a, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x7a, 0x65, - 0x12, 0x1c, 0x0a, 0x09, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x09, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1e, - 0x0a, 0x0a, 0x4d, 0x61, 0x78, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x0a, 0x4d, 0x61, 0x78, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x18, - 0x0a, 0x07, 0x4d, 0x61, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x4d, 0x61, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xcb, 0x08, 0x0a, 0x0e, 0x4b, 0x70, 0x72, - 0x6f, 0x62, 0x65, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0a, 0x73, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, - 0x00, 0x52, 0x09, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x41, 0x72, 0x67, 0x12, 0x19, 0x0a, 0x07, - 0x69, 0x6e, 0x74, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, - 0x06, 0x69, 0x6e, 0x74, 0x41, 0x72, 0x67, 0x12, 0x2e, 0x0a, 0x07, 0x73, 0x6b, 0x62, 0x5f, 0x61, - 0x72, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, - 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x53, 0x6b, 0x62, 0x48, 0x00, 0x52, - 0x06, 0x73, 0x6b, 0x62, 0x41, 0x72, 0x67, 0x12, 0x1b, 0x0a, 0x08, 0x73, 0x69, 0x7a, 0x65, 0x5f, - 0x61, 0x72, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, 0x07, 0x73, 0x69, 0x7a, - 0x65, 0x41, 0x72, 0x67, 0x12, 0x1d, 0x0a, 0x09, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x61, 0x72, - 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x08, 0x62, 0x79, 0x74, 0x65, 0x73, - 0x41, 0x72, 0x67, 0x12, 0x31, 0x0a, 0x08, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x61, 0x72, 0x67, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, - 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x50, 0x61, 0x74, 0x68, 0x48, 0x00, 0x52, 0x07, 0x70, - 0x61, 0x74, 0x68, 0x41, 0x72, 0x67, 0x12, 0x31, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x61, - 0x72, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, - 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x48, 0x00, - 0x52, 0x07, 0x66, 0x69, 0x6c, 0x65, 0x41, 0x72, 0x67, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x75, - 0x6e, 0x63, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x61, 0x72, 0x67, - 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, - 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x54, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, - 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x48, 0x00, 0x52, 0x11, 0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, - 0x74, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x41, 0x72, 0x67, 0x12, 0x31, 0x0a, 0x08, 0x73, - 0x6f, 0x63, 0x6b, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, - 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x53, - 0x6f, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x07, 0x73, 0x6f, 0x63, 0x6b, 0x41, 0x72, 0x67, 0x12, 0x31, - 0x0a, 0x08, 0x63, 0x72, 0x65, 0x64, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x14, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, - 0x62, 0x65, 0x43, 0x72, 0x65, 0x64, 0x48, 0x00, 0x52, 0x07, 0x63, 0x72, 0x65, 0x64, 0x41, 0x72, - 0x67, 0x12, 0x1b, 0x0a, 0x08, 0x6c, 0x6f, 0x6e, 0x67, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x0b, 0x20, - 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x07, 0x6c, 0x6f, 0x6e, 0x67, 0x41, 0x72, 0x67, 0x12, 0x3b, - 0x0a, 0x0c, 0x62, 0x70, 0x66, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x0c, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, - 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x42, 0x70, 0x66, 0x41, 0x74, 0x74, 0x72, 0x48, 0x00, 0x52, - 0x0a, 0x62, 0x70, 0x66, 0x41, 0x74, 0x74, 0x72, 0x41, 0x72, 0x67, 0x12, 0x41, 0x0a, 0x0e, 0x70, - 0x65, 0x72, 0x66, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x0d, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, - 0x70, 0x72, 0x6f, 0x62, 0x65, 0x50, 0x65, 0x72, 0x66, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, - 0x52, 0x0c, 0x70, 0x65, 0x72, 0x66, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x41, 0x72, 0x67, 0x12, 0x38, - 0x0a, 0x0b, 0x62, 0x70, 0x66, 0x5f, 0x6d, 0x61, 0x70, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x0e, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, - 0x70, 0x72, 0x6f, 0x62, 0x65, 0x42, 0x70, 0x66, 0x4d, 0x61, 0x70, 0x48, 0x00, 0x52, 0x09, 0x62, - 0x70, 0x66, 0x4d, 0x61, 0x70, 0x41, 0x72, 0x67, 0x12, 0x1b, 0x0a, 0x08, 0x75, 0x69, 0x6e, 0x74, - 0x5f, 0x61, 0x72, 0x67, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x07, 0x75, 0x69, - 0x6e, 0x74, 0x41, 0x72, 0x67, 0x12, 0x51, 0x0a, 0x12, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x10, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, - 0x6f, 0x62, 0x65, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x42, 0x02, 0x18, 0x01, 0x48, 0x00, 0x52, 0x10, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x72, 0x67, 0x12, 0x43, 0x0a, 0x0e, 0x63, 0x61, 0x70, 0x61, - 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, - 0x62, 0x65, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x48, 0x00, 0x52, 0x0d, - 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x41, 0x72, 0x67, 0x12, 0x56, 0x0a, - 0x17, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, - 0x69, 0x61, 0x6c, 0x73, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, - 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, - 0x73, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x48, 0x00, 0x52, 0x15, - 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, - 0x6c, 0x73, 0x41, 0x72, 0x67, 0x12, 0x39, 0x0a, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x73, - 0x5f, 0x61, 0x72, 0x67, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, - 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x48, 0x00, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x73, 0x41, 0x72, 0x67, - 0x12, 0x37, 0x0a, 0x0a, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x15, + 0x70, 0x61, 0x63, 0x65, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x73, 0x22, 0xd1, 0x01, 0x0a, + 0x10, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, + 0x73, 0x12, 0x34, 0x0a, 0x06, 0x73, 0x65, 0x74, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, + 0x06, 0x73, 0x65, 0x74, 0x75, 0x69, 0x64, 0x12, 0x34, 0x0a, 0x06, 0x73, 0x65, 0x74, 0x67, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x73, 0x65, 0x74, 0x67, 0x69, 0x64, 0x12, 0x51, 0x0a, + 0x12, 0x70, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x73, 0x5f, 0x63, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x64, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x74, 0x65, 0x74, 0x72, + 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x50, 0x72, 0x69, 0x76, + 0x69, 0x6c, 0x65, 0x67, 0x65, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x52, 0x11, 0x70, + 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, + 0x22, 0xdc, 0x05, 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x17, 0x0a, 0x07, + 0x65, 0x78, 0x65, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x65, + 0x78, 0x65, 0x63, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, 0x2e, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x77, 0x64, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x63, 0x77, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x69, 0x6e, 0x61, 0x72, + 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x12, + 0x1c, 0x0a, 0x09, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x14, 0x0a, + 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x66, 0x6c, + 0x61, 0x67, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, + 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x30, + 0x0a, 0x04, 0x61, 0x75, 0x69, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, + 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x04, 0x61, 0x75, 0x69, 0x64, + 0x12, 0x1f, 0x0a, 0x03, 0x70, 0x6f, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, + 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x6f, 0x64, 0x52, 0x03, 0x70, 0x6f, + 0x64, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x64, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x5f, 0x65, 0x78, 0x65, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0c, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x45, 0x78, 0x65, 0x63, 0x49, 0x64, 0x12, + 0x16, 0x0a, 0x06, 0x72, 0x65, 0x66, 0x63, 0x6e, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x06, 0x72, 0x65, 0x66, 0x63, 0x6e, 0x74, 0x12, 0x28, 0x0a, 0x03, 0x63, 0x61, 0x70, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, - 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x48, 0x00, 0x52, 0x09, - 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x41, 0x72, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, - 0x65, 0x6c, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x42, - 0x05, 0x0a, 0x03, 0x61, 0x72, 0x67, 0x22, 0xb6, 0x03, 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x63, 0x65, - 0x73, 0x73, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, + 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x03, 0x63, 0x61, + 0x70, 0x12, 0x24, 0x0a, 0x02, 0x6e, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, + 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x73, 0x52, 0x02, 0x6e, 0x73, 0x12, 0x2e, 0x0a, 0x03, 0x74, 0x69, 0x64, 0x18, 0x10, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x03, 0x74, 0x69, 0x64, 0x12, 0x4d, 0x0a, 0x13, 0x70, 0x72, 0x6f, 0x63, 0x65, + 0x73, 0x73, 0x5f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x18, 0x11, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, + 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, + 0x6c, 0x73, 0x52, 0x12, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x72, 0x65, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x47, 0x0a, 0x11, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, + 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x12, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x42, 0x69, 0x6e, + 0x61, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x52, 0x10, 0x62, + 0x69, 0x6e, 0x61, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, + 0x96, 0x01, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, 0x65, 0x63, 0x12, + 0x2b, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x29, 0x0a, 0x06, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, + 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, + 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x2f, 0x0a, 0x09, 0x61, 0x6e, 0x63, 0x65, 0x73, + 0x74, 0x6f, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, + 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x09, 0x61, + 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x22, 0xc5, 0x01, 0x0a, 0x0b, 0x50, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, 0x69, 0x74, 0x12, 0x2b, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x29, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, - 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2c, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x73, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, - 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x04, 0x61, - 0x72, 0x67, 0x73, 0x12, 0x30, 0x0a, 0x06, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, - 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x72, - 0x65, 0x74, 0x75, 0x72, 0x6e, 0x12, 0x2e, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, - 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3a, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5f, 0x74, - 0x72, 0x61, 0x63, 0x65, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x65, 0x74, - 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x54, 0x72, 0x61, 0x63, 0x65, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x54, 0x72, 0x61, 0x63, - 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x0d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, - 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x0c, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, - 0x98, 0x02, 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x72, 0x61, 0x63, 0x65, - 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x2b, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, - 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, - 0x73, 0x73, 0x12, 0x29, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, - 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, - 0x06, 0x73, 0x75, 0x62, 0x73, 0x79, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, - 0x75, 0x62, 0x73, 0x79, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x04, 0x61, - 0x72, 0x67, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x74, 0x72, - 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x72, 0x67, 0x75, 0x6d, - 0x65, 0x6e, 0x74, 0x52, 0x04, 0x61, 0x72, 0x67, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, - 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x06, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, - 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xb4, 0x01, 0x0a, 0x0d, 0x50, - 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x55, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x12, 0x2b, 0x0a, 0x07, + 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, + 0x22, 0x8a, 0x02, 0x0a, 0x0a, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x53, 0x6f, 0x63, 0x6b, 0x12, + 0x16, 0x0a, 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x61, 0x72, 0x6b, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x6d, 0x61, 0x72, 0x6b, 0x12, 0x1a, 0x0a, 0x08, 0x70, + 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x70, + 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x61, 0x64, 0x64, 0x72, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x61, 0x64, 0x64, 0x72, 0x12, 0x14, 0x0a, + 0x05, 0x64, 0x61, 0x64, 0x64, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x64, 0x61, + 0x64, 0x64, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x05, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x70, 0x6f, + 0x72, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x64, 0x70, 0x6f, 0x72, 0x74, 0x12, + 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x06, 0x63, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0xc9, 0x02, + 0x0a, 0x09, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x53, 0x6b, 0x62, 0x12, 0x12, 0x0a, 0x04, 0x68, + 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, + 0x10, 0x0a, 0x03, 0x6c, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6c, 0x65, + 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x12, 0x0a, + 0x04, 0x6d, 0x61, 0x72, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x6d, 0x61, 0x72, + 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x61, 0x64, 0x64, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x73, 0x61, 0x64, 0x64, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x61, 0x64, 0x64, 0x72, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x64, 0x61, 0x64, 0x64, 0x72, 0x12, 0x14, 0x0a, + 0x05, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x73, 0x70, + 0x6f, 0x72, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x05, 0x64, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x20, 0x0a, 0x0c, 0x73, 0x65, 0x63, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x6c, 0x65, 0x6e, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x73, 0x65, 0x63, 0x50, 0x61, 0x74, 0x68, 0x4c, 0x65, + 0x6e, 0x12, 0x22, 0x0a, 0x0d, 0x73, 0x65, 0x63, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x6f, 0x6c, + 0x65, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x73, 0x65, 0x63, 0x50, 0x61, 0x74, + 0x68, 0x4f, 0x6c, 0x65, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6c, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x22, 0x4c, 0x0a, 0x0a, 0x4b, 0x70, 0x72, + 0x6f, 0x62, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f, 0x75, 0x6e, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, + 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, + 0x68, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x22, 0x4c, 0x0a, 0x0a, 0x4b, 0x70, 0x72, 0x6f, 0x62, + 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, + 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, + 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x66, 0x6c, 0x61, 0x67, 0x73, 0x22, 0x50, 0x0a, 0x14, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x54, + 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1b, 0x0a, + 0x09, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x08, 0x62, 0x79, 0x74, 0x65, 0x73, 0x41, 0x72, 0x67, 0x12, 0x1b, 0x0a, 0x09, 0x6f, 0x72, + 0x69, 0x67, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x6f, + 0x72, 0x69, 0x67, 0x53, 0x69, 0x7a, 0x65, 0x22, 0xbe, 0x01, 0x0a, 0x0a, 0x4b, 0x70, 0x72, 0x6f, + 0x62, 0x65, 0x43, 0x72, 0x65, 0x64, 0x12, 0x38, 0x0a, 0x09, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x74, + 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, + 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, + 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, 0x09, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, + 0x12, 0x38, 0x0a, 0x09, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, + 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, + 0x09, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x3c, 0x0a, 0x0b, 0x69, 0x6e, + 0x68, 0x65, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, + 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, + 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x69, 0x6e, 0x68, + 0x65, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x59, 0x0a, 0x10, 0x4b, 0x70, 0x72, 0x6f, + 0x62, 0x65, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x31, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, + 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x22, 0xd5, 0x01, 0x0a, 0x13, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x55, 0x73, + 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x31, 0x0a, 0x05, 0x6c, + 0x65, 0x76, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, + 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x32, + 0x0a, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x6f, 0x77, 0x6e, + 0x65, 0x72, 0x12, 0x32, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, + 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x23, 0x0a, 0x02, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4e, 0x61, + 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x02, 0x6e, 0x73, 0x22, 0x61, 0x0a, 0x0d, 0x4b, + 0x70, 0x72, 0x6f, 0x62, 0x65, 0x42, 0x70, 0x66, 0x41, 0x74, 0x74, 0x72, 0x12, 0x1a, 0x0a, 0x08, + 0x50, 0x72, 0x6f, 0x67, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x50, 0x72, 0x6f, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x49, 0x6e, 0x73, 0x6e, + 0x43, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x49, 0x6e, 0x73, 0x6e, 0x43, + 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x7f, + 0x0a, 0x0f, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x50, 0x65, 0x72, 0x66, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x46, 0x75, 0x6e, 0x63, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x46, 0x75, 0x6e, + 0x63, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x20, 0x0a, + 0x0b, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x0b, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x22, + 0x9a, 0x01, 0x0a, 0x0c, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x42, 0x70, 0x66, 0x4d, 0x61, 0x70, + 0x12, 0x18, 0x0a, 0x07, 0x4d, 0x61, 0x70, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x4d, 0x61, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x4b, 0x65, + 0x79, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x4b, 0x65, 0x79, + 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x69, 0x7a, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x69, + 0x7a, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x4d, 0x61, 0x78, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x4d, 0x61, 0x78, 0x45, 0x6e, 0x74, 0x72, 0x69, + 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x4d, 0x61, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x4d, 0x61, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xcb, 0x08, 0x0a, + 0x0e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x12, + 0x1f, 0x0a, 0x0a, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x09, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x41, 0x72, 0x67, + 0x12, 0x19, 0x0a, 0x07, 0x69, 0x6e, 0x74, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x05, 0x48, 0x00, 0x52, 0x06, 0x69, 0x6e, 0x74, 0x41, 0x72, 0x67, 0x12, 0x2e, 0x0a, 0x07, 0x73, + 0x6b, 0x62, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, + 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x53, 0x6b, + 0x62, 0x48, 0x00, 0x52, 0x06, 0x73, 0x6b, 0x62, 0x41, 0x72, 0x67, 0x12, 0x1b, 0x0a, 0x08, 0x73, + 0x69, 0x7a, 0x65, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, + 0x07, 0x73, 0x69, 0x7a, 0x65, 0x41, 0x72, 0x67, 0x12, 0x1d, 0x0a, 0x09, 0x62, 0x79, 0x74, 0x65, + 0x73, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x08, 0x62, + 0x79, 0x74, 0x65, 0x73, 0x41, 0x72, 0x67, 0x12, 0x31, 0x0a, 0x08, 0x70, 0x61, 0x74, 0x68, 0x5f, + 0x61, 0x72, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x65, 0x74, 0x72, + 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x50, 0x61, 0x74, 0x68, 0x48, + 0x00, 0x52, 0x07, 0x70, 0x61, 0x74, 0x68, 0x41, 0x72, 0x67, 0x12, 0x31, 0x0a, 0x08, 0x66, 0x69, + 0x6c, 0x65, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, + 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x46, 0x69, + 0x6c, 0x65, 0x48, 0x00, 0x52, 0x07, 0x66, 0x69, 0x6c, 0x65, 0x41, 0x72, 0x67, 0x12, 0x50, 0x0a, + 0x13, 0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, + 0x5f, 0x61, 0x72, 0x67, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x65, 0x74, + 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x54, 0x72, 0x75, 0x6e, + 0x63, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x48, 0x00, 0x52, 0x11, 0x74, 0x72, + 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x41, 0x72, 0x67, 0x12, + 0x31, 0x0a, 0x08, 0x73, 0x6f, 0x63, 0x6b, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x09, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, + 0x6f, 0x62, 0x65, 0x53, 0x6f, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x07, 0x73, 0x6f, 0x63, 0x6b, 0x41, + 0x72, 0x67, 0x12, 0x31, 0x0a, 0x08, 0x63, 0x72, 0x65, 0x64, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, + 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x43, 0x72, 0x65, 0x64, 0x48, 0x00, 0x52, 0x07, 0x63, 0x72, + 0x65, 0x64, 0x41, 0x72, 0x67, 0x12, 0x1b, 0x0a, 0x08, 0x6c, 0x6f, 0x6e, 0x67, 0x5f, 0x61, 0x72, + 0x67, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x07, 0x6c, 0x6f, 0x6e, 0x67, 0x41, + 0x72, 0x67, 0x12, 0x3b, 0x0a, 0x0c, 0x62, 0x70, 0x66, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x5f, 0x61, + 0x72, 0x67, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, + 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x42, 0x70, 0x66, 0x41, 0x74, 0x74, + 0x72, 0x48, 0x00, 0x52, 0x0a, 0x62, 0x70, 0x66, 0x41, 0x74, 0x74, 0x72, 0x41, 0x72, 0x67, 0x12, + 0x41, 0x0a, 0x0e, 0x70, 0x65, 0x72, 0x66, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x72, + 0x67, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, + 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x50, 0x65, 0x72, 0x66, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0c, 0x70, 0x65, 0x72, 0x66, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x41, + 0x72, 0x67, 0x12, 0x38, 0x0a, 0x0b, 0x62, 0x70, 0x66, 0x5f, 0x6d, 0x61, 0x70, 0x5f, 0x61, 0x72, + 0x67, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, + 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x42, 0x70, 0x66, 0x4d, 0x61, 0x70, 0x48, + 0x00, 0x52, 0x09, 0x62, 0x70, 0x66, 0x4d, 0x61, 0x70, 0x41, 0x72, 0x67, 0x12, 0x1b, 0x0a, 0x08, + 0x75, 0x69, 0x6e, 0x74, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, + 0x52, 0x07, 0x75, 0x69, 0x6e, 0x74, 0x41, 0x72, 0x67, 0x12, 0x51, 0x0a, 0x12, 0x75, 0x73, 0x65, + 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x61, 0x72, 0x67, 0x18, + 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, + 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x42, 0x02, 0x18, 0x01, 0x48, 0x00, 0x52, 0x10, 0x75, 0x73, 0x65, 0x72, + 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x72, 0x67, 0x12, 0x43, 0x0a, 0x0e, + 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x11, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, + 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, + 0x48, 0x00, 0x52, 0x0d, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x41, 0x72, + 0x67, 0x12, 0x56, 0x0a, 0x17, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x72, 0x65, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x13, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, + 0x48, 0x00, 0x52, 0x15, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x72, 0x65, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x41, 0x72, 0x67, 0x12, 0x39, 0x0a, 0x0b, 0x75, 0x73, 0x65, + 0x72, 0x5f, 0x6e, 0x73, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, + 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x61, + 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x48, 0x00, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x4e, + 0x73, 0x41, 0x72, 0x67, 0x12, 0x37, 0x0a, 0x0a, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x61, + 0x72, 0x67, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, + 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x48, 0x00, 0x52, 0x09, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x41, 0x72, 0x67, 0x12, 0x14, 0x0a, + 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x42, 0x05, 0x0a, 0x03, 0x61, 0x72, 0x67, 0x22, 0xd0, 0x03, 0x0a, 0x0d, 0x50, + 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x29, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x06, 0x70, 0x61, - 0x72, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, 0x6d, 0x62, - 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, - 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4e, 0x61, 0x6d, - 0x65, 0x22, 0x96, 0x01, 0x0a, 0x0c, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x4d, 0x6f, 0x64, 0x75, - 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3d, 0x0a, 0x0c, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, - 0x75, 0x72, 0x65, 0x5f, 0x6f, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, - 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, - 0x75, 0x72, 0x65, 0x4f, 0x6b, 0x12, 0x33, 0x0a, 0x07, 0x74, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x64, - 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, - 0x6e, 0x2e, 0x54, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x64, 0x42, 0x69, 0x74, 0x73, 0x54, 0x79, 0x70, - 0x65, 0x52, 0x07, 0x74, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x64, 0x22, 0x56, 0x0a, 0x04, 0x54, 0x65, - 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x30, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x04, 0x61, 0x72, 0x67, 0x30, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x31, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x61, 0x72, 0x67, 0x31, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, - 0x67, 0x32, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x61, 0x72, 0x67, 0x32, 0x12, 0x12, - 0x0a, 0x04, 0x61, 0x72, 0x67, 0x33, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x61, 0x72, - 0x67, 0x33, 0x22, 0x51, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x37, 0x0a, 0x09, - 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, - 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, - 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x65, 0x76, 0x65, - 0x6e, 0x74, 0x53, 0x65, 0x74, 0x22, 0x90, 0x01, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x30, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, - 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x54, 0x79, 0x70, - 0x65, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x34, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, - 0x67, 0x6f, 0x6e, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, - 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x56, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x48, - 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x0d, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x5f, 0x73, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, + 0x72, 0x65, 0x6e, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2c, 0x0a, 0x04, 0x61, 0x72, 0x67, + 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, + 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x52, 0x04, 0x61, 0x72, 0x67, 0x73, 0x12, 0x30, 0x0a, 0x06, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, + 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x52, 0x06, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x12, 0x2e, 0x0a, 0x06, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, + 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3a, 0x0a, 0x0b, 0x73, 0x74, 0x61, + 0x63, 0x6b, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, + 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x54, + 0x72, 0x61, 0x63, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x54, 0x72, 0x61, 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x0d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, + 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x41, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xb2, 0x02, + 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x72, 0x61, 0x63, 0x65, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x12, 0x2b, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, + 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, + 0x12, 0x29, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, + 0x75, 0x62, 0x73, 0x79, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x75, 0x62, + 0x73, 0x79, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x04, 0x61, 0x72, 0x67, + 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, + 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x52, 0x04, 0x61, 0x72, 0x67, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, + 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x22, 0xce, 0x01, 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x55, 0x70, + 0x72, 0x6f, 0x62, 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, + 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, + 0x73, 0x12, 0x29, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, + 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, + 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x22, 0x96, 0x01, 0x0a, 0x0c, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x4d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3d, 0x0a, 0x0c, 0x73, 0x69, 0x67, 0x6e, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x6f, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0b, 0x73, 0x69, 0x67, 0x6e, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x4f, 0x6b, 0x12, 0x33, 0x0a, 0x07, 0x74, 0x61, 0x69, 0x6e, 0x74, + 0x65, 0x64, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, + 0x67, 0x6f, 0x6e, 0x2e, 0x54, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x64, 0x42, 0x69, 0x74, 0x73, 0x54, + 0x79, 0x70, 0x65, 0x52, 0x07, 0x74, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x64, 0x22, 0x56, 0x0a, 0x04, + 0x54, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x30, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x04, 0x61, 0x72, 0x67, 0x30, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x31, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x61, 0x72, 0x67, 0x31, 0x12, 0x12, 0x0a, 0x04, + 0x61, 0x72, 0x67, 0x32, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x61, 0x72, 0x67, 0x32, + 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x33, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, + 0x61, 0x72, 0x67, 0x33, 0x22, 0x51, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x48, 0x65, 0x61, 0x6c, 0x74, + 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x37, + 0x0a, 0x09, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x48, 0x65, 0x61, + 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x74, 0x22, 0x90, 0x01, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x6c, + 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x30, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, + 0x6f, 0x6e, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x54, + 0x79, 0x70, 0x65, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x34, 0x0a, 0x06, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x52, 0x0c, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x22, 0x6a, 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x61, 0x64, 0x65, - 0x72, 0x12, 0x2b, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, - 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x12, - 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, - 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x64, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x64, 0x22, 0x64, 0x0a, 0x12, - 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x45, 0x0a, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x65, - 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x48, 0x00, 0x52, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, - 0x6e, 0x74, 0x22, 0x15, 0x0a, 0x13, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x48, 0x6f, 0x6f, - 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xdb, 0x01, 0x0a, 0x0f, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x20, 0x0a, - 0x0b, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x50, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0b, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x50, 0x61, 0x74, 0x68, 0x12, - 0x18, 0x0a, 0x07, 0x72, 0x6f, 0x6f, 0x74, 0x44, 0x69, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x72, 0x6f, 0x6f, 0x74, 0x44, 0x69, 0x72, 0x12, 0x4c, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, - 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, - 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x3e, 0x0a, 0x10, 0x41, 0x6e, 0x6e, 0x6f, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x5b, 0x0a, 0x0f, 0x53, 0x74, 0x61, 0x63, 0x6b, - 0x54, 0x72, 0x61, 0x63, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x61, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x16, 0x0a, 0x06, - 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x79, - 0x6d, 0x62, 0x6f, 0x6c, 0x2a, 0x93, 0x03, 0x0a, 0x0c, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x15, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, - 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, - 0x12, 0x16, 0x0a, 0x12, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x4b, 0x50, 0x52, 0x4f, - 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x46, 0x4f, 0x4c, 0x4c, 0x4f, 0x57, - 0x46, 0x44, 0x10, 0x02, 0x12, 0x19, 0x0a, 0x15, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, - 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x49, 0x47, 0x4b, 0x49, 0x4c, 0x4c, 0x10, 0x03, 0x12, - 0x1c, 0x0a, 0x18, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, - 0x5f, 0x55, 0x4e, 0x46, 0x4f, 0x4c, 0x4c, 0x4f, 0x57, 0x46, 0x44, 0x10, 0x04, 0x12, 0x1a, 0x0a, - 0x16, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4f, - 0x56, 0x45, 0x52, 0x52, 0x49, 0x44, 0x45, 0x10, 0x05, 0x12, 0x18, 0x0a, 0x14, 0x4b, 0x50, 0x52, - 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4f, 0x50, 0x59, 0x46, - 0x44, 0x10, 0x06, 0x12, 0x18, 0x0a, 0x14, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, - 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x47, 0x45, 0x54, 0x55, 0x52, 0x4c, 0x10, 0x07, 0x12, 0x1b, 0x0a, - 0x17, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, - 0x4e, 0x53, 0x4c, 0x4f, 0x4f, 0x4b, 0x55, 0x50, 0x10, 0x08, 0x12, 0x18, 0x0a, 0x14, 0x4b, 0x50, - 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x4f, 0x50, 0x4f, - 0x53, 0x54, 0x10, 0x09, 0x12, 0x18, 0x0a, 0x14, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, - 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x41, 0x4c, 0x10, 0x0a, 0x12, 0x1b, - 0x0a, 0x17, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, - 0x54, 0x52, 0x41, 0x43, 0x4b, 0x53, 0x4f, 0x43, 0x4b, 0x10, 0x0b, 0x12, 0x1d, 0x0a, 0x19, 0x4b, - 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x54, - 0x52, 0x41, 0x43, 0x4b, 0x53, 0x4f, 0x43, 0x4b, 0x10, 0x0c, 0x12, 0x1e, 0x0a, 0x1a, 0x4b, 0x50, - 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x4f, 0x54, 0x49, - 0x46, 0x59, 0x4b, 0x49, 0x4c, 0x4c, 0x45, 0x52, 0x10, 0x0d, 0x2a, 0x4f, 0x0a, 0x10, 0x48, 0x65, - 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1c, - 0x0a, 0x18, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, - 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x10, 0x00, 0x12, 0x1d, 0x0a, 0x19, - 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x54, 0x59, - 0x50, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x10, 0x01, 0x2a, 0x7c, 0x0a, 0x12, 0x48, - 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x12, 0x17, 0x0a, 0x13, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, - 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x48, 0x45, - 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x55, 0x4e, 0x4e, - 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, - 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x53, 0x54, 0x4f, 0x50, 0x50, 0x45, 0x44, 0x10, 0x02, - 0x12, 0x17, 0x0a, 0x13, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, - 0x53, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x2a, 0x8d, 0x02, 0x0a, 0x0f, 0x54, 0x61, - 0x69, 0x6e, 0x74, 0x65, 0x64, 0x42, 0x69, 0x74, 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0f, 0x0a, - 0x0b, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x45, 0x54, 0x10, 0x00, 0x12, 0x1c, - 0x0a, 0x18, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x50, 0x52, 0x4f, 0x50, 0x52, 0x49, 0x45, 0x54, - 0x41, 0x52, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, - 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x44, 0x5f, 0x4d, 0x4f, 0x44, - 0x55, 0x4c, 0x45, 0x10, 0x02, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x46, - 0x4f, 0x52, 0x43, 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x4d, 0x4f, 0x44, - 0x55, 0x4c, 0x45, 0x10, 0x04, 0x12, 0x18, 0x0a, 0x13, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x53, - 0x54, 0x41, 0x47, 0x45, 0x44, 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x80, 0x08, 0x12, - 0x1d, 0x0a, 0x18, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, - 0x54, 0x52, 0x45, 0x45, 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x80, 0x20, 0x12, 0x1a, - 0x0a, 0x15, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x49, 0x47, 0x4e, 0x45, 0x44, - 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x80, 0x40, 0x12, 0x24, 0x0a, 0x1e, 0x54, 0x41, - 0x49, 0x4e, 0x54, 0x5f, 0x4b, 0x45, 0x52, 0x4e, 0x45, 0x4c, 0x5f, 0x4c, 0x49, 0x56, 0x45, 0x5f, - 0x50, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x80, 0x80, 0x02, - 0x12, 0x17, 0x0a, 0x11, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x4d, - 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x80, 0x80, 0x10, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x75, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x56, 0x0a, 0x17, 0x47, 0x65, + 0x74, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x0d, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x5f, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, + 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x0c, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x22, 0x6a, 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x61, + 0x64, 0x65, 0x72, 0x12, 0x2b, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, + 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, + 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x70, 0x61, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x64, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x64, 0x22, 0x64, + 0x0a, 0x12, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x45, 0x0a, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, + 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x48, 0x00, 0x52, 0x0f, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x42, 0x07, 0x0a, 0x05, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x22, 0x15, 0x0a, 0x13, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x48, + 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xdb, 0x01, 0x0a, 0x0f, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, + 0x20, 0x0a, 0x0b, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x50, 0x61, 0x74, 0x68, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x50, 0x61, 0x74, + 0x68, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x6f, 0x6f, 0x74, 0x44, 0x69, 0x72, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x72, 0x6f, 0x6f, 0x74, 0x44, 0x69, 0x72, 0x12, 0x4c, 0x0a, 0x0b, 0x61, + 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x2a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, + 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x3e, 0x0a, 0x10, 0x41, 0x6e, 0x6e, + 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x5b, 0x0a, 0x0f, 0x53, 0x74, 0x61, + 0x63, 0x6b, 0x54, 0x72, 0x61, 0x63, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x18, 0x0a, 0x07, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x16, + 0x0a, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x2a, 0x93, 0x03, 0x0a, 0x0c, 0x4b, 0x70, 0x72, 0x6f, 0x62, + 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x15, 0x4b, 0x50, 0x52, 0x4f, 0x42, + 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, + 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x4b, 0x50, + 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x46, 0x4f, 0x4c, 0x4c, + 0x4f, 0x57, 0x46, 0x44, 0x10, 0x02, 0x12, 0x19, 0x0a, 0x15, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, + 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x49, 0x47, 0x4b, 0x49, 0x4c, 0x4c, 0x10, + 0x03, 0x12, 0x1c, 0x0a, 0x18, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, + 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x46, 0x4f, 0x4c, 0x4c, 0x4f, 0x57, 0x46, 0x44, 0x10, 0x04, 0x12, + 0x1a, 0x0a, 0x16, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x52, 0x49, 0x44, 0x45, 0x10, 0x05, 0x12, 0x18, 0x0a, 0x14, 0x4b, + 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4f, 0x50, + 0x59, 0x46, 0x44, 0x10, 0x06, 0x12, 0x18, 0x0a, 0x14, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, + 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x47, 0x45, 0x54, 0x55, 0x52, 0x4c, 0x10, 0x07, 0x12, + 0x1b, 0x0a, 0x17, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x44, 0x4e, 0x53, 0x4c, 0x4f, 0x4f, 0x4b, 0x55, 0x50, 0x10, 0x08, 0x12, 0x18, 0x0a, 0x14, + 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x4f, + 0x50, 0x4f, 0x53, 0x54, 0x10, 0x09, 0x12, 0x18, 0x0a, 0x14, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, + 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x41, 0x4c, 0x10, 0x0a, + 0x12, 0x1b, 0x0a, 0x17, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, + 0x4e, 0x5f, 0x54, 0x52, 0x41, 0x43, 0x4b, 0x53, 0x4f, 0x43, 0x4b, 0x10, 0x0b, 0x12, 0x1d, 0x0a, + 0x19, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, + 0x4e, 0x54, 0x52, 0x41, 0x43, 0x4b, 0x53, 0x4f, 0x43, 0x4b, 0x10, 0x0c, 0x12, 0x1e, 0x0a, 0x1a, + 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x4f, + 0x54, 0x49, 0x46, 0x59, 0x4b, 0x49, 0x4c, 0x4c, 0x45, 0x52, 0x10, 0x0d, 0x2a, 0x4f, 0x0a, 0x10, + 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x1c, 0x0a, 0x18, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, + 0x53, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x10, 0x00, 0x12, 0x1d, + 0x0a, 0x19, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x10, 0x01, 0x2a, 0x7c, 0x0a, + 0x12, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x12, 0x17, 0x0a, 0x13, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x53, 0x54, + 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, + 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x55, + 0x4e, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x48, 0x45, 0x41, 0x4c, 0x54, + 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x53, 0x54, 0x4f, 0x50, 0x50, 0x45, 0x44, + 0x10, 0x02, 0x12, 0x17, 0x0a, 0x13, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x53, 0x54, 0x41, + 0x54, 0x55, 0x53, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x2a, 0x8d, 0x02, 0x0a, 0x0f, + 0x54, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x64, 0x42, 0x69, 0x74, 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x0f, 0x0a, 0x0b, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x45, 0x54, 0x10, 0x00, + 0x12, 0x1c, 0x0a, 0x18, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x50, 0x52, 0x4f, 0x50, 0x52, 0x49, + 0x45, 0x54, 0x41, 0x52, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x17, + 0x0a, 0x13, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x44, 0x5f, 0x4d, + 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x02, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x41, 0x49, 0x4e, 0x54, + 0x5f, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x4d, + 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x04, 0x12, 0x18, 0x0a, 0x13, 0x54, 0x41, 0x49, 0x4e, 0x54, + 0x5f, 0x53, 0x54, 0x41, 0x47, 0x45, 0x44, 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x80, + 0x08, 0x12, 0x1d, 0x0a, 0x18, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, + 0x46, 0x5f, 0x54, 0x52, 0x45, 0x45, 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x80, 0x20, + 0x12, 0x1a, 0x0a, 0x15, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x49, 0x47, 0x4e, + 0x45, 0x44, 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x80, 0x40, 0x12, 0x24, 0x0a, 0x1e, + 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x4b, 0x45, 0x52, 0x4e, 0x45, 0x4c, 0x5f, 0x4c, 0x49, 0x56, + 0x45, 0x5f, 0x50, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x80, + 0x80, 0x02, 0x12, 0x17, 0x0a, 0x11, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x54, 0x45, 0x53, 0x54, + 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x80, 0x80, 0x10, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( @@ -4230,7 +4278,8 @@ var file_tetragon_tetragon_proto_goTypes = []interface{}{ (CapabilitiesType)(0), // 45: tetragon.CapabilitiesType (*wrapperspb.Int32Value)(nil), // 46: google.protobuf.Int32Value (SecureBitsType)(0), // 47: tetragon.SecureBitsType - (*wrapperspb.BoolValue)(nil), // 48: google.protobuf.BoolValue + (ProcessPrivilegesChanged)(0), // 48: tetragon.ProcessPrivilegesChanged + (*wrapperspb.BoolValue)(nil), // 49: google.protobuf.BoolValue } var file_tetragon_tetragon_proto_depIdxs = []int32{ 4, // 0: tetragon.Container.image:type_name -> tetragon.Image @@ -4268,71 +4317,72 @@ var file_tetragon_tetragon_proto_depIdxs = []int32{ 10, // 32: tetragon.ProcessCredentials.user_ns:type_name -> tetragon.UserNamespace 44, // 33: tetragon.BinaryProperties.setuid:type_name -> google.protobuf.UInt32Value 44, // 34: tetragon.BinaryProperties.setgid:type_name -> google.protobuf.UInt32Value - 44, // 35: tetragon.Process.pid:type_name -> google.protobuf.UInt32Value - 44, // 36: tetragon.Process.uid:type_name -> google.protobuf.UInt32Value - 43, // 37: tetragon.Process.start_time:type_name -> google.protobuf.Timestamp - 44, // 38: tetragon.Process.auid:type_name -> google.protobuf.UInt32Value - 6, // 39: tetragon.Process.pod:type_name -> tetragon.Pod - 7, // 40: tetragon.Process.cap:type_name -> tetragon.Capabilities - 9, // 41: tetragon.Process.ns:type_name -> tetragon.Namespaces - 44, // 42: tetragon.Process.tid:type_name -> google.protobuf.UInt32Value - 11, // 43: tetragon.Process.process_credentials:type_name -> tetragon.ProcessCredentials - 12, // 44: tetragon.Process.binary_properties:type_name -> tetragon.BinaryProperties - 13, // 45: tetragon.ProcessExec.process:type_name -> tetragon.Process - 13, // 46: tetragon.ProcessExec.parent:type_name -> tetragon.Process - 13, // 47: tetragon.ProcessExec.ancestors:type_name -> tetragon.Process - 13, // 48: tetragon.ProcessExit.process:type_name -> tetragon.Process - 13, // 49: tetragon.ProcessExit.parent:type_name -> tetragon.Process - 43, // 50: tetragon.ProcessExit.time:type_name -> google.protobuf.Timestamp - 45, // 51: tetragon.KprobeCred.permitted:type_name -> tetragon.CapabilitiesType - 45, // 52: tetragon.KprobeCred.effective:type_name -> tetragon.CapabilitiesType - 45, // 53: tetragon.KprobeCred.inheritable:type_name -> tetragon.CapabilitiesType - 46, // 54: tetragon.KprobeCapability.value:type_name -> google.protobuf.Int32Value - 46, // 55: tetragon.KprobeUserNamespace.level:type_name -> google.protobuf.Int32Value - 44, // 56: tetragon.KprobeUserNamespace.owner:type_name -> google.protobuf.UInt32Value - 44, // 57: tetragon.KprobeUserNamespace.group:type_name -> google.protobuf.UInt32Value - 8, // 58: tetragon.KprobeUserNamespace.ns:type_name -> tetragon.Namespace - 17, // 59: tetragon.KprobeArgument.skb_arg:type_name -> tetragon.KprobeSkb - 18, // 60: tetragon.KprobeArgument.path_arg:type_name -> tetragon.KprobePath - 19, // 61: tetragon.KprobeArgument.file_arg:type_name -> tetragon.KprobeFile - 20, // 62: tetragon.KprobeArgument.truncated_bytes_arg:type_name -> tetragon.KprobeTruncatedBytes - 16, // 63: tetragon.KprobeArgument.sock_arg:type_name -> tetragon.KprobeSock - 21, // 64: tetragon.KprobeArgument.cred_arg:type_name -> tetragon.KprobeCred - 24, // 65: tetragon.KprobeArgument.bpf_attr_arg:type_name -> tetragon.KprobeBpfAttr - 25, // 66: tetragon.KprobeArgument.perf_event_arg:type_name -> tetragon.KprobePerfEvent - 26, // 67: tetragon.KprobeArgument.bpf_map_arg:type_name -> tetragon.KprobeBpfMap - 23, // 68: tetragon.KprobeArgument.user_namespace_arg:type_name -> tetragon.KprobeUserNamespace - 22, // 69: tetragon.KprobeArgument.capability_arg:type_name -> tetragon.KprobeCapability - 11, // 70: tetragon.KprobeArgument.process_credentials_arg:type_name -> tetragon.ProcessCredentials - 10, // 71: tetragon.KprobeArgument.user_ns_arg:type_name -> tetragon.UserNamespace - 31, // 72: tetragon.KprobeArgument.module_arg:type_name -> tetragon.KernelModule - 13, // 73: tetragon.ProcessKprobe.process:type_name -> tetragon.Process - 13, // 74: tetragon.ProcessKprobe.parent:type_name -> tetragon.Process - 27, // 75: tetragon.ProcessKprobe.args:type_name -> tetragon.KprobeArgument - 27, // 76: tetragon.ProcessKprobe.return:type_name -> tetragon.KprobeArgument - 0, // 77: tetragon.ProcessKprobe.action:type_name -> tetragon.KprobeAction - 40, // 78: tetragon.ProcessKprobe.stack_trace:type_name -> tetragon.StackTraceEntry - 0, // 79: tetragon.ProcessKprobe.return_action:type_name -> tetragon.KprobeAction - 13, // 80: tetragon.ProcessTracepoint.process:type_name -> tetragon.Process - 13, // 81: tetragon.ProcessTracepoint.parent:type_name -> tetragon.Process - 27, // 82: tetragon.ProcessTracepoint.args:type_name -> tetragon.KprobeArgument - 0, // 83: tetragon.ProcessTracepoint.action:type_name -> tetragon.KprobeAction - 13, // 84: tetragon.ProcessUprobe.process:type_name -> tetragon.Process - 13, // 85: tetragon.ProcessUprobe.parent:type_name -> tetragon.Process - 48, // 86: tetragon.KernelModule.signature_ok:type_name -> google.protobuf.BoolValue - 3, // 87: tetragon.KernelModule.tainted:type_name -> tetragon.TaintedBitsType - 1, // 88: tetragon.GetHealthStatusRequest.event_set:type_name -> tetragon.HealthStatusType - 1, // 89: tetragon.HealthStatus.event:type_name -> tetragon.HealthStatusType - 2, // 90: tetragon.HealthStatus.status:type_name -> tetragon.HealthStatusResult - 34, // 91: tetragon.GetHealthStatusResponse.health_status:type_name -> tetragon.HealthStatus - 13, // 92: tetragon.ProcessLoader.process:type_name -> tetragon.Process - 39, // 93: tetragon.RuntimeHookRequest.createContainer:type_name -> tetragon.CreateContainer - 42, // 94: tetragon.CreateContainer.annotations:type_name -> tetragon.CreateContainer.AnnotationsEntry - 95, // [95:95] is the sub-list for method output_type - 95, // [95:95] is the sub-list for method input_type - 95, // [95:95] is the sub-list for extension type_name - 95, // [95:95] is the sub-list for extension extendee - 0, // [0:95] is the sub-list for field type_name + 48, // 35: tetragon.BinaryProperties.privileges_changed:type_name -> tetragon.ProcessPrivilegesChanged + 44, // 36: tetragon.Process.pid:type_name -> google.protobuf.UInt32Value + 44, // 37: tetragon.Process.uid:type_name -> google.protobuf.UInt32Value + 43, // 38: tetragon.Process.start_time:type_name -> google.protobuf.Timestamp + 44, // 39: tetragon.Process.auid:type_name -> google.protobuf.UInt32Value + 6, // 40: tetragon.Process.pod:type_name -> tetragon.Pod + 7, // 41: tetragon.Process.cap:type_name -> tetragon.Capabilities + 9, // 42: tetragon.Process.ns:type_name -> tetragon.Namespaces + 44, // 43: tetragon.Process.tid:type_name -> google.protobuf.UInt32Value + 11, // 44: tetragon.Process.process_credentials:type_name -> tetragon.ProcessCredentials + 12, // 45: tetragon.Process.binary_properties:type_name -> tetragon.BinaryProperties + 13, // 46: tetragon.ProcessExec.process:type_name -> tetragon.Process + 13, // 47: tetragon.ProcessExec.parent:type_name -> tetragon.Process + 13, // 48: tetragon.ProcessExec.ancestors:type_name -> tetragon.Process + 13, // 49: tetragon.ProcessExit.process:type_name -> tetragon.Process + 13, // 50: tetragon.ProcessExit.parent:type_name -> tetragon.Process + 43, // 51: tetragon.ProcessExit.time:type_name -> google.protobuf.Timestamp + 45, // 52: tetragon.KprobeCred.permitted:type_name -> tetragon.CapabilitiesType + 45, // 53: tetragon.KprobeCred.effective:type_name -> tetragon.CapabilitiesType + 45, // 54: tetragon.KprobeCred.inheritable:type_name -> tetragon.CapabilitiesType + 46, // 55: tetragon.KprobeCapability.value:type_name -> google.protobuf.Int32Value + 46, // 56: tetragon.KprobeUserNamespace.level:type_name -> google.protobuf.Int32Value + 44, // 57: tetragon.KprobeUserNamespace.owner:type_name -> google.protobuf.UInt32Value + 44, // 58: tetragon.KprobeUserNamespace.group:type_name -> google.protobuf.UInt32Value + 8, // 59: tetragon.KprobeUserNamespace.ns:type_name -> tetragon.Namespace + 17, // 60: tetragon.KprobeArgument.skb_arg:type_name -> tetragon.KprobeSkb + 18, // 61: tetragon.KprobeArgument.path_arg:type_name -> tetragon.KprobePath + 19, // 62: tetragon.KprobeArgument.file_arg:type_name -> tetragon.KprobeFile + 20, // 63: tetragon.KprobeArgument.truncated_bytes_arg:type_name -> tetragon.KprobeTruncatedBytes + 16, // 64: tetragon.KprobeArgument.sock_arg:type_name -> tetragon.KprobeSock + 21, // 65: tetragon.KprobeArgument.cred_arg:type_name -> tetragon.KprobeCred + 24, // 66: tetragon.KprobeArgument.bpf_attr_arg:type_name -> tetragon.KprobeBpfAttr + 25, // 67: tetragon.KprobeArgument.perf_event_arg:type_name -> tetragon.KprobePerfEvent + 26, // 68: tetragon.KprobeArgument.bpf_map_arg:type_name -> tetragon.KprobeBpfMap + 23, // 69: tetragon.KprobeArgument.user_namespace_arg:type_name -> tetragon.KprobeUserNamespace + 22, // 70: tetragon.KprobeArgument.capability_arg:type_name -> tetragon.KprobeCapability + 11, // 71: tetragon.KprobeArgument.process_credentials_arg:type_name -> tetragon.ProcessCredentials + 10, // 72: tetragon.KprobeArgument.user_ns_arg:type_name -> tetragon.UserNamespace + 31, // 73: tetragon.KprobeArgument.module_arg:type_name -> tetragon.KernelModule + 13, // 74: tetragon.ProcessKprobe.process:type_name -> tetragon.Process + 13, // 75: tetragon.ProcessKprobe.parent:type_name -> tetragon.Process + 27, // 76: tetragon.ProcessKprobe.args:type_name -> tetragon.KprobeArgument + 27, // 77: tetragon.ProcessKprobe.return:type_name -> tetragon.KprobeArgument + 0, // 78: tetragon.ProcessKprobe.action:type_name -> tetragon.KprobeAction + 40, // 79: tetragon.ProcessKprobe.stack_trace:type_name -> tetragon.StackTraceEntry + 0, // 80: tetragon.ProcessKprobe.return_action:type_name -> tetragon.KprobeAction + 13, // 81: tetragon.ProcessTracepoint.process:type_name -> tetragon.Process + 13, // 82: tetragon.ProcessTracepoint.parent:type_name -> tetragon.Process + 27, // 83: tetragon.ProcessTracepoint.args:type_name -> tetragon.KprobeArgument + 0, // 84: tetragon.ProcessTracepoint.action:type_name -> tetragon.KprobeAction + 13, // 85: tetragon.ProcessUprobe.process:type_name -> tetragon.Process + 13, // 86: tetragon.ProcessUprobe.parent:type_name -> tetragon.Process + 49, // 87: tetragon.KernelModule.signature_ok:type_name -> google.protobuf.BoolValue + 3, // 88: tetragon.KernelModule.tainted:type_name -> tetragon.TaintedBitsType + 1, // 89: tetragon.GetHealthStatusRequest.event_set:type_name -> tetragon.HealthStatusType + 1, // 90: tetragon.HealthStatus.event:type_name -> tetragon.HealthStatusType + 2, // 91: tetragon.HealthStatus.status:type_name -> tetragon.HealthStatusResult + 34, // 92: tetragon.GetHealthStatusResponse.health_status:type_name -> tetragon.HealthStatus + 13, // 93: tetragon.ProcessLoader.process:type_name -> tetragon.Process + 39, // 94: tetragon.RuntimeHookRequest.createContainer:type_name -> tetragon.CreateContainer + 42, // 95: tetragon.CreateContainer.annotations:type_name -> tetragon.CreateContainer.AnnotationsEntry + 96, // [96:96] is the sub-list for method output_type + 96, // [96:96] is the sub-list for method input_type + 96, // [96:96] is the sub-list for extension type_name + 96, // [96:96] is the sub-list for extension extendee + 0, // [0:96] is the sub-list for field type_name } func init() { file_tetragon_tetragon_proto_init() } diff --git a/api/v1/tetragon/tetragon.proto b/api/v1/tetragon/tetragon.proto index 70b52f6a924..ad0bf214197 100644 --- a/api/v1/tetragon/tetragon.proto +++ b/api/v1/tetragon/tetragon.proto @@ -141,6 +141,10 @@ message BinaryProperties { google.protobuf.UInt32Value setuid = 1; // If set then this is the set group ID used for execution google.protobuf.UInt32Value setgid = 2; + // The reasons why this binary execution changed privileges. Usually this happens when the process executes + // a binary with the set-user-ID to root or file capability sets. + // The final granted privileges can be listed inside the `process_credentials` or capabilities fields part of of the `process` object. + repeated ProcessPrivilegesChanged privileges_changed = 3; } message Process { @@ -427,6 +431,8 @@ message ProcessKprobe { string policy_name = 8; // Action performed when the return kprobe executed. KprobeAction return_action = 9; + // Short message of the Tracing Policy to inform users what is going on. + string message = 10; } message ProcessTracepoint { @@ -445,6 +451,8 @@ message ProcessTracepoint { string policy_name = 7; // Action performed when the tracepoint matched. KprobeAction action = 8; + // Short message of the Tracing Policy to inform users what is going on. + string message = 9; } message ProcessUprobe { @@ -454,6 +462,8 @@ message ProcessUprobe { string symbol = 4; // Name of the policy that created that uprobe. string policy_name = 5; + // Short message of the Tracing Policy to inform users what is going on. + string message = 6; } message KernelModule { diff --git a/api/vendor/golang.org/x/sys/unix/mkerrors.sh b/api/vendor/golang.org/x/sys/unix/mkerrors.sh index 6202638bae8..c6492020ec7 100644 --- a/api/vendor/golang.org/x/sys/unix/mkerrors.sh +++ b/api/vendor/golang.org/x/sys/unix/mkerrors.sh @@ -248,6 +248,7 @@ struct ltchars { #include #include #include +#include #include #include #include @@ -283,10 +284,6 @@ struct ltchars { #include #endif -#ifndef MSG_FASTOPEN -#define MSG_FASTOPEN 0x20000000 -#endif - #ifndef PTRACE_GETREGS #define PTRACE_GETREGS 0xc #endif @@ -295,14 +292,6 @@ struct ltchars { #define PTRACE_SETREGS 0xd #endif -#ifndef SOL_NETLINK -#define SOL_NETLINK 270 -#endif - -#ifndef SOL_SMC -#define SOL_SMC 286 -#endif - #ifdef SOL_BLUETOOTH // SPARC includes this in /usr/include/sparc64-linux-gnu/bits/socket.h // but it is already in bluetooth_linux.go @@ -319,10 +308,23 @@ struct ltchars { #undef TIPC_WAIT_FOREVER #define TIPC_WAIT_FOREVER 0xffffffff -// Copied from linux/l2tp.h -// Including linux/l2tp.h here causes conflicts between linux/in.h -// and netinet/in.h included via net/route.h above. -#define IPPROTO_L2TP 115 +// Copied from linux/netfilter/nf_nat.h +// Including linux/netfilter/nf_nat.h here causes conflicts between linux/in.h +// and netinet/in.h. +#define NF_NAT_RANGE_MAP_IPS (1 << 0) +#define NF_NAT_RANGE_PROTO_SPECIFIED (1 << 1) +#define NF_NAT_RANGE_PROTO_RANDOM (1 << 2) +#define NF_NAT_RANGE_PERSISTENT (1 << 3) +#define NF_NAT_RANGE_PROTO_RANDOM_FULLY (1 << 4) +#define NF_NAT_RANGE_PROTO_OFFSET (1 << 5) +#define NF_NAT_RANGE_NETMAP (1 << 6) +#define NF_NAT_RANGE_PROTO_RANDOM_ALL \ + (NF_NAT_RANGE_PROTO_RANDOM | NF_NAT_RANGE_PROTO_RANDOM_FULLY) +#define NF_NAT_RANGE_MASK \ + (NF_NAT_RANGE_MAP_IPS | NF_NAT_RANGE_PROTO_SPECIFIED | \ + NF_NAT_RANGE_PROTO_RANDOM | NF_NAT_RANGE_PERSISTENT | \ + NF_NAT_RANGE_PROTO_RANDOM_FULLY | NF_NAT_RANGE_PROTO_OFFSET | \ + NF_NAT_RANGE_NETMAP) // Copied from linux/hid.h. // Keep in sync with the size of the referenced fields. @@ -603,6 +605,9 @@ ccflags="$@" $2 ~ /^FSOPT_/ || $2 ~ /^WDIO[CFS]_/ || $2 ~ /^NFN/ || + $2 !~ /^NFT_META_IIFTYPE/ && + $2 ~ /^NFT_/ || + $2 ~ /^NF_NAT_/ || $2 ~ /^XDP_/ || $2 ~ /^RWF_/ || $2 ~ /^(HDIO|WIN|SMART)_/ || diff --git a/api/vendor/golang.org/x/sys/unix/zerrors_linux.go b/api/vendor/golang.org/x/sys/unix/zerrors_linux.go index c73cfe2f10b..a5d3ff8df95 100644 --- a/api/vendor/golang.org/x/sys/unix/zerrors_linux.go +++ b/api/vendor/golang.org/x/sys/unix/zerrors_linux.go @@ -2127,6 +2127,60 @@ const ( NFNL_SUBSYS_QUEUE = 0x3 NFNL_SUBSYS_ULOG = 0x4 NFS_SUPER_MAGIC = 0x6969 + NFT_CHAIN_FLAGS = 0x7 + NFT_CHAIN_MAXNAMELEN = 0x100 + NFT_CT_MAX = 0x17 + NFT_DATA_RESERVED_MASK = 0xffffff00 + NFT_DATA_VALUE_MAXLEN = 0x40 + NFT_EXTHDR_OP_MAX = 0x4 + NFT_FIB_RESULT_MAX = 0x3 + NFT_INNER_MASK = 0xf + NFT_LOGLEVEL_MAX = 0x8 + NFT_NAME_MAXLEN = 0x100 + NFT_NG_MAX = 0x1 + NFT_OBJECT_CONNLIMIT = 0x5 + NFT_OBJECT_COUNTER = 0x1 + NFT_OBJECT_CT_EXPECT = 0x9 + NFT_OBJECT_CT_HELPER = 0x3 + NFT_OBJECT_CT_TIMEOUT = 0x7 + NFT_OBJECT_LIMIT = 0x4 + NFT_OBJECT_MAX = 0xa + NFT_OBJECT_QUOTA = 0x2 + NFT_OBJECT_SECMARK = 0x8 + NFT_OBJECT_SYNPROXY = 0xa + NFT_OBJECT_TUNNEL = 0x6 + NFT_OBJECT_UNSPEC = 0x0 + NFT_OBJ_MAXNAMELEN = 0x100 + NFT_OSF_MAXGENRELEN = 0x10 + NFT_QUEUE_FLAG_BYPASS = 0x1 + NFT_QUEUE_FLAG_CPU_FANOUT = 0x2 + NFT_QUEUE_FLAG_MASK = 0x3 + NFT_REG32_COUNT = 0x10 + NFT_REG32_SIZE = 0x4 + NFT_REG_MAX = 0x4 + NFT_REG_SIZE = 0x10 + NFT_REJECT_ICMPX_MAX = 0x3 + NFT_RT_MAX = 0x4 + NFT_SECMARK_CTX_MAXLEN = 0x100 + NFT_SET_MAXNAMELEN = 0x100 + NFT_SOCKET_MAX = 0x3 + NFT_TABLE_F_MASK = 0x3 + NFT_TABLE_MAXNAMELEN = 0x100 + NFT_TRACETYPE_MAX = 0x3 + NFT_TUNNEL_F_MASK = 0x7 + NFT_TUNNEL_MAX = 0x1 + NFT_TUNNEL_MODE_MAX = 0x2 + NFT_USERDATA_MAXLEN = 0x100 + NFT_XFRM_KEY_MAX = 0x6 + NF_NAT_RANGE_MAP_IPS = 0x1 + NF_NAT_RANGE_MASK = 0x7f + NF_NAT_RANGE_NETMAP = 0x40 + NF_NAT_RANGE_PERSISTENT = 0x8 + NF_NAT_RANGE_PROTO_OFFSET = 0x20 + NF_NAT_RANGE_PROTO_RANDOM = 0x4 + NF_NAT_RANGE_PROTO_RANDOM_ALL = 0x14 + NF_NAT_RANGE_PROTO_RANDOM_FULLY = 0x10 + NF_NAT_RANGE_PROTO_SPECIFIED = 0x2 NILFS_SUPER_MAGIC = 0x3434 NL0 = 0x0 NL1 = 0x100 diff --git a/api/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go b/api/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go index a1d061597cc..9dc42410b78 100644 --- a/api/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go +++ b/api/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/api/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go b/api/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go index 5b2a7409778..0d3a0751cd4 100644 --- a/api/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go +++ b/api/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/api/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go b/api/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go index f6eda1344a8..c39f7776db3 100644 --- a/api/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go +++ b/api/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/api/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go b/api/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go index 55df20ae9d8..57571d072fe 100644 --- a/api/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go +++ b/api/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/api/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go b/api/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go index 8c1155cbc08..e62963e67e2 100644 --- a/api/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go +++ b/api/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/api/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go b/api/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go index 7cc80c58d98..00831354c82 100644 --- a/api/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go +++ b/api/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/api/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go b/api/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go index 0688737f494..79029ed5848 100644 --- a/api/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go +++ b/api/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/api/vendor/golang.org/x/sys/windows/syscall_windows.go b/api/vendor/golang.org/x/sys/windows/syscall_windows.go index 47dc5796769..ffb8708ccf8 100644 --- a/api/vendor/golang.org/x/sys/windows/syscall_windows.go +++ b/api/vendor/golang.org/x/sys/windows/syscall_windows.go @@ -194,6 +194,7 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys GetComputerName(buf *uint16, n *uint32) (err error) = GetComputerNameW //sys GetComputerNameEx(nametype uint32, buf *uint16, n *uint32) (err error) = GetComputerNameExW //sys SetEndOfFile(handle Handle) (err error) +//sys SetFileValidData(handle Handle, validDataLength int64) (err error) //sys GetSystemTimeAsFileTime(time *Filetime) //sys GetSystemTimePreciseAsFileTime(time *Filetime) //sys GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) [failretval==0xffffffff] diff --git a/api/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/api/vendor/golang.org/x/sys/windows/zsyscall_windows.go index 146a1f0196f..e8791c82c30 100644 --- a/api/vendor/golang.org/x/sys/windows/zsyscall_windows.go +++ b/api/vendor/golang.org/x/sys/windows/zsyscall_windows.go @@ -342,6 +342,7 @@ var ( procSetDefaultDllDirectories = modkernel32.NewProc("SetDefaultDllDirectories") procSetDllDirectoryW = modkernel32.NewProc("SetDllDirectoryW") procSetEndOfFile = modkernel32.NewProc("SetEndOfFile") + procSetFileValidData = modkernel32.NewProc("SetFileValidData") procSetEnvironmentVariableW = modkernel32.NewProc("SetEnvironmentVariableW") procSetErrorMode = modkernel32.NewProc("SetErrorMode") procSetEvent = modkernel32.NewProc("SetEvent") @@ -2988,6 +2989,14 @@ func SetEndOfFile(handle Handle) (err error) { return } +func SetFileValidData(handle Handle, validDataLength int64) (err error) { + r1, _, e1 := syscall.Syscall(procSetFileValidData.Addr(), 2, uintptr(handle), uintptr(validDataLength), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func SetEnvironmentVariable(name *uint16, value *uint16) (err error) { r1, _, e1 := syscall.Syscall(procSetEnvironmentVariableW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(value)), 0) if r1 == 0 { diff --git a/api/vendor/modules.txt b/api/vendor/modules.txt index 9f7b756ca17..d9a994649a4 100644 --- a/api/vendor/modules.txt +++ b/api/vendor/modules.txt @@ -32,7 +32,7 @@ golang.org/x/net/http2/hpack golang.org/x/net/idna golang.org/x/net/internal/timeseries golang.org/x/net/trace -# golang.org/x/sys v0.15.0 +# golang.org/x/sys v0.16.0 ## explicit; go 1.18 golang.org/x/sys/unix golang.org/x/sys/windows diff --git a/bpf/lib/bpf_cred.h b/bpf/lib/bpf_cred.h index f847521bc0c..ea3bcd2fc80 100644 --- a/bpf/lib/bpf_cred.h +++ b/bpf/lib/bpf_cred.h @@ -69,4 +69,38 @@ struct msg_cred_minimal { __u32 pad; } __attribute__((packed)); +/* Execution and cred related flags shared with userspace */ +#define EXEC_SETUID 0x01 /* This is a set-user-id execution */ +#define EXEC_SETGID 0x02 /* This is a set-group-id execution */ +#define EXEC_FILE_CAPS 0x04 /* This binary execution gained new capabilities through file capabilities execution */ +#define EXEC_SETUID_ROOT 0x08 /* This binary execution gained new privileges through setuid to root execution */ +#define EXEC_SETGID_ROOT 0x10 /* This binary execution gained new privileges through setgid to root execution */ + +/* + * Check if "a" is a subset of "set". + * return true if all of the capabilities in "a" are also in "set" + * __cap_issubset(0100, 1111) will return true + * return false if any of the capabilities in "a" are not in "set" + * __cap_issubset(1111, 0100) will return false + */ +static inline __attribute__((always_inline)) bool +__cap_issubset(const __u64 a, const __u64 set) +{ + return !(a & ~set); +} + +#define __cap_gained(target, source) \ + !__cap_issubset(target, source) + +/* + * We check if it user id is global root. Right now we do not + * support per user namespace translation, example checking if + * root in user namespace. + */ +static inline __attribute__((always_inline)) bool +__is_uid_global_root(__u32 uid) +{ + return uid == 0; +} + #endif diff --git a/bpf/lib/generic.h b/bpf/lib/generic.h index 19d00d5cab1..ea31582e04d 100644 --- a/bpf/lib/generic.h +++ b/bpf/lib/generic.h @@ -51,7 +51,8 @@ struct msg_generic_kprobe { long argsoff[MAX_POSSIBLE_ARGS]; struct msg_selector_data sel; __u32 idx; // attach cookie index - __u32 filter_tailcall_index; // recursion index for filter_read_arg/generic_process_event + __u32 tailcall_index_process; // recursion index for generic_process_event + __u32 tailcall_index_selector; // recursion index for filter_read_arg int pass; }; diff --git a/bpf/lib/process.h b/bpf/lib/process.h index d9a3d6ffbee..95749820cfd 100644 --- a/bpf/lib/process.h +++ b/bpf/lib/process.h @@ -155,10 +155,6 @@ struct msg_execve_key { __u64 ktime; }; // All fields aligned so no 'packed' attribute. -/* Execution and cred related flags shared with userspace */ -#define EXEC_SETUID 0x01 /* This is a set-user-id execution */ -#define EXEC_SETGID 0x02 /* This is a set-group-id execution */ - /* This is the struct stored in bpf map to share info between * different execve hooks. */ diff --git a/bpf/process/bpf_execve_bprm_commit_creds.c b/bpf/process/bpf_execve_bprm_commit_creds.c index 0dba18c8adf..e65cdbaa891 100644 --- a/bpf/process/bpf_execve_bprm_commit_creds.c +++ b/bpf/process/bpf_execve_bprm_commit_creds.c @@ -19,6 +19,9 @@ char _license[] __attribute__((section("license"), used)) = "Dual BSD/GPL"; * current task part of the execve call. * For such case this hook must be when we are committing the new credentials * to the task being executed. + * For such the hook must run after: + * bprm_creds_from_file() + * |__cap_bprm_creds_from_file() capability LSM where the bprm is properly set. * * It reads the linux_bprm->per_clear flags that are the personality flags to clear * when we are executing a privilged program. Normally we should check the @@ -46,8 +49,8 @@ BPF_KPROBE(tg_kp_bprm_committing_creds, struct linux_binprm *bprm) struct execve_map_value *curr; struct execve_heap *heap; struct task_struct *task; - __u32 pid, euid, uid, egid, gid, sec = 0, zero = 0; - __u64 tid; + __u32 pid, ruid, euid, uid, egid, gid, sec = 0, zero = 0; + __u64 tid, permitted, new_permitted, new_ambient = 0; sec = BPF_CORE_READ(bprm, per_clear); /* If no flags to clear then this is not a privileged execution */ @@ -76,11 +79,67 @@ BPF_KPROBE(tg_kp_bprm_committing_creds, struct linux_binprm *bprm) gid = BPF_CORE_READ(task, cred, gid.val); /* Is setuid? */ - if (euid != uid) + if (euid != uid) { heap->info.secureexec |= EXEC_SETUID; + /* If euid is being changed to root? */ + ruid = BPF_CORE_READ(bprm, cred, uid.val); + if (!__is_uid_global_root(ruid) && __is_uid_global_root(euid)) + /* If we executed from a non root and became global effective root + * then set the EXEC_FS_SETUID to indicate that there was a privilege + * elevation through binary suid root. + * Now it is possible that the root 0 does not have capabilities + * meaning it is running with SECURE_NOROOT Sec bit set, but we still + * handle it as privileged change since running with uid root allows + * to access files, ptrace root binaries, etc. From Tetragon euid==0 + * is still raising privileges. + * + * Note: there is the case of a uid being in a user namespace + * and it is mapped to uid 0 root inside that namespace that we do + * not detect now, since we do not do user ids translation into + * user namespaces. For such case we may not report if the binary + * gained privileges through setuid. To be fixed in the future. + */ + heap->info.secureexec |= EXEC_SETUID_ROOT; + } /* Is setgid? */ - if (egid != gid) + if (egid != gid) { heap->info.secureexec |= EXEC_SETGID; + /* Is egid is being changed to real root? */ + gid = BPF_CORE_READ(bprm, cred, gid.val); + if (!__is_uid_global_root(gid) && __is_uid_global_root(egid)) + /* If we executed a setgid to root binary then this is a + * privilege elevation since it can now access root files, etc + */ + heap->info.secureexec |= EXEC_SETGID_ROOT; + } + + /* Ensure that ambient capabilities are not set since they clash with: + * setuid/setgid on the binary. + * file capabilities on the binary. + * + * This is an extra guard. Since if the new ambient capabilities are set then + * there is no way the binary could provide extra capabilities, they cancel + * each other. + */ + BPF_CORE_READ_INTO(&new_ambient, bprm, cred, cap_ambient); + if (new_ambient) + return; + + /* Did we gain new capabilities through execve? + * + * To determin if we gained new capabilities we compare the current permitted + * set with the new set. This can happen if: + * (1) The setuid of binary is the _mapped_ root id in current or parent owning namespace. + * This is already handled above in the setuid code path. + * (2) The file capabilities are set on the binary. If the setuid bit is not set + * then the gained capabilities are from file capabilities execution. + */ + BPF_CORE_READ_INTO(&permitted, task, cred, cap_permitted); + BPF_CORE_READ_INTO(&new_permitted, bprm, cred, cap_permitted); + if (__cap_gained(new_permitted, permitted) && euid == uid) { + /* If the setuid bit is not set then this is probably a file cap execution. */ + heap->info.secureexec |= EXEC_FILE_CAPS; + } /* Do we cache the entry? */ if (heap->info.secureexec != 0) diff --git a/bpf/process/bpf_generic_kprobe.c b/bpf/process/bpf_generic_kprobe.c index d0980991e97..95beabadb49 100644 --- a/bpf/process/bpf_generic_kprobe.c +++ b/bpf/process/bpf_generic_kprobe.c @@ -86,8 +86,6 @@ generic_kprobe_start_process_filter(void *ctx) config = map_lookup_elem(&config_map, &msg->idx); if (!config) return 0; - if (!generic_process_filter_binary(config)) - return 0; if (!policy_filter_check(config->policy_id)) return 0; msg->func_id = config->func_id; @@ -99,7 +97,8 @@ generic_kprobe_start_process_filter(void *ctx) msg->sel.active[i] = 0; /* Initialize accept field to reject */ msg->sel.pass = false; - msg->filter_tailcall_index = 0; + msg->tailcall_index_process = 0; + msg->tailcall_index_selector = 0; task = (struct task_struct *)get_current_task(); /* Initialize namespaces to apply filters on them */ get_namespaces(&(msg->ns), task); diff --git a/bpf/process/bpf_generic_tracepoint.c b/bpf/process/bpf_generic_tracepoint.c index 9c05ea1f0f7..bab84891bdb 100644 --- a/bpf/process/bpf_generic_tracepoint.c +++ b/bpf/process/bpf_generic_tracepoint.c @@ -125,9 +125,6 @@ generic_tracepoint_event(struct generic_tracepoint_event_arg *ctx) if (!config) return 0; - if (!generic_process_filter_binary(config)) - return 0; - /* check policy filter */ if (!policy_filter_check(config->policy_id)) return 0; @@ -181,7 +178,8 @@ generic_tracepoint_event(struct generic_tracepoint_event_arg *ctx) msg->common.op = MSG_OP_GENERIC_TRACEPOINT; msg->sel.curr = 0; - msg->filter_tailcall_index = 0; + msg->tailcall_index_process = 0; + msg->tailcall_index_selector = 0; #pragma unroll for (i = 0; i < MAX_CONFIGURED_SELECTORS; i++) msg->sel.active[i] = 0; diff --git a/bpf/process/bpf_generic_uprobe.c b/bpf/process/bpf_generic_uprobe.c index 862c07deb1a..9f05b5471f3 100644 --- a/bpf/process/bpf_generic_uprobe.c +++ b/bpf/process/bpf_generic_uprobe.c @@ -67,7 +67,8 @@ generic_uprobe_start_process_filter(void *ctx) msg->sel.active[i] = 0; /* Initialize accept field to reject */ msg->sel.pass = false; - msg->filter_tailcall_index = 0; + msg->tailcall_index_process = 0; + msg->tailcall_index_selector = 0; task = (struct task_struct *)get_current_task(); /* Initialize namespaces to apply filters on them */ get_namespaces(&msg->ns, task); @@ -86,8 +87,6 @@ generic_uprobe_start_process_filter(void *ctx) msg->idx = 0; msg->func_id = config->func_id; msg->retprobe_id = 0; - if (!generic_process_filter_binary(config)) - return 0; /* Tail call into filters. */ tail_call(ctx, &uprobe_calls, TAIL_CALL_FILTER); return 0; diff --git a/bpf/process/generic_calls.h b/bpf/process/generic_calls.h index a91ed0f195d..fea9bbb68f4 100644 --- a/bpf/process/generic_calls.h +++ b/bpf/process/generic_calls.h @@ -29,7 +29,7 @@ generic_process_event(void *ctx, struct bpf_map_def *heap_map, if (!config) return 0; - index = e->filter_tailcall_index; + index = e->tailcall_index_process; asm volatile("%[index] &= %1 ;\n" : [index] "+r"(index) : "i"(MAX_SELECTORS_MASK)); @@ -61,12 +61,12 @@ generic_process_event(void *ctx, struct bpf_map_def *heap_map, e->common.size = total; /* Continue to process other arguments. */ if (index < 4) { - e->filter_tailcall_index = index + 1; + e->tailcall_index_process = index + 1; tail_call(ctx, tailcals, TAIL_CALL_PROCESS); } /* Last argument, go send.. */ - e->filter_tailcall_index = 0; + e->tailcall_index_process = 0; tail_call(ctx, tailcals, TAIL_CALL_ARGS); return 0; } diff --git a/bpf/process/pfilter.h b/bpf/process/pfilter.h index 5da326b9238..d8daf84c237 100644 --- a/bpf/process/pfilter.h +++ b/bpf/process/pfilter.h @@ -396,6 +396,10 @@ selector_process_filter(__u32 *f, __u32 index, struct execve_map_value *enter, __u32 len; __u64 i; + /* Do binary filter first for selector index */ + if (!match_binaries(index)) + return 0; + /* Find selector offset byte index */ index *= 4; index += 4; diff --git a/bpf/process/types/basic.h b/bpf/process/types/basic.h index 624a8d578cf..879f087fede 100644 --- a/bpf/process/types/basic.h +++ b/bpf/process/types/basic.h @@ -123,8 +123,6 @@ struct selector_arg_filters { __u32 argoff[5]; } __attribute__((packed)); -#define FLAGS_EARLY_FILTER BIT(0) - #define IS_32BIT 0x80000000 struct event_config { @@ -1595,18 +1593,9 @@ static inline __attribute__((always_inline)) int match_binaries(__u32 selidx) return 1; } -static inline __attribute__((always_inline)) int -generic_process_filter_binary(struct event_config *config) -{ - /* single flag bit at the moment (FLAGS_EARLY_FILTER) */ - if (config->flags & FLAGS_EARLY_FILTER) - return match_binaries(0); - return 1; -} - static inline __attribute__((always_inline)) int selector_arg_offset(__u8 *f, struct msg_generic_kprobe *e, __u32 selidx, - bool early_binary_filter, bool is_entry) + bool is_entry) { struct selector_arg_filters *filters; struct selector_arg_filter *filter; @@ -1635,10 +1624,6 @@ selector_arg_offset(__u8 *f, struct msg_generic_kprobe *e, __u32 selidx, seloff += *(__u32 *)((__u64)f + (seloff & INDEX_MASK)); /* skip the matchCapabilityChanges by reading its length */ seloff += *(__u32 *)((__u64)f + (seloff & INDEX_MASK)); - - // check for match binary actions - if (!early_binary_filter && !match_binaries(selidx)) - return 0; } /* Making binary selectors fixes size helps on some kernels */ @@ -1723,8 +1708,8 @@ static inline __attribute__((always_inline)) int filter_args_reject(u64 id) } static inline __attribute__((always_inline)) int -filter_args(struct msg_generic_kprobe *e, int index, void *filter_map, - bool early_binary_filter, bool is_entry) +filter_args(struct msg_generic_kprobe *e, int selidx, void *filter_map, + bool is_entry) { __u8 *f; @@ -1742,11 +1727,11 @@ filter_args(struct msg_generic_kprobe *e, int index, void *filter_map, * events early. Now we need to ensure that active pid sselectors * have their arg filters run. */ - if (index > SELECTORS_ACTIVE) + if (selidx > SELECTORS_ACTIVE) return filter_args_reject(e->func_id); - if (e->sel.active[index]) { - int pass = selector_arg_offset(f, e, index, early_binary_filter, is_entry); + if (e->sel.active[selidx]) { + int pass = selector_arg_offset(f, e, selidx, is_entry); if (pass) return pass; } @@ -2220,22 +2205,17 @@ filter_read_arg(void *ctx, struct bpf_map_def *heap, struct bpf_map_def *config_map, bool is_entry) { struct msg_generic_kprobe *e; - struct event_config *config; - int index, pass, zero = 0; + int selidx, pass, zero = 0; e = map_lookup_elem(heap, &zero); if (!e) return 0; - config = map_lookup_elem(config_map, &e->idx); - if (!config) - return 0; - index = e->filter_tailcall_index; - pass = filter_args(e, index & MAX_SELECTORS_MASK, filter, - config->flags & FLAGS_EARLY_FILTER, is_entry); + selidx = e->tailcall_index_selector; + pass = filter_args(e, selidx & MAX_SELECTORS_MASK, filter, is_entry); if (!pass) { - index++; - if (index <= MAX_SELECTORS && e->sel.active[index & MAX_SELECTORS_MASK]) { - e->filter_tailcall_index = index; + selidx++; + if (selidx <= MAX_SELECTORS && e->sel.active[selidx & MAX_SELECTORS_MASK]) { + e->tailcall_index_selector = selidx; tail_call(ctx, tailcalls, TAIL_CALL_ARGS); } // reject if we did not attempt to tailcall, or if tailcall failed. diff --git a/cmd/tetragon-vmtests-run/conf.go b/cmd/tetragon-vmtests-run/conf.go index 97f514ed7c4..482dcadeeb7 100644 --- a/cmd/tetragon-vmtests-run/conf.go +++ b/cmd/tetragon-vmtests-run/conf.go @@ -27,6 +27,8 @@ type RunConf struct { disableUnifiedCgroups bool portForwards runner.PortForwards testerConf vmtests.Conf + detailedResults bool + keepAllLogs bool filesystems []QemuFS } diff --git a/cmd/tetragon-vmtests-run/main.go b/cmd/tetragon-vmtests-run/main.go index 922a4766e09..fa2f904d0a8 100644 --- a/cmd/tetragon-vmtests-run/main.go +++ b/cmd/tetragon-vmtests-run/main.go @@ -35,6 +35,12 @@ func main() { return fmt.Errorf("error parseing ports: %w", err) } + // Keep all logs if user asked for it, or if user asked for detailed results + // since we need the log files to generate them. + if rcnf.keepAllLogs || rcnf.detailedResults { + rcnf.testerConf.KeepAllLogs = true + } + // Hardcoded (for now): // mount cwd as cwd in the VM (this helps with contrib/test-progs paths) // set output to be /tester-tetragon.out. @@ -125,6 +131,11 @@ func main() { return errors.New("failed") } + if results.nrSkipedTests == results.nrTests { + fmt.Printf("All %d tests were skipped 🤔 (took: %s, skipped:%d)\n", results.nrTests, dur, results.nrSkipedTests) + return nil + } + fmt.Printf("All %d tests succeeded! 🎉🚢🍕 (took: %s, skipped:%d)\n", results.nrTests, dur, results.nrSkipedTests) return nil }, @@ -145,10 +156,11 @@ func main() { cmd.Flags().StringVar(&rcnf.testerConf.TestsFile, "testsfile", "", "list of tests to run") cmd.Flags().StringVar(&rcnf.btfFile, "btf-file", "", "BTF file to use.") cmd.Flags().BoolVar(&rcnf.testerConf.FailFast, "fail-fast", false, "Exit as soon as an error is encountered.") - cmd.Flags().BoolVar(&rcnf.testerConf.KeepAllLogs, "keep-all-logs", false, "Normally, logs are kept only for failed tests. This switch keeps all logs.") + cmd.Flags().BoolVar(&rcnf.keepAllLogs, "keep-all-logs", false, "Normally, logs are kept only for failed tests. This switch keeps all logs.") cmd.Flags().BoolVar(&rcnf.disableUnifiedCgroups, "disable-unified-cgroups", false, "boot with systemd.unified_cgroup_hierarchy=0.") cmd.Flags().StringArrayVarP(&ports, "port", "p", nil, "Forward a port (hostport[:vmport[:tcp|udp]])") cmd.Flags().StringVar(&rcnf.testerConf.KernelVer, "kernel-ver", "", "kenel version") + cmd.Flags().BoolVar(&rcnf.detailedResults, "enable-detailed-results", false, "produce detailed results") if err := cmd.Execute(); err != nil { os.Exit(1) diff --git a/cmd/tetragon-vmtests-run/run_tests.go b/cmd/tetragon-vmtests-run/run_tests.go index 601809d3ce3..2e190fb4bbf 100644 --- a/cmd/tetragon-vmtests-run/run_tests.go +++ b/cmd/tetragon-vmtests-run/run_tests.go @@ -5,6 +5,7 @@ package main import ( "bufio" + "bytes" "context" "encoding/json" "fmt" @@ -22,6 +23,7 @@ import ( type runTestsResults struct { nrTests, nrFailedTests, nrSkipedTests int + totalDuration time.Duration } func runTests( @@ -66,28 +68,153 @@ func runTests( results = append(results, result) } - var totalDuration time.Duration - errCnt := 0 - skipCnt := 0 + var out runTestsResults w := new(tabwriter.Writer) w.Init(os.Stdout, 0, 8, 0, '\t', 0) - for _, r := range results { - totalDuration += r.Duration - ok := "✅" - if r.Error { - ok = "❌" - errCnt++ - } else if r.Skip { - ok = "⏭️" - skipCnt++ + for _, res := range results { + // NB: res.Skip means that the test was never executed, so we cannot print detailed + // results. + if rcnf.detailedResults && res.Outfile != "" && !res.Skip { + updateResultsDetailed(w, &res, &out) + } else { + updateResultsSimple(w, &res, &out) } - fmt.Fprintf(w, "%s\t%s\t%s\t(%s)\n", ok, r.Name, r.Duration.Round(time.Millisecond), totalDuration.Round(time.Millisecond)) } w.Flush() - return &runTestsResults{ - nrTests: len(results), - nrFailedTests: errCnt, - nrSkipedTests: skipCnt, - }, nil + return &out, nil +} + +func updateResultsSimple(w io.Writer, res *vmtests.Result, out *runTestsResults) { + out.nrTests++ + out.totalDuration += res.Duration + ok := "✅" + if res.Error { + ok = "❌" + out.nrFailedTests++ + } else if res.Skip { + // "⏭️" + // ok = "\u23E9" + out.nrSkipedTests++ + } + fmt.Fprintf(w, "%s\t%s\t%s\t(%s)\n", ok, res.Name, res.Duration.Round(time.Millisecond), out.totalDuration.Round(time.Millisecond)) +} + +// see: https://pkg.go.dev/cmd/test2json +type TestEvent struct { + Time time.Time // encodes as an RFC3339-format string + Action string + Package string + Test string + Elapsed float64 // seconds + Output string +} + +func updateResultsDetailed(w io.Writer, res *vmtests.Result, out *runTestsResults) { + + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + f, err := os.Open(res.Outfile) + if err != nil { + fmt.Fprintf(os.Stderr, "Error openning %s: %v", res.Outfile, res) + updateResultsSimple(w, res, out) + return + } + defer f.Close() + + prog := "go" + // NB: we need -t to enable timestamps and get the Elapsed field + args := []string{"tool", "test2json", "-t"} + cmd := exec.CommandContext(ctx, prog, args...) + cmd.Stdin = f + output, err := cmd.CombinedOutput() + if err != nil { + fmt.Fprintf(os.Stderr, "Error executing test2json: %v", res) + updateResultsSimple(w, res, out) + return + } + buff := bytes.NewBuffer(output) + scanner := bufio.NewScanner(buff) + + var totalDuration time.Duration + + type detail struct { + name string + icon string + dur time.Duration + } + var details []detail + + nrTests := 0 + nrSkippedTests := 0 + nrFailedTests := 0 + for scanner.Scan() { + var tevent TestEvent + line := scanner.Bytes() + err := json.Unmarshal(line, &tevent) + if err != nil { + fmt.Fprintf(os.Stderr, "Error parsing: '%s': %v, bailing out", line, err) + updateResultsSimple(w, res, out) + return + } + if tevent.Test == "" { + continue + } + + var icon string + switch tevent.Action { + case "skip": + nrSkippedTests++ + // "⚡" + icon = "\u26a1" + case "pass": + icon = "✅" + case "fail": + nrFailedTests++ + icon = "❌" + default: + continue + } + + nrTests++ + dur := time.Duration(float64(time.Second) * tevent.Elapsed) + details = append(details, detail{name: tevent.Test, icon: icon, dur: dur}) + + } + + if err := scanner.Err(); err != nil { + fmt.Fprintf(os.Stderr, "Scanner failed: %v, bailing out", err) + updateResultsSimple(w, res, out) + return + } + + out.totalDuration += res.Duration + out.nrTests += nrTests + out.nrSkipedTests += nrSkippedTests + out.nrFailedTests += nrFailedTests + + icon := "✅" + if res.Error { + icon = "❌" + } else if nrSkippedTests == nrTests { + // "⚡" + icon = "\u26a1" + } else if nrFailedTests > 0 { + // NB(kkourt): res.Error should not be false + icon = "⁉️" + } + + fmt.Fprintf(w, "%s\t%s\t(total:%d failed:%d skipped:%d)\t%s\t%s\n", icon, res.Name, nrTests, nrFailedTests, nrSkippedTests, res.Duration, out.totalDuration) + if len(details) > 1 { + for i, detail := range details { + totalDuration += detail.dur + if i == len(details)-1 { + fmt.Fprintf(w, "└─%s\t%s\t%s\t(%s)\n", detail.icon, detail.name, detail.dur.Round(time.Millisecond), totalDuration) + } else { + fmt.Fprintf(w, "├─%s\t%s\t%s\t(%s)\n", detail.icon, detail.name, detail.dur.Round(time.Millisecond), totalDuration) + } + } + } + } diff --git a/contrib/rthooks/tetragon-oci-hook/vendor/github.com/cilium/tetragon/api/v1/tetragon/capabilities.pb.go b/contrib/rthooks/tetragon-oci-hook/vendor/github.com/cilium/tetragon/api/v1/tetragon/capabilities.pb.go index be5ac6df28b..0bade9a09cb 100644 --- a/contrib/rthooks/tetragon-oci-hook/vendor/github.com/cilium/tetragon/api/v1/tetragon/capabilities.pb.go +++ b/contrib/rthooks/tetragon-oci-hook/vendor/github.com/cilium/tetragon/api/v1/tetragon/capabilities.pb.go @@ -373,6 +373,58 @@ func (SecureBitsType) EnumDescriptor() ([]byte, []int) { return file_tetragon_capabilities_proto_rawDescGZIP(), []int{1} } +// Reasons of why the process privileges changed. +type ProcessPrivsChanged int32 + +const ( + ProcessPrivsChanged_PRIVS_UNSET ProcessPrivsChanged = 0 + // A privilege elevation happened due to the execution of a binary with file capabilities set. + ProcessPrivsChanged_PRIVS_RAISED_EXEC_FILE_CAP ProcessPrivsChanged = 1 + // A privilege elevation happened due to the execution of a binary with setuid to root. + ProcessPrivsChanged_PRIVS_RAISED_EXEC_FILE_SETUID ProcessPrivsChanged = 2 +) + +// Enum value maps for ProcessPrivsChanged. +var ( + ProcessPrivsChanged_name = map[int32]string{ + 0: "PRIVS_UNSET", + 1: "PRIVS_RAISED_EXEC_FILE_CAP", + 2: "PRIVS_RAISED_EXEC_FILE_SETUID", + } + ProcessPrivsChanged_value = map[string]int32{ + "PRIVS_UNSET": 0, + "PRIVS_RAISED_EXEC_FILE_CAP": 1, + "PRIVS_RAISED_EXEC_FILE_SETUID": 2, + } +) + +func (x ProcessPrivsChanged) Enum() *ProcessPrivsChanged { + p := new(ProcessPrivsChanged) + *p = x + return p +} + +func (x ProcessPrivsChanged) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ProcessPrivsChanged) Descriptor() protoreflect.EnumDescriptor { + return file_tetragon_capabilities_proto_enumTypes[2].Descriptor() +} + +func (ProcessPrivsChanged) Type() protoreflect.EnumType { + return &file_tetragon_capabilities_proto_enumTypes[2] +} + +func (x ProcessPrivsChanged) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ProcessPrivsChanged.Descriptor instead. +func (ProcessPrivsChanged) EnumDescriptor() ([]byte, []int) { + return file_tetragon_capabilities_proto_rawDescGZIP(), []int{2} +} + var File_tetragon_capabilities_proto protoreflect.FileDescriptor var file_tetragon_capabilities_proto_rawDesc = []byte{ @@ -444,7 +496,14 @@ var file_tetragon_capabilities_proto_rawDesc = []byte{ 0x61, 0x70, 0x41, 0x6d, 0x62, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x61, 0x69, 0x73, 0x65, 0x10, 0x40, 0x12, 0x22, 0x0a, 0x1d, 0x53, 0x65, 0x63, 0x42, 0x69, 0x74, 0x4e, 0x6f, 0x43, 0x61, 0x70, 0x41, 0x6d, 0x62, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x61, 0x69, 0x73, 0x65, 0x4c, 0x6f, 0x63, 0x6b, 0x65, - 0x64, 0x10, 0x80, 0x01, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x64, 0x10, 0x80, 0x01, 0x2a, 0x69, 0x0a, 0x13, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x50, + 0x72, 0x69, 0x76, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x0f, 0x0a, 0x0b, 0x50, + 0x52, 0x49, 0x56, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x45, 0x54, 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a, + 0x50, 0x52, 0x49, 0x56, 0x53, 0x5f, 0x52, 0x41, 0x49, 0x53, 0x45, 0x44, 0x5f, 0x45, 0x58, 0x45, + 0x43, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x5f, 0x43, 0x41, 0x50, 0x10, 0x01, 0x12, 0x21, 0x0a, 0x1d, + 0x50, 0x52, 0x49, 0x56, 0x53, 0x5f, 0x52, 0x41, 0x49, 0x53, 0x45, 0x44, 0x5f, 0x45, 0x58, 0x45, + 0x43, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x5f, 0x53, 0x45, 0x54, 0x55, 0x49, 0x44, 0x10, 0x02, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -459,10 +518,11 @@ func file_tetragon_capabilities_proto_rawDescGZIP() []byte { return file_tetragon_capabilities_proto_rawDescData } -var file_tetragon_capabilities_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_tetragon_capabilities_proto_enumTypes = make([]protoimpl.EnumInfo, 3) var file_tetragon_capabilities_proto_goTypes = []interface{}{ - (CapabilitiesType)(0), // 0: tetragon.CapabilitiesType - (SecureBitsType)(0), // 1: tetragon.SecureBitsType + (CapabilitiesType)(0), // 0: tetragon.CapabilitiesType + (SecureBitsType)(0), // 1: tetragon.SecureBitsType + (ProcessPrivsChanged)(0), // 2: tetragon.ProcessPrivsChanged } var file_tetragon_capabilities_proto_depIdxs = []int32{ 0, // [0:0] is the sub-list for method output_type @@ -482,7 +542,7 @@ func file_tetragon_capabilities_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_tetragon_capabilities_proto_rawDesc, - NumEnums: 2, + NumEnums: 3, NumMessages: 0, NumExtensions: 0, NumServices: 0, diff --git a/contrib/rthooks/tetragon-oci-hook/vendor/github.com/cilium/tetragon/api/v1/tetragon/capabilities.proto b/contrib/rthooks/tetragon-oci-hook/vendor/github.com/cilium/tetragon/api/v1/tetragon/capabilities.proto index 9b097083a2f..50701116f3a 100644 --- a/contrib/rthooks/tetragon-oci-hook/vendor/github.com/cilium/tetragon/api/v1/tetragon/capabilities.proto +++ b/contrib/rthooks/tetragon-oci-hook/vendor/github.com/cilium/tetragon/api/v1/tetragon/capabilities.proto @@ -306,3 +306,14 @@ enum SecureBitsType { /* Make bit-6 SecBitNoCapAmbientRaise immutable */ SecBitNoCapAmbientRaiseLocked = 128; } + +// Reasons of why the process privileges changed. +enum ProcessPrivsChanged { + PRIVS_UNSET = 0; + + // A privilege elevation happened due to the execution of a binary with file capabilities set. + PRIVS_RAISED_EXEC_FILE_CAP = 1; + + // A privilege elevation happened due to the execution of a binary with setuid to root. + PRIVS_RAISED_EXEC_FILE_SETUID = 2; +} diff --git a/contrib/rthooks/tetragon-oci-hook/vendor/github.com/cilium/tetragon/api/v1/tetragon/tetragon.pb.go b/contrib/rthooks/tetragon-oci-hook/vendor/github.com/cilium/tetragon/api/v1/tetragon/tetragon.pb.go index 4aa6cac53ac..0ec0c16013d 100644 --- a/contrib/rthooks/tetragon-oci-hook/vendor/github.com/cilium/tetragon/api/v1/tetragon/tetragon.pb.go +++ b/contrib/rthooks/tetragon-oci-hook/vendor/github.com/cilium/tetragon/api/v1/tetragon/tetragon.pb.go @@ -1027,6 +1027,10 @@ type BinaryProperties struct { Setuid *wrapperspb.UInt32Value `protobuf:"bytes,1,opt,name=setuid,proto3" json:"setuid,omitempty"` // If set then this is the set group ID used for execution Setgid *wrapperspb.UInt32Value `protobuf:"bytes,2,opt,name=setgid,proto3" json:"setgid,omitempty"` + // The reasons why this binary execution changed privileges and raised both the permitted and effective capabilities. + // Usually this happens when the process executes a binary with setuid root bit set or file capabilities. + // The final ganted capabilities are listed in the capabilities field of the process execution. + PrivsChanged []ProcessPrivsChanged `protobuf:"varint,3,rep,packed,name=privs_changed,json=privsChanged,proto3,enum=tetragon.ProcessPrivsChanged" json:"privs_changed,omitempty"` } func (x *BinaryProperties) Reset() { @@ -1075,6 +1079,13 @@ func (x *BinaryProperties) GetSetgid() *wrapperspb.UInt32Value { return nil } +func (x *BinaryProperties) GetPrivsChanged() []ProcessPrivsChanged { + if x != nil { + return x.PrivsChanged + } + return nil +} + type Process struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -4230,7 +4241,8 @@ var file_tetragon_tetragon_proto_goTypes = []interface{}{ (CapabilitiesType)(0), // 45: tetragon.CapabilitiesType (*wrapperspb.Int32Value)(nil), // 46: google.protobuf.Int32Value (SecureBitsType)(0), // 47: tetragon.SecureBitsType - (*wrapperspb.BoolValue)(nil), // 48: google.protobuf.BoolValue + (ProcessPrivsChanged)(0), // 48: tetragon.ProcessPrivsChanged + (*wrapperspb.BoolValue)(nil), // 49: google.protobuf.BoolValue } var file_tetragon_tetragon_proto_depIdxs = []int32{ 4, // 0: tetragon.Container.image:type_name -> tetragon.Image diff --git a/contrib/rthooks/tetragon-oci-hook/vendor/github.com/cilium/tetragon/api/v1/tetragon/tetragon.proto b/contrib/rthooks/tetragon-oci-hook/vendor/github.com/cilium/tetragon/api/v1/tetragon/tetragon.proto index 70b52f6a924..8eb410e0403 100644 --- a/contrib/rthooks/tetragon-oci-hook/vendor/github.com/cilium/tetragon/api/v1/tetragon/tetragon.proto +++ b/contrib/rthooks/tetragon-oci-hook/vendor/github.com/cilium/tetragon/api/v1/tetragon/tetragon.proto @@ -141,6 +141,10 @@ message BinaryProperties { google.protobuf.UInt32Value setuid = 1; // If set then this is the set group ID used for execution google.protobuf.UInt32Value setgid = 2; + // The reasons why this binary execution changed privileges and raised both the permitted and effective capabilities. + // Usually this happens when the process executes a binary with setuid root bit set or file capabilities. + // The final ganted capabilities are listed in the capabilities field of the process execution. + repeated ProcessPrivsChanged privs_changed = 3; } message Process { diff --git a/contrib/tester-progs/Makefile b/contrib/tester-progs/Makefile index 89b2344fabd..9009cb64197 100644 --- a/contrib/tester-progs/Makefile +++ b/contrib/tester-progs/Makefile @@ -18,7 +18,8 @@ PROGS = sigkill-tester \ threads-tester \ bench-reader \ threads-exit \ - killer-tester + killer-tester \ + drop-privileges # For now killer-tester is compiled to 32-bit only on x86_64 as we want # to test 32-bit binaries and system calls compatibility layer. @@ -52,6 +53,9 @@ sigkill-unprivileged-user-ns-tester: sigkill-unprivileged-user-ns-tester.c nop: nop.c $(GCC) -Wall $< -o $@ -lpthread +drop-privileges: drop-privileges.c + $(GCC) -Wall $< -o $@ -lpthread + exit-leader: exit-leader.c $(GCC) -Wall $< -o $@ -lpthread @@ -68,8 +72,9 @@ uprobe-test-2: uprobe-test-1 cp uprobe-test-1 uprobe-test-2 # -m32 is an x86_64 flag. +# NB(kkourt) we compile this as static to avoid the need for ia32 libs in VMs killer-tester-32: killer-tester.c - $(GCC) -Wall -m32 $< -o $@ + $(GCC) -Wall -m32 -static $< -o $@ lseek-pipe: FORCE go build -o lseek-pipe ./go/lseek-pipe diff --git a/contrib/tester-progs/drop-privileges.c b/contrib/tester-progs/drop-privileges.c new file mode 100644 index 00000000000..141100b3665 --- /dev/null +++ b/contrib/tester-progs/drop-privileges.c @@ -0,0 +1,30 @@ +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include + +#define errExit(msg) \ + do { \ + perror(msg); \ + exit(EXIT_FAILURE); \ + } while (0) + +int main(int argc, char *argv[]) +{ + if (argc <= 1) + errExit("no target program to execute"); + + if (setregid(1879048188, 1879048188) < 0) + errExit("setregid()"); + + if (setreuid(1879048188, 1879048188) < 0) + errExit("setreuid()"); + + execve(argv[1], argv, NULL); + errExit("execve()"); +} diff --git a/docs/content/en/docs/reference/grpc-api.md b/docs/content/en/docs/reference/grpc-api.md index e91fc6f8d1b..273d1ee7c0a 100644 --- a/docs/content/en/docs/reference/grpc-api.md +++ b/docs/content/en/docs/reference/grpc-api.md @@ -66,6 +66,18 @@ version 1 of this API is defined in | CAP_BPF | 39 | CAP_BPF allows the following BPF operations: - Creating all types of BPF maps - Advanced verifier features - Indirect variable access - Bounded loops - BPF to BPF function calls - Scalar precision tracking - Larger complexity limits - Dead code elimination - And potentially other features - Loading BPF Type Format (BTF) data - Retrieve xlated and JITed code of BPF programs - Use bpf_spin_lock() helper CAP_PERFMON relaxes the verifier checks further: - BPF progs can use of pointer-to-integer conversions - speculation attack hardening measures are bypassed - bpf_probe_read to read arbitrary kernel memory is allowed - bpf_trace_printk to print kernel memory is allowed CAP_SYS_ADMIN is required to use bpf_probe_write_user. CAP_SYS_ADMIN is required to iterate system wide loaded programs, maps, links, BTFs and convert their IDs to file descriptors. CAP_PERFMON and CAP_BPF are required to load tracing programs. CAP_NET_ADMIN and CAP_BPF are required to load networking programs. | | CAP_CHECKPOINT_RESTORE | 40 | Allow writing to ns_last_pid | + + +### ProcessPrivilegesChanged +Reasons of why the process privileges changed. + +| Name | Number | Description | +| ---- | ------ | ----------- | +| PRIVILEGES_CHANGED_UNSET | 0 | | +| PRIVILEGES_RAISED_EXEC_FILE_CAP | 1 | A privilege elevation happened due to the execution of a binary with file capability sets. The kernel supports associating capability sets with an executable file using `setcap` command. The file capability sets are stored in an extended attribute (see https://man7.org/linux/man-pages/man7/xattr.7.html) named `security.capability`. The file capability sets, in conjunction with the capability sets of the process, determine the process capabilities and privileges after the `execve` system call. For further reference, please check sections `File capability extended attribute versioning` and `Namespaced file capabilities` of the capabilities man pages: https://man7.org/linux/man-pages/man7/capabilities.7.html. The new granted capabilities can be listed inside the `process` object. | +| PRIVILEGES_RAISED_EXEC_FILE_SETUID | 2 | A privilege elevation happened due to the execution of a binary with set-user-ID to root. When a process with nonzero UIDs executes a binary with a set-user-ID to root also known as suid-root executable, then the kernel switches the effective user ID to 0 (root) which is a privilege elevation operation since it grants access to resources owned by the root user. The effective user ID is listed inside the `process_credentials` part of the `process` object. For further reading, section `Capabilities and execution of programs by root` of https://man7.org/linux/man-pages/man7/capabilities.7.html. Afterward the kernel recalculates the capability sets of the process and grants all capabilities in the permitted and effective capability sets, except those masked out by the capability bounding set. If the binary also have file capability sets then these bits are honored and the process gains just the capabilities granted by the file capability sets (i.e., not all capabilities, as it would occur when executing a set-user-ID to root binary that does not have any associated file capabilities). This is described in section `Set-user-ID-root programs that have file capabilities` of https://man7.org/linux/man-pages/man7/capabilities.7.html. The new granted capabilities can be listed inside the `process` object. There is one exception for the special treatments of set-user-ID to root execution receiving all capabilities, if the `SecBitNoRoot` bit of the Secure bits is set, then the kernel does not grant any capability. Please check section: `The securebits flags: establishing a capabilities-only environment` of the capabilities man pages: https://man7.org/linux/man-pages/man7/capabilities.7.html | +| PRIVILEGES_RAISED_EXEC_FILE_SETGID | 3 | A privilege elevation happened due to the execution of a binary with set-group-ID to root. When a process with nonzero GIDs executes a binary with a set-group-ID to root, the kernel switches the effective group ID to 0 (root) which is a privilege elevation operation since it grants access to resources owned by the root group. The effective group ID is listed inside the `process_credentials` part of the `process` object. | + ### SecureBitsType @@ -94,6 +106,7 @@ version 1 of this API is defined in | ----- | ---- | ----- | ----------- | | setuid | [google.protobuf.UInt32Value](#google-protobuf-UInt32Value) | | If set then this is the set user ID used for execution | | setgid | [google.protobuf.UInt32Value](#google-protobuf-UInt32Value) | | If set then this is the set group ID used for execution | +| privileges_changed | [ProcessPrivilegesChanged](#tetragon-ProcessPrivilegesChanged) | repeated | The reasons why this binary execution changed privileges. Usually this happens when the process executes a binary with the set-user-ID to root or file capability sets. The final granted privileges can be listed inside the `process_credentials` or capabilities fields part of of the `process` object. | @@ -472,6 +485,7 @@ https://github.com/opencontainers/runtime-spec/blob/main/config.md#createcontain | stack_trace | [StackTraceEntry](#tetragon-StackTraceEntry) | repeated | Kernel stack trace to the call. | | policy_name | [string](#string) | | Name of the Tracing Policy that created that kprobe. | | return_action | [KprobeAction](#tetragon-KprobeAction) | | Action performed when the return kprobe executed. | +| message | [string](#string) | | Short message of the Tracing Policy to inform users what is going on. | @@ -497,6 +511,7 @@ loader sensor event triggered for loaded binary/library | args | [KprobeArgument](#tetragon-KprobeArgument) | repeated | Arguments definition of the observed tracepoint. TODO: once we implement all we want, rename KprobeArgument to GenericArgument | | policy_name | [string](#string) | | Name of the policy that created that tracepoint. | | action | [KprobeAction](#tetragon-KprobeAction) | | Action performed when the tracepoint matched. | +| message | [string](#string) | | Short message of the Tracing Policy to inform users what is going on. | @@ -509,6 +524,7 @@ loader sensor event triggered for loaded binary/library | path | [string](#string) | | | | symbol | [string](#string) | | | | policy_name | [string](#string) | | Name of the policy that created that uprobe. | +| message | [string](#string) | | Short message of the Tracing Policy to inform users what is going on. | diff --git a/examples/policylibrary/modules.yaml b/examples/policylibrary/modules.yaml index 9e1c5fa2eed..bad18037617 100644 --- a/examples/policylibrary/modules.yaml +++ b/examples/policylibrary/modules.yaml @@ -3,12 +3,12 @@ apiVersion: cilium.io/v1alpha1 kind: TracingPolicy metadata: name: "monitor-kernel-modules" - #annotations: - #description: "Monitor kernel modules operations" + annotations: + description: "Monitor kernel modules operations" spec: kprobes: - call: "security_kernel_module_request" - # Automatic module loading detection + message: "Kernel module requested and is being loaded automatically" syscall: false return: true args: @@ -18,6 +18,7 @@ spec: index: 0 type: "int" - call: "security_kernel_read_file" + message: "Kernel module is being loaded" # Explicit module loading using file descriptor finit_module() to print module full path syscall: false return: true diff --git a/go.mod b/go.mod index 6fcb0dfb5a9..89915864053 100644 --- a/go.mod +++ b/go.mod @@ -40,8 +40,8 @@ require ( github.com/vishvananda/netlink v1.2.1-beta.2.0.20231127184239-0ced8385386a go.uber.org/atomic v1.11.0 go.uber.org/multierr v1.11.0 - golang.org/x/sync v0.5.0 - golang.org/x/sys v0.15.0 + golang.org/x/sync v0.6.0 + golang.org/x/sys v0.16.0 golang.org/x/time v0.5.0 google.golang.org/grpc v1.60.1 google.golang.org/protobuf v1.32.0 diff --git a/go.sum b/go.sum index 64e54e604dc..5e076f55183 100644 --- a/go.sum +++ b/go.sum @@ -671,8 +671,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -712,8 +712,8 @@ golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= diff --git a/install/kubernetes/Makefile b/install/kubernetes/Makefile new file mode 100644 index 00000000000..59c0f7a9edf --- /dev/null +++ b/install/kubernetes/Makefile @@ -0,0 +1,19 @@ +# Variables +SCRIPT_DIR := $(shell dirname "$(realpath $(lastword $(MAKEFILE_LIST)))") +TETRAGON_CHART := $(SCRIPT_DIR)/tetragon +HELM ?= docker run --rm -v $(TETRAGON_CHART):/apps alpine/helm:3.3.4 + +# Targets +.PHONY: all lint docs +all: deps lint docs + +deps: + $(HELM) dependency update . + +lint: + $(HELM) lint . --with-subcharts + $(HELM) template tetragon . | docker run --rm -i ghcr.io/yannh/kubeconform:v0.6.4-alpine@sha256:e68a0b638c6e9b76f1b7d58b4ec94340ef3b6601db25b2e40b29e3ac2d68e4bf --strict --schema-location default + +docs: + docker run --rm -v $(TETRAGON_CHART):/helm-docs -u $$(id -u) jnorwood/helm-docs:v1.11.0@sha256:66c8f4164dec860fa5c1528239c4aa826a12485305b7b224594b1a73f7e6879a + $(SCRIPT_DIR)/export-doc.sh $(SCRIPT_DIR)/../../docs/content/en/docs/reference/helm-chart.md diff --git a/install/kubernetes/test.sh b/install/kubernetes/test.sh deleted file mode 100755 index 6d26ca46955..00000000000 --- a/install/kubernetes/test.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -set -e -set -o pipefail -shopt -s expand_aliases - -SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) -TETRAGON_CHART="$SCRIPT_DIR/tetragon" - -alias helm='docker run --rm -v $TETRAGON_CHART:/apps alpine/helm:3.3.4' -alias kubeconform='docker run --rm -i ghcr.io/yannh/kubeconform:v0.6.4-alpine@sha256:e68a0b638c6e9b76f1b7d58b4ec94340ef3b6601db25b2e40b29e3ac2d68e4bf' -helm dependency update . -helm lint . --with-subcharts -helm template tetragon . | kubeconform --strict --schema-location default - -# Update README.md and documentation -docker run --rm -v "$TETRAGON_CHART:/helm-docs" -u "$(id -u)" jnorwood/helm-docs:v1.11.0@sha256:66c8f4164dec860fa5c1528239c4aa826a12485305b7b224594b1a73f7e6879a -"$SCRIPT_DIR/export-doc.sh" "$SCRIPT_DIR/../../docs/content/en/docs/reference/helm-chart.md" diff --git a/pkg/api/processapi/processapi.go b/pkg/api/processapi/processapi.go index d0e19d0b305..c10d75e4986 100644 --- a/pkg/api/processapi/processapi.go +++ b/pkg/api/processapi/processapi.go @@ -34,6 +34,10 @@ const ( /* Execve extra flags */ ExecveSetuid = 0x01 ExecveSetgid = 0x02 + /* Execve flags received from BPF */ + ExecveFileCaps = 0x04 // This binary execution gained new capabilities through file capabilities execution + ExecveSetuidRoot = 0x08 // This binary execution gained new capabilities through setuid root execution + ExecveSetgidRoot = 0x10 // This binary execution gained new capabilities through setgid root execution // flags of MsgCommon MSG_COMMON_FLAG_RETURN = 0x1 diff --git a/pkg/eventcache/eventcache.go b/pkg/eventcache/eventcache.go index 9755bf686d9..507ebabc612 100644 --- a/pkg/eventcache/eventcache.go +++ b/pkg/eventcache/eventcache.go @@ -246,7 +246,3 @@ func New(s *server.Server) *Cache { func Get() *Cache { return cache } - -func (ec *Cache) len() int { - return len(ec.cache) -} diff --git a/pkg/eventcache/metrics.go b/pkg/eventcache/metrics.go deleted file mode 100644 index 532674d7095..00000000000 --- a/pkg/eventcache/metrics.go +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Tetragon - -package eventcache - -import ( - "github.com/cilium/tetragon/pkg/metrics/mapmetrics" - "github.com/prometheus/client_golang/prometheus" -) - -// bpfCollector implements prometheus.Collector. It collects metrics directly from BPF maps. -type bpfCollector struct{} - -func NewBPFCollector() prometheus.Collector { - return &bpfCollector{} -} - -func (c *bpfCollector) Describe(ch chan<- *prometheus.Desc) { - ch <- mapmetrics.MapSize.Desc() -} - -func (c *bpfCollector) Collect(ch chan<- prometheus.Metric) { - ec := Get() - if ec != nil { - ch <- mapmetrics.MapSize.MustMetric( - float64(ec.len()), - "eventcache", "0", - ) - } -} diff --git a/pkg/grpc/tracing/tracing.go b/pkg/grpc/tracing/tracing.go index 828d8fd22b9..5778fb36a94 100644 --- a/pkg/grpc/tracing/tracing.go +++ b/pkg/grpc/tracing/tracing.go @@ -306,6 +306,7 @@ func GetProcessKprobe(event *MsgGenericKprobeUnix) *tetragon.ProcessKprobe { ReturnAction: kprobeAction(event.ReturnAction), StackTrace: stackTrace, PolicyName: event.PolicyName, + Message: event.Message, } if tetragonProcess.Pid == nil { @@ -347,6 +348,7 @@ type MsgGenericTracepointUnix struct { Event string Args []tracingapi.MsgGenericTracepointArg PolicyName string + Message string Action uint64 } @@ -419,6 +421,7 @@ func (msg *MsgGenericTracepointUnix) HandleMessage() *tetragon.GetEventsResponse Event: msg.Event, Args: tetragonArgs, PolicyName: msg.PolicyName, + Message: msg.Message, Action: kprobeAction(msg.Action), } @@ -477,6 +480,7 @@ type MsgGenericKprobeUnix struct { FuncName string Args []tracingapi.MsgGenericKprobeArg PolicyName string + Message string StackTrace [unix.PERF_MAX_STACK_DEPTH]uint64 } @@ -609,6 +613,7 @@ type MsgGenericUprobeUnix struct { Path string Symbol string PolicyName string + Message string } func (msg *MsgGenericUprobeUnix) Notify() bool { @@ -657,6 +662,7 @@ func GetProcessUprobe(event *MsgGenericUprobeUnix) *tetragon.ProcessUprobe { Path: event.Path, Symbol: event.Symbol, PolicyName: event.PolicyName, + Message: event.Message, } if tetragonProcess.Pid == nil { diff --git a/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_tracingpolicies.yaml b/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_tracingpolicies.yaml index 31ad24954e1..c7d189a7095 100644 --- a/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_tracingpolicies.yaml +++ b/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_tracingpolicies.yaml @@ -131,6 +131,11 @@ spec: call: description: Name of the function to apply the kprobe spec to. type: string + message: + description: A short message of 256 characters max that will + be included in the event output to inform users what is going + on. + type: string return: default: false description: Indicates whether to collect return value of the @@ -831,6 +836,11 @@ spec: event: description: Tracepoint event type: string + message: + description: A short message of 256 characters max that will + be included in the event output to inform users what is going + on. + type: string selectors: description: Selectors to apply before producing trace output. Selectors are ORed. @@ -1270,6 +1280,11 @@ spec: description: A list of uprobe specs. items: properties: + message: + description: A short message of 256 characters max that will + be included in the event output to inform users what is going + on. + type: string path: description: Name of the traced binary type: string diff --git a/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_tracingpoliciesnamespaced.yaml b/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_tracingpoliciesnamespaced.yaml index 1ed3b1fb9bc..4e40f35c8b7 100644 --- a/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_tracingpoliciesnamespaced.yaml +++ b/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_tracingpoliciesnamespaced.yaml @@ -131,6 +131,11 @@ spec: call: description: Name of the function to apply the kprobe spec to. type: string + message: + description: A short message of 256 characters max that will + be included in the event output to inform users what is going + on. + type: string return: default: false description: Indicates whether to collect return value of the @@ -831,6 +836,11 @@ spec: event: description: Tracepoint event type: string + message: + description: A short message of 256 characters max that will + be included in the event output to inform users what is going + on. + type: string selectors: description: Selectors to apply before producing trace output. Selectors are ORed. @@ -1270,6 +1280,11 @@ spec: description: A list of uprobe specs. items: properties: + message: + description: A short message of 256 characters max that will + be included in the event output to inform users what is going + on. + type: string path: description: Name of the traced binary type: string diff --git a/pkg/k8s/apis/cilium.io/v1alpha1/types.go b/pkg/k8s/apis/cilium.io/v1alpha1/types.go index 998911f2bc8..191f37c91e0 100644 --- a/pkg/k8s/apis/cilium.io/v1alpha1/types.go +++ b/pkg/k8s/apis/cilium.io/v1alpha1/types.go @@ -33,6 +33,10 @@ type KProbeSpec struct { // Indicates whether the traced function is a syscall. Syscall bool `json:"syscall"` // +kubebuilder:validation:Optional + // A short message of 256 characters max that will be included + // in the event output to inform users what is going on. + Message string `json:"message"` + // +kubebuilder:validation:Optional // A list of function arguments to include in the trace output. Args []KProbeArg `json:"args,omitempty"` // +kubebuilder:validation:Optional @@ -227,6 +231,10 @@ type TracepointSpec struct { // Tracepoint event Event string `json:"event"` // +kubebuilder:validation:Optional + // A short message of 256 characters max that will be included + // in the event output to inform users what is going on. + Message string `json:"message"` + // +kubebuilder:validation:Optional // A list of function arguments to include in the trace output. Args []KProbeArg `json:"args,omitempty"` // +kubebuilder:validation:Optional @@ -240,6 +248,10 @@ type UProbeSpec struct { // Name of the traced symbol Symbol string `json:"symbol"` // +kubebuilder:validation:Optional + // A short message of 256 characters max that will be included + // in the event output to inform users what is going on. + Message string `json:"message"` + // +kubebuilder:validation:Optional // Selectors to apply before producing trace output. Selectors are ORed. Selectors []KProbeSelector `json:"selectors,omitempty"` } diff --git a/pkg/k8s/apis/cilium.io/v1alpha1/version.go b/pkg/k8s/apis/cilium.io/v1alpha1/version.go index 65a30f7ebe8..f54cef27815 100644 --- a/pkg/k8s/apis/cilium.io/v1alpha1/version.go +++ b/pkg/k8s/apis/cilium.io/v1alpha1/version.go @@ -7,4 +7,4 @@ package v1alpha1 // Used to determine if CRD needs to be updated in cluster // // Developers: Bump patch for each change in the CRD schema. -const CustomResourceDefinitionSchemaVersion = "1.1.1" +const CustomResourceDefinitionSchemaVersion = "1.1.2" diff --git a/pkg/k8s/go.mod b/pkg/k8s/go.mod index 84da4a8cafc..fba792c8ea8 100644 --- a/pkg/k8s/go.mod +++ b/pkg/k8s/go.mod @@ -7,7 +7,7 @@ require ( github.com/blang/semver/v4 v4.0.0 github.com/cilium/cilium v1.15.0-rc.0 github.com/sirupsen/logrus v1.9.3 - golang.org/x/sync v0.5.0 + golang.org/x/sync v0.6.0 k8s.io/apiextensions-apiserver v0.29.0 k8s.io/apimachinery v0.29.0 k8s.io/client-go v0.29.0 diff --git a/pkg/k8s/go.sum b/pkg/k8s/go.sum index a3f4d76d41d..85e8efb435d 100644 --- a/pkg/k8s/go.sum +++ b/pkg/k8s/go.sum @@ -148,8 +148,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/pkg/k8s/vendor/golang.org/x/sync/errgroup/errgroup.go b/pkg/k8s/vendor/golang.org/x/sync/errgroup/errgroup.go index b18efb743fe..948a3ee63d4 100644 --- a/pkg/k8s/vendor/golang.org/x/sync/errgroup/errgroup.go +++ b/pkg/k8s/vendor/golang.org/x/sync/errgroup/errgroup.go @@ -4,6 +4,9 @@ // Package errgroup provides synchronization, error propagation, and Context // cancelation for groups of goroutines working on subtasks of a common task. +// +// [errgroup.Group] is related to [sync.WaitGroup] but adds handling of tasks +// returning errors. package errgroup import ( diff --git a/pkg/k8s/vendor/modules.txt b/pkg/k8s/vendor/modules.txt index c28b1cb765c..cc9b4e3af78 100644 --- a/pkg/k8s/vendor/modules.txt +++ b/pkg/k8s/vendor/modules.txt @@ -135,7 +135,7 @@ golang.org/x/net/idna ## explicit; go 1.18 golang.org/x/oauth2 golang.org/x/oauth2/internal -# golang.org/x/sync v0.5.0 +# golang.org/x/sync v0.6.0 ## explicit; go 1.18 golang.org/x/sync/errgroup golang.org/x/sync/semaphore diff --git a/pkg/metrics/eventcachemetrics/eventcachemetrics.go b/pkg/metrics/eventcachemetrics/eventcachemetrics.go index 9fa660b5a24..fabfbed1bf3 100644 --- a/pkg/metrics/eventcachemetrics/eventcachemetrics.go +++ b/pkg/metrics/eventcachemetrics/eventcachemetrics.go @@ -8,6 +8,10 @@ import ( "github.com/prometheus/client_golang/prometheus" ) +var ( + ProcessCacheSize = "process_cache_size" +) + var ( processInfoErrors = prometheus.NewCounterVec(prometheus.CounterOpts{ Namespace: consts.MetricsNamespace, @@ -33,6 +37,12 @@ var ( Help: "The total of errors encountered while fetching process exec information from the cache.", ConstLabels: nil, }, []string{"error"}) + ProcessCacheTotal = prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: consts.MetricsNamespace, + Name: "event_cache_process_total", + Help: "The size of the process cache.", + ConstLabels: nil, + }, []string{"type"}) ) func InitMetrics(registry *prometheus.Registry) { @@ -56,3 +66,8 @@ func PodInfoError(eventType string) prometheus.Counter { func EventCacheError(err string) prometheus.Counter { return eventCacheErrorsTotal.WithLabelValues(err) } + +// Get a new handle on an ProcessCache metric for an entryType +func ProcessCache(entryType string) prometheus.Counter { + return ProcessCacheTotal.WithLabelValues(entryType) +} diff --git a/pkg/metrics/mapmetrics/mapmetrics.go b/pkg/metrics/mapmetrics/mapmetrics.go index b3a9066b20d..2be73887c20 100644 --- a/pkg/metrics/mapmetrics/mapmetrics.go +++ b/pkg/metrics/mapmetrics/mapmetrics.go @@ -10,33 +10,22 @@ import ( ) var ( - MapDrops = prometheus.NewCounterVec(prometheus.CounterOpts{ - Namespace: consts.MetricsNamespace, - Name: "map_drops_total", - Help: "The total number of entries dropped per LRU map.", - ConstLabels: nil, - }, []string{"map"}) MapSize = metrics.NewBPFGauge(prometheus.NewDesc( - prometheus.BuildFQName(consts.MetricsNamespace, "", "map_in_use_gauge"), + prometheus.BuildFQName(consts.MetricsNamespace, "", "map_in_use"), "The total number of in-use entries per map.", []string{"map", "total"}, nil, )) MapErrors = metrics.NewBPFCounter(prometheus.NewDesc( prometheus.BuildFQName(consts.MetricsNamespace, "", "map_errors_total"), - "The total number of entries dropped per LRU map.", + "The entries dropped per LRU map.", []string{"map"}, nil, )) ) -func InitMetrics(registry *prometheus.Registry) { - registry.MustRegister(MapDrops) +func InitMetrics(_ *prometheus.Registry) { // custom collectors are registered independently } -func MapDropInc(mapName string) { - MapDrops.WithLabelValues(mapName).Inc() -} - // bpfCollector implements prometheus.Collector. It collects metrics directly from BPF maps. // NB: We can't register individual BPF collectors collecting map metrics, because they share the // metrics descriptors. Sending duplicate descriptors from different collectors results in diff --git a/pkg/metrics/metricsconfig/initmetrics.go b/pkg/metrics/metricsconfig/initmetrics.go index 4109597f899..000d19da0d6 100644 --- a/pkg/metrics/metricsconfig/initmetrics.go +++ b/pkg/metrics/metricsconfig/initmetrics.go @@ -4,7 +4,6 @@ package metricsconfig import ( - "github.com/cilium/tetragon/pkg/eventcache" "github.com/cilium/tetragon/pkg/grpc/tracing" "github.com/cilium/tetragon/pkg/metrics/errormetrics" "github.com/cilium/tetragon/pkg/metrics/eventcachemetrics" @@ -20,7 +19,6 @@ import ( "github.com/cilium/tetragon/pkg/metrics/syscallmetrics" "github.com/cilium/tetragon/pkg/metrics/watchermetrics" "github.com/cilium/tetragon/pkg/observer" - "github.com/cilium/tetragon/pkg/process" "github.com/cilium/tetragon/pkg/version" grpcmetrics "github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus" "github.com/prometheus/client_golang/prometheus" @@ -46,9 +44,7 @@ func InitAllMetrics(registry *prometheus.Registry) { // register BPF collectors registry.MustRegister(mapmetrics.NewBPFCollector( - eventcache.NewBPFCollector(), observer.NewBPFCollector(), - process.NewBPFCollector(), )) registry.MustRegister(eventmetrics.NewBPFCollector()) diff --git a/pkg/observer/observer_stats.go b/pkg/observer/observer_stats.go index bdf51c772ed..1e6e48fb34c 100644 --- a/pkg/observer/observer_stats.go +++ b/pkg/observer/observer_stats.go @@ -6,12 +6,15 @@ package observer import ( "fmt" "path/filepath" + "strings" "github.com/cilium/ebpf" + "github.com/cilium/tetragon/pkg/logger" "github.com/cilium/tetragon/pkg/metrics/mapmetrics" "github.com/cilium/tetragon/pkg/option" "github.com/cilium/tetragon/pkg/sensors" "github.com/prometheus/client_golang/prometheus" + "github.com/sirupsen/logrus" ) // bpfCollector implements prometheus.Collector. It collects metrics directly from BPF maps. @@ -27,19 +30,34 @@ func (c *bpfCollector) Describe(ch chan<- *prometheus.Desc) { } func (c *bpfCollector) Collect(ch chan<- prometheus.Metric) { + statsSuffix := "_stats" for _, m := range sensors.AllMaps { name := m.Name pin := filepath.Join(option.Config.MapDir, name) - pinStats := pin + "_stats" - mapLinkStats, err := ebpf.LoadPinnedMap(pinStats, nil) + // Skip map names that end up with _stats. + // This will result in _stats_stats suffixes that we don't care about + if strings.HasSuffix(pin, statsSuffix) { + continue + } + pinStats := pin + statsSuffix + + mapLinkStats, err := ebpf.LoadPinnedMap(pin, nil) if err != nil { - return + // If we fail to open the map with _stats suffix + // continue to the next map. + continue } defer mapLinkStats.Close() mapLink, err := ebpf.LoadPinnedMap(pin, nil) if err != nil { - return + // We have already opened the map with _stats suffix + // so we don't expect that to fail. + logger.GetLogger().WithFields(logrus.Fields{ + "MapName": pin, + "StatsMapName": pinStats, + }).Warn("Failed to open the corresponding map for an existing stats map.") + continue } defer mapLink.Close() diff --git a/pkg/process/cache.go b/pkg/process/cache.go index 190a052a3ff..081da9444e3 100644 --- a/pkg/process/cache.go +++ b/pkg/process/cache.go @@ -11,7 +11,6 @@ import ( "github.com/cilium/tetragon/api/v1/tetragon" "github.com/cilium/tetragon/pkg/logger" "github.com/cilium/tetragon/pkg/metrics/errormetrics" - "github.com/cilium/tetragon/pkg/metrics/mapmetrics" lru "github.com/hashicorp/golang-lru/v2" ) @@ -132,7 +131,7 @@ func NewCache( lruCache, err := lru.NewWithEvict( processCacheSize, func(_ string, _ *ProcessInternal) { - mapmetrics.MapDropInc("processLru") + errormetrics.ErrorTotalInc(errormetrics.ProcessCacheEvicted) }, ) if err != nil { diff --git a/pkg/process/metrics.go b/pkg/process/metrics.go deleted file mode 100644 index 5d37cb34704..00000000000 --- a/pkg/process/metrics.go +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Tetragon - -package process - -import ( - "fmt" - - "github.com/cilium/tetragon/pkg/metrics/mapmetrics" - "github.com/prometheus/client_golang/prometheus" -) - -// bpfCollector implements prometheus.Collector. It collects metrics directly from BPF maps. -type bpfCollector struct{} - -func NewBPFCollector() prometheus.Collector { - return &bpfCollector{} -} - -func (c *bpfCollector) Describe(ch chan<- *prometheus.Desc) { - ch <- mapmetrics.MapSize.Desc() -} - -func (c *bpfCollector) Collect(ch chan<- prometheus.Metric) { - if procCache != nil { - ch <- mapmetrics.MapSize.MustMetric( - float64(procCache.len()), - "processLru", fmt.Sprint(procCache.size), - ) - } -} diff --git a/pkg/process/process.go b/pkg/process/process.go index db9e82a9bbf..0015f783f41 100644 --- a/pkg/process/process.go +++ b/pkg/process/process.go @@ -12,6 +12,7 @@ import ( "sync/atomic" "github.com/cilium/tetragon/pkg/metrics/errormetrics" + "github.com/cilium/tetragon/pkg/metrics/eventcachemetrics" hubble "github.com/cilium/tetragon/pkg/oldhubble/cilium" "github.com/sirupsen/logrus" @@ -61,9 +62,7 @@ var ( k8s watcher.K8sResourceWatcher ) -var ( - ErrProcessInfoMissing = errors.New("failed process info missing") -) +var ErrProcessInfoMissing = errors.New("failed process info missing") func InitCache(w watcher.K8sResourceWatcher, size int) error { var err error @@ -88,6 +87,7 @@ func InitCache(w watcher.K8sResourceWatcher, size int) error { func FreeCache() { procCache.Purge() procCache = nil + eventcachemetrics.ProcessCacheTotal.Reset() } // GetProcessCopy() duplicates tetragon.Process and returns it @@ -179,6 +179,10 @@ func (pi *ProcessInternal) UpdateExecOutsideCache(cred bool) (*tetragon.Process, prop.Setgid = pi.apiBinaryProp.Setgid update = true } + if pi.apiBinaryProp.PrivilegesChanged != nil { + prop.PrivilegesChanged = pi.apiBinaryProp.PrivilegesChanged + update = true + } } // Take a copy of the process, add the necessary fields to the @@ -309,6 +313,8 @@ func initProcessInternalExec( apiBinaryProp.Setgid = &wrapperspb.UInt32Value{Value: creds.Egid} } + apiBinaryProp.PrivilegesChanged = caps.GetPrivilegesChangedReasons(process.SecureExec) + // Per thread tracking rules PID == TID // // Ensure that exported events have the TID set. For events generated by @@ -355,7 +361,8 @@ func initProcessInternalExec( // initProcessInternalClone() initialize and returns ProcessInternal from // a clone event func initProcessInternalClone(event *tetragonAPI.MsgCloneEvent, - parent *ProcessInternal, parentExecId string) (*ProcessInternal, error) { + parent *ProcessInternal, parentExecId string, +) (*ProcessInternal, error) { pi := parent.cloneInternalProcessCopy() if pi.process == nil { err := fmt.Errorf("failed to clone parent process from cache") @@ -440,6 +447,7 @@ func AddExecEvent(event *tetragonAPI.MsgExecveEventUnix) *ProcessInternal { } procCache.add(proc) + eventcachemetrics.ProcessCache(eventcachemetrics.ProcessCacheSize).Inc() return proc } @@ -463,6 +471,7 @@ func AddCloneEvent(event *tetragonAPI.MsgCloneEvent) error { parent.RefInc() procCache.add(proc) + eventcachemetrics.ProcessCache(eventcachemetrics.ProcessCacheSize).Inc() return nil } diff --git a/pkg/reader/caps/caps.go b/pkg/reader/caps/caps.go index da1cf5540d2..266a281704f 100644 --- a/pkg/reader/caps/caps.go +++ b/pkg/reader/caps/caps.go @@ -480,3 +480,29 @@ func GetSecureBitsTypes(secBit uint32) []tetragon.SecureBitsType { return bits } + +func GetPrivilegesChangedReasons(reasons uint32) []tetragon.ProcessPrivilegesChanged { + if reasons == 0 { + return nil + } + + var bits []tetragon.ProcessPrivilegesChanged + + if reasons&uint32(processapi.ExecveFileCaps) != 0 { + bits = append(bits, tetragon.ProcessPrivilegesChanged_PRIVILEGES_RAISED_EXEC_FILE_CAP) + } + + if reasons&uint32(processapi.ExecveSetuidRoot) != 0 { + bits = append(bits, tetragon.ProcessPrivilegesChanged_PRIVILEGES_RAISED_EXEC_FILE_SETUID) + } + + if reasons&uint32(processapi.ExecveSetgidRoot) != 0 { + bits = append(bits, tetragon.ProcessPrivilegesChanged_PRIVILEGES_RAISED_EXEC_FILE_SETGID) + } + + if len(bits) > 0 { + return bits + } + + return nil +} diff --git a/pkg/selectors/kernel.go b/pkg/selectors/kernel.go index 7494ecf2c01..1478587cd4a 100644 --- a/pkg/selectors/kernel.go +++ b/pkg/selectors/kernel.go @@ -1385,26 +1385,6 @@ func HasOverride(spec *v1alpha1.KProbeSpec) bool { return false } -func HasEarlyBinaryFilter(selectors []v1alpha1.KProbeSelector) bool { - if len(selectors) == 0 { - return false - } - for _, s := range selectors { - if len(s.MatchPIDs) > 0 || - len(s.MatchNamespaces) > 0 || - len(s.MatchCapabilities) > 0 || - len(s.MatchNamespaceChanges) > 0 || - len(s.MatchCapabilityChanges) > 0 || - len(s.MatchArgs) > 0 { - return false - } - } - if len(selectors) == 1 && len(selectors[0].MatchBinaries) > 0 { - return true - } - return false -} - func HasSigkillAction(kspec *v1alpha1.KProbeSpec) bool { for i := range kspec.Selectors { s := &kspec.Selectors[i] diff --git a/pkg/sensors/exec/exec_test.go b/pkg/sensors/exec/exec_test.go index c20ec2874b5..e5772e2bc6e 100644 --- a/pkg/sensors/exec/exec_test.go +++ b/pkg/sensors/exec/exec_test.go @@ -27,6 +27,7 @@ import ( "github.com/cilium/tetragon/pkg/jsonchecker" "github.com/cilium/tetragon/pkg/kernels" "github.com/cilium/tetragon/pkg/logger" + lc "github.com/cilium/tetragon/pkg/matchers/listmatcher" sm "github.com/cilium/tetragon/pkg/matchers/stringmatcher" "github.com/cilium/tetragon/pkg/observer" "github.com/cilium/tetragon/pkg/observer/observertesthelper" @@ -43,6 +44,7 @@ import ( tus "github.com/cilium/tetragon/pkg/testutils/sensors" "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" + "golang.org/x/sys/unix" ) func TestMain(m *testing.M) { @@ -878,10 +880,17 @@ func TestExecProcessCredentials(t *testing.T) { t.Fatalf("Failed to execute test binary: %s\n", err) } + oldGid := syscall.Getgid() gid := uint32(1879048193) if err := syscall.Setegid(int(gid)); err != nil { t.Fatalf("setegid(%d) error: %s", gid, err) } + t.Cleanup(func() { + // Restores all gids since we retain capabilities + if err = syscall.Setgid(oldGid); err != nil { + t.Fatalf("Failed to restore gid to %d : %s\n", oldGid, err) + } + }) if err := exec.Command(testNop).Run(); err != nil { t.Fatalf("Failed to execute test binary: %s\n", err) @@ -910,13 +919,11 @@ func TestExecProcessCredentials(t *testing.T) { err = jsonchecker.JsonTestCheck(t, checker) assert.NoError(t, err) - - if err = syscall.Setgid(0); err != nil { - t.Fatalf("Failed to restore gid to 0 : %s\n", err) - } } -func TestExecProcessCredentialsSuid(t *testing.T) { +// Test ensures that running as fully privileged root and executing a setuid or +// setgid to root does not generate a binary_properties setuid field nor privs_changed fields. +func TestExecProcessCredentialsSuidRootNoPrivsChange(t *testing.T) { var doneWG, readyWG sync.WaitGroup defer doneWG.Wait() @@ -934,7 +941,6 @@ func TestExecProcessCredentialsSuid(t *testing.T) { if err := testutils.CopyFile(testSuid, testBin, 0754|os.ModeSetuid|os.ModeSetgid); err != nil { t.Fatalf("Failed to copy binary: %s", err) } - t.Cleanup(func() { err := os.Remove(testSuid) if err != nil { @@ -945,23 +951,122 @@ func TestExecProcessCredentialsSuid(t *testing.T) { observertesthelper.LoopEvents(ctx, t, &doneWG, &readyWG, obs) readyWG.Wait() + noCredsChange := ec.NewProcessCredentialsChecker(). + WithUid(0).WithEuid(0).WithSuid(0).WithFsuid(0). + WithGid(0).WithEgid(0).WithSgid(0).WithFsgid((0)) + procExecNoPrivilegesChanged := ec.NewProcessChecker(). + WithBinary(sm.Full(testBin)).WithProcessCredentials(noCredsChange).WithBinaryProperties(nil) + execNoPrivilegesChangedChecker := ec.NewProcessExecChecker("exec").WithProcess(procExecNoPrivilegesChanged) if err := exec.Command(testBin).Run(); err != nil { t.Fatalf("Failed to execute '%s' binary: %s\n", testBin, err) } + /* Executing a setuid and setgid to root but we are already running as root + * so no privilege change should be detected, same filters as above apply. + */ + if err := os.Chown(testSuid, 0, 0); err != nil { + t.Fatalf("Chown() on '%s' binary error: %s\n", testSuid, err) + } + if err := os.Chmod(testSuid, 0754|os.ModeSetuid|os.ModeSetgid); err != nil { + t.Fatalf("Chown() on '%s' binary error: %s\n", testSuid, err) + } + procExecSetuidRootNoPrivilegesChanged := ec.NewProcessChecker(). + WithBinary(sm.Full(testSuid)).WithProcessCredentials(noCredsChange).WithBinaryProperties(nil) + execSetuidRootNoPrivilegesChangedChecker := ec.NewProcessExecChecker("exec").WithProcess(procExecSetuidRootNoPrivilegesChanged) + if err := exec.Command(testSuid).Run(); err != nil { + t.Fatalf("Failed to execute '%s' binary: %s\n", testSuid, err) + } + checker := ec.NewUnorderedEventChecker(execNoPrivilegesChangedChecker, execSetuidRootNoPrivilegesChangedChecker) + err = jsonchecker.JsonTestCheck(t, checker) + assert.NoError(t, err) +} + +// Test running with different combinations of setgid bit set +// 1. setgid() systemcall to arbitrary gid value then exec binary to +// assert credentials did not change. +// 2. executes a set-group-ID to root binary asserting that we detect +// the setgid bit set + the privileges changed due to the setgid bit +// being set to root group. +// 3. executes a set-group-ID to non root, it is set to arbitrary value +// to assert that binary execution detects the setgid bit but we do +// not report as a privilege changed execution as the target group +// is not root. +func TestExecProcessCredentialsSetgidChanges(t *testing.T) { + var doneWG, readyWG sync.WaitGroup + defer doneWG.Wait() + + ctx, cancel := context.WithTimeout(context.Background(), tus.Conf().CmdWaitTime) + defer cancel() + + obs, err := observertesthelper.GetDefaultObserver(t, ctx, tus.Conf().TetragonLib, observertesthelper.WithMyPid()) + if err != nil { + t.Fatalf("Failed to run observer: %s", err) + } + + testBin := testutils.RepoRootPath("contrib/tester-progs/nop") + // We should be able to create suid on local mount point + testSuid := testutils.RepoRootPath("contrib/tester-progs/suidnop") + if err := testutils.CopyFile(testSuid, testBin, 0754|os.ModeSetuid|os.ModeSetgid); err != nil { + t.Fatalf("Failed to copy binary: %s", err) + } + + observertesthelper.LoopEvents(ctx, t, &doneWG, &readyWG, obs) + readyWG.Wait() + + oldGid := syscall.Getgid() + /* Executing a setgid to root with current gid as normal not root */ gid := 1879048188 if err := syscall.Setgid(gid); err != nil { - t.Fatalf("setegid(%d) error: %s", gid, err) + t.Fatalf("setgid(%d) error: %s", gid, err) } + t.Cleanup(func() { + // Restore old gid + if err = syscall.Setgid(oldGid); err != nil { + t.Fatalf("Failed to restore gid to %d : %s\n", oldGid, err) + } + err := os.Remove(testSuid) + if err != nil { + t.Logf("Error failed to cleanup '%s'", testSuid) + } + }) + noGidCredsChanged := ec.NewProcessCredentialsChecker(). + WithUid(0).WithEuid(0).WithSuid(0).WithFsuid(0). + WithGid(uint32(gid)).WithEgid(uint32(gid)).WithSgid(uint32(gid)).WithFsgid(uint32(gid)) + procExecNoGidCredsChangedChecker := ec.NewProcessChecker().WithUid(uint32(0)). + WithBinary(sm.Full(testBin)).WithProcessCredentials(noGidCredsChanged).WithBinaryProperties(nil) + execNoGidsCredsChangedChecker := ec.NewProcessExecChecker("exec").WithProcess(procExecNoGidCredsChangedChecker) if err := exec.Command(testBin).Run(); err != nil { t.Fatalf("Failed to execute '%s' binary: %s\n", testBin, err) } + if err := os.Chown(testSuid, 0, 0); err != nil { + t.Fatalf("Chown() on '%s' binary error: %s\n", testSuid, err) + } + if err := os.Chmod(testSuid, 0754|os.ModeSetuid|os.ModeSetgid); err != nil { + t.Fatalf("Chown() on '%s' binary error: %s\n", testSuid, err) + } + /* Setgid to 0 */ + privsChangedRaiseSetgid := ec.NewProcessPrivilegesChangedListMatcher().WithOperator(lc.Ordered). + WithValues(ec.NewProcessPrivilegesChangedChecker(tetragon.ProcessPrivilegesChanged_PRIVILEGES_RAISED_EXEC_FILE_SETGID)) + bpSetgidRoot := ec.NewBinaryPropertiesChecker(). + WithSetgid(0).WithPrivilegesChanged(privsChangedRaiseSetgid) + setgidRootCreds := ec.NewProcessCredentialsChecker(). + WithUid(0).WithEuid(0).WithSuid(0).WithFsuid(0). + WithGid(uint32(gid)).WithEgid(0).WithSgid(0).WithFsgid(0) + procExecSetgidRootChecker := ec.NewProcessChecker().WithUid(uint32(0)). + WithBinary(sm.Full(testSuid)).WithProcessCredentials(setgidRootCreds).WithBinaryProperties(bpSetgidRoot) + execSetgidRootChecker := ec.NewProcessExecChecker("exec").WithProcess(procExecSetgidRootChecker) + procExitSetgidRootChecker := ec.NewProcessChecker().WithUid(uint32(0)). + WithBinary(sm.Full(testSuid)).WithProcessCredentials(setgidRootCreds).WithBinaryProperties(nil) + exitSetgidRootChecker := ec.NewProcessExitChecker("exit").WithProcess(procExitSetgidRootChecker) + if err := exec.Command(testSuid).Run(); err != nil { t.Fatalf("Failed to execute '%s' suid binary: %s\n", testSuid, err) } + /* Setuid to gid and Setgid to gid both are not root */ + /* First restore gid to root */ if err := syscall.Setgid(0); err != nil { t.Fatalf("setegid(%d) error: %s", gid, err) } @@ -974,64 +1079,187 @@ func TestExecProcessCredentialsSuid(t *testing.T) { t.Fatalf("Chown() on '%s' binary error: %s\n", testSuid, err) } + bpSetgidNoRoot := ec.NewBinaryPropertiesChecker(). + WithSetuid(uint32(gid)).WithSetgid(uint32(gid)).WithPrivilegesChanged(nil) + setgidNonRootCreds := ec.NewProcessCredentialsChecker(). + WithUid(0).WithEuid(uint32(gid)).WithSuid(uint32(gid)).WithFsuid(uint32(gid)). + WithGid(0).WithEgid(uint32(gid)).WithSgid(uint32(gid)).WithFsgid(uint32(gid)) + procExecSetgidNoRootChecker := ec.NewProcessChecker().WithUid(uint32(0)). + WithBinary(sm.Full(testSuid)).WithProcessCredentials(setgidNonRootCreds).WithBinaryProperties(bpSetgidNoRoot) + execSetgidNoRootChecker := ec.NewProcessExecChecker("exec").WithProcess(procExecSetgidNoRootChecker) + procExitSetgidNoRootChecker := ec.NewProcessChecker().WithUid(uint32(0)). + WithBinary(sm.Full(testSuid)).WithProcessCredentials(setgidNonRootCreds).WithBinaryProperties(nil) + exitSetgidNoRootChecker := ec.NewProcessExitChecker("exit").WithProcess(procExitSetgidNoRootChecker) + if err := exec.Command(testSuid).Run(); err != nil { t.Fatalf("Failed to execute secound round suid '%s' binary: %s\n", testSuid, err) } - /* Setgid to 0 */ - binaryProperties1 := ec.NewBinaryPropertiesChecker(). - WithSetgid(0) + checker := ec.NewUnorderedEventChecker(execNoGidsCredsChangedChecker, execSetgidRootChecker, exitSetgidRootChecker, execSetgidNoRootChecker, exitSetgidNoRootChecker) + err = jsonchecker.JsonTestCheck(t, checker) + assert.NoError(t, err) +} - /* Setuid and Setgid to gid */ - binaryProperties2 := ec.NewBinaryPropertiesChecker(). - WithSetuid(uint32(gid)).WithSetgid(uint32(gid)) +// Test running with different combinations of setuid bit set +// 1. executes a set-user-ID to non root, it is set to arbitrary value +// to assert that binary execution detects the setuid bit but we do +// not report as a privilege changed execution as the target user +// is not root. +// 2. executes a set-user-ID to root binary asserting that we detect +// the setuid bit set + the privileges changed due to the setuid bit +// being set to root. +func TestExecProcessCredentialsSetuidChanges(t *testing.T) { + var doneWG, readyWG sync.WaitGroup + defer doneWG.Wait() - normalCreds := ec.NewProcessCredentialsChecker(). - WithUid(0).WithEuid(0).WithSuid(0).WithFsuid(0). - WithGid(0).WithEgid(0).WithSgid(0).WithFsgid((0)) + ctx, cancel := context.WithTimeout(context.Background(), tus.Conf().CmdWaitTime) + defer cancel() - gidCreds := ec.NewProcessCredentialsChecker(). - WithUid(0).WithEuid(0).WithSuid(0).WithFsuid(0). - WithGid(uint32(gid)).WithEgid(uint32(gid)).WithSgid(uint32(gid)).WithFsgid(uint32(gid)) + obs, err := observertesthelper.GetDefaultObserver(t, ctx, tus.Conf().TetragonLib, observertesthelper.WithMyPid()) + if err != nil { + t.Fatalf("Failed to run observer: %s", err) + } - suidCreds1 := ec.NewProcessCredentialsChecker(). - WithUid(0).WithEuid(0).WithSuid(0).WithFsuid(0). - WithGid(uint32(gid)).WithEgid(0).WithSgid(0).WithFsgid(0) + testBin := testutils.RepoRootPath("contrib/tester-progs/nop") + // The drop-privileges is a helper binary that drops privileges so we do not + // drop it inside this test which will break the test framework. + testDrop := testutils.RepoRootPath("contrib/tester-progs/drop-privileges") + testSu, err := exec.LookPath("su") + if err != nil { + t.Skip("Could not find 'su' binary skipping") + } + // We should be able to create suid on local mount point + // This binary will have setuid set to non root. + testSuid := testutils.RepoRootPath("contrib/tester-progs/suidnop") + if err := testutils.CopyFile(testSuid, testBin, 0755|os.ModeSetuid|os.ModeSetgid); err != nil { + t.Fatalf("Failed to copy binary: %s", err) + } + t.Cleanup(func() { + err := os.Remove(testSuid) + if err != nil { + t.Logf("Error failed to cleanup '%s'", testSuid) + } + }) + + observertesthelper.LoopEvents(ctx, t, &doneWG, &readyWG, obs) + readyWG.Wait() + + gid := 1879048188 + if err := os.Chown(testSuid, gid, gid); err != nil { + t.Fatalf("Chown() on '%s' binary error: %s\n", testSuid, err) + } + + if err := os.Chmod(testSuid, 0755|os.ModeSetuid|os.ModeSetgid); err != nil { + t.Fatalf("Chown() on '%s' binary error: %s\n", testSuid, err) + } - suidCreds2 := ec.NewProcessCredentialsChecker(). + bpSetuidNoRoot := ec.NewBinaryPropertiesChecker(). + WithSetuid(uint32(gid)).WithSetgid(uint32(gid)).WithPrivilegesChanged(nil) + setuidNonRootCreds := ec.NewProcessCredentialsChecker(). WithUid(0).WithEuid(uint32(gid)).WithSuid(uint32(gid)).WithFsuid(uint32(gid)). WithGid(0).WithEgid(uint32(gid)).WithSgid(uint32(gid)).WithFsgid(uint32(gid)) + procExecSetuidNoRootChecker := ec.NewProcessChecker().WithUid(uint32(0)). + WithBinary(sm.Full(testSuid)).WithProcessCredentials(setuidNonRootCreds).WithBinaryProperties(bpSetuidNoRoot) + execSetuidNoRootChecker := ec.NewProcessExecChecker("exec").WithProcess(procExecSetuidNoRootChecker) + procExitSetuidNoRootChecker := ec.NewProcessChecker().WithUid(uint32(0)). + WithBinary(sm.Full(testSuid)).WithProcessCredentials(setuidNonRootCreds).WithBinaryProperties(nil) + exitSetuidNoRootChecker := ec.NewProcessExitChecker("exit").WithProcess(procExitSetuidNoRootChecker) + + if err := exec.Command(testSuid).Run(); err != nil { + t.Fatalf("Failed to execute suid '%s' binary: %s\n", testSuid, err) + } + + privsChangedRaiseSetuid := ec.NewProcessPrivilegesChangedListMatcher().WithOperator(lc.Ordered). + WithValues(ec.NewProcessPrivilegesChangedChecker(tetragon.ProcessPrivilegesChanged_PRIVILEGES_RAISED_EXEC_FILE_SETUID)) + bpSetuidRoot := ec.NewBinaryPropertiesChecker(). + WithSetuid(0).WithPrivilegesChanged(privsChangedRaiseSetuid) + setuidRootCreds := ec.NewProcessCredentialsChecker(). + WithUid(uint32(gid)).WithEuid(0).WithSuid(0).WithFsuid(0). + WithGid(uint32(gid)).WithEgid(uint32(gid)).WithSgid(uint32(gid)).WithFsgid(uint32(gid)) + procExecSetuidRootChecker := ec.NewProcessChecker().WithUid(uint32(gid)). + WithBinary(sm.Full(testSu)).WithProcessCredentials(setuidRootCreds).WithBinaryProperties(bpSetuidRoot) + execSetuidRootChecker := ec.NewProcessExecChecker("exec").WithProcess(procExecSetuidRootChecker) + procExitSetuidRootChecker := ec.NewProcessChecker().WithUid(uint32(gid)). + WithBinary(sm.Full(testSu)).WithProcessCredentials(setuidRootCreds).WithBinaryProperties(nil) + exitSetuidRootChecker := ec.NewProcessExitChecker("exit").WithProcess(procExitSetuidRootChecker) + + // We use the testDrop to drop uid so we don't break the test framework by + // chaning the uid here. The testDrop binary will execute su binary as we are sure + // its path allows to exec into directory but also execute the su binary. + // The result is based on the su binary being detected as a privilege_changed execution. + testCmd := exec.CommandContext(ctx, testDrop, testSu, "--help") + if err := testCmd.Start(); err != nil { + t.Fatal(err) + } + if err := testCmd.Wait(); err != nil { + t.Fatalf("command failed with %s. Context error: %v", err, ctx.Err()) + } + + checker := ec.NewUnorderedEventChecker(execSetuidNoRootChecker, exitSetuidNoRootChecker, execSetuidRootChecker, exitSetuidRootChecker) + err = jsonchecker.JsonTestCheck(t, checker) + assert.NoError(t, err) +} + +// Detect execution of binaries with file capability sets +func TestExecProcessCredentialsFileCapChanges(t *testing.T) { + var doneWG, readyWG sync.WaitGroup + defer doneWG.Wait() - procExecNormalChecker := ec.NewProcessChecker(). - WithBinary(sm.Full(testBin)).WithProcessCredentials(normalCreds).WithBinaryProperties(nil) - procExecGidChecker := ec.NewProcessChecker().WithUid(uint32(0)). - WithBinary(sm.Full(testBin)).WithProcessCredentials(gidCreds).WithBinaryProperties(nil) - procExecSuidChecker := ec.NewProcessChecker().WithUid(uint32(0)). - WithBinary(sm.Full(testSuid)).WithProcessCredentials(suidCreds1).WithBinaryProperties(binaryProperties1) - procExecSuid2Checker := ec.NewProcessChecker().WithUid(uint32(0)). - WithBinary(sm.Full(testSuid)).WithProcessCredentials(suidCreds2).WithBinaryProperties(binaryProperties2) + ctx, cancel := context.WithTimeout(context.Background(), tus.Conf().CmdWaitTime) + defer cancel() - procExitSuid1Checker := ec.NewProcessChecker().WithUid(uint32(0)). - WithBinary(sm.Full(testSuid)).WithProcessCredentials(suidCreds1).WithBinaryProperties(nil) + obs, err := observertesthelper.GetDefaultObserver(t, ctx, tus.Conf().TetragonLib, observertesthelper.WithMyPid()) + if err != nil { + t.Fatalf("Failed to run observer: %s", err) + } - procExitSuid2Checker := ec.NewProcessChecker().WithUid(uint32(0)). - WithBinary(sm.Full(testSuid)).WithProcessCredentials(suidCreds2).WithBinaryProperties(nil) + // The drop-privileges is a helper binary that drops privileges so we do not + // drop it inside this test which will break the test framework. + testDrop := testutils.RepoRootPath("contrib/tester-progs/drop-privileges") + testPing, err := exec.LookPath("ping") + if err != nil { + t.Skipf("Skipping test could not find 'ping' binary: %v", err) + } - execNormalChecker := ec.NewProcessExecChecker("exec").WithProcess(procExecNormalChecker) - execGidChecker := ec.NewProcessExecChecker("exec").WithProcess(procExecGidChecker) - execSuidChecker := ec.NewProcessExecChecker("exec").WithProcess(procExecSuidChecker) - execSuid2Checker := ec.NewProcessExecChecker("exec").WithProcess(procExecSuid2Checker) - exitSuid1Checker := ec.NewProcessExitChecker("exit").WithProcess(procExitSuid1Checker) - exitSuid2Checker := ec.NewProcessExitChecker("exit").WithProcess(procExitSuid2Checker) + xattrs := make([]byte, 0) + ret, err := unix.Getxattr(testPing, "security.capability", xattrs) + if err != nil { + t.Skipf("Skipping test could 'security.capability' xattr of binary '%s' error: %v", testPing, err) + } + if ret == 0 { + t.Skipf("Skipping test 'security.capability' xattr is not set on binary '%s'", testPing) + } + + observertesthelper.LoopEvents(ctx, t, &doneWG, &readyWG, obs) + readyWG.Wait() - if err = syscall.Setuid(0); err != nil { - t.Fatalf("Failed to restore uid to 0 : %s\n", err) + gid := 1879048188 + privsChangedRaiseFscaps := ec.NewProcessPrivilegesChangedListMatcher().WithOperator(lc.Ordered). + WithValues(ec.NewProcessPrivilegesChangedChecker(tetragon.ProcessPrivilegesChanged_PRIVILEGES_RAISED_EXEC_FILE_CAP)) + bp := ec.NewBinaryPropertiesChecker().WithPrivilegesChanged(privsChangedRaiseFscaps) + noRootCreds := ec.NewProcessCredentialsChecker(). + WithUid(uint32(gid)).WithEuid(uint32(gid)).WithSuid(uint32(gid)).WithFsuid(uint32(gid)). + WithGid(uint32(gid)).WithEgid(uint32(gid)).WithSgid(uint32(gid)).WithFsgid(uint32(gid)) + procExecFsCapsChecker := ec.NewProcessChecker().WithUid(uint32(gid)). + WithBinary(sm.Full(testPing)).WithProcessCredentials(noRootCreds).WithBinaryProperties(bp) + execChecker := ec.NewProcessExecChecker("exec").WithProcess(procExecFsCapsChecker) + procExitFsCapsChecker := ec.NewProcessChecker().WithUid(uint32(gid)). + WithBinary(sm.Full(testPing)).WithProcessCredentials(noRootCreds).WithBinaryProperties(nil) + exitChecker := ec.NewProcessExitChecker("exit").WithProcess(procExitFsCapsChecker) + + // We use the testDrop to drop uid so we don't break the test framework by + // changing the uid here. The testDrop binary will execute ping binary as we are sure + // its path allows to exec into directory but also execute the ping binary. + // The result is based on the ping binary being detected as a privilege_changed execution. + testCmd := exec.CommandContext(ctx, testDrop, testPing, "-V") + if err := testCmd.Start(); err != nil { + t.Fatal(err) } - if err = syscall.Setgid(0); err != nil { - t.Fatalf("Failed to restore gid to 0 : %s\n", err) + if err := testCmd.Wait(); err != nil { + t.Fatalf("command failed with %s. Context error: %v", err, ctx.Err()) } - checker := ec.NewUnorderedEventChecker(execNormalChecker, execGidChecker, execSuidChecker, execSuid2Checker, exitSuid1Checker, exitSuid2Checker) + checker := ec.NewUnorderedEventChecker(execChecker, exitChecker) err = jsonchecker.JsonTestCheck(t, checker) assert.NoError(t, err) } diff --git a/pkg/sensors/tracing/generickprobe.go b/pkg/sensors/tracing/generickprobe.go index e9ed5f0af99..3015fc2700f 100644 --- a/pkg/sensors/tracing/generickprobe.go +++ b/pkg/sensors/tracing/generickprobe.go @@ -123,6 +123,9 @@ type genericKprobe struct { // policyName is the name of the policy that this tracepoint belongs to policyName string + // message field of the Tracing Policy + message string + // is there override defined for the kprobe hasOverride bool @@ -511,19 +514,6 @@ func preValidateKprobes(name string, kprobes []v1alpha1.KProbeSpec, lists []v1al return nil } -const ( - flagsEarlyFilter = 1 << 0 -) - -func flagsString(flags uint32) string { - s := "none" - - if flags&flagsEarlyFilter != 0 { - s = "early_filter" - } - return s -} - type addKprobeIn struct { useMulti bool sensorPath string @@ -691,6 +681,13 @@ func addKprobe(funcName string, f *v1alpha1.KProbeSpec, in *addKprobeIn) (id idt } } + msgField, err := getPolicyMessage(f.Message) + if errors.Is(err, ErrMsgSyntaxShort) || errors.Is(err, ErrMsgSyntaxEscape) { + return errFn(fmt.Errorf("Error: '%v'", err)) + } else if errors.Is(err, ErrMsgSyntaxLong) { + logger.GetLogger().WithField("policy-name", in.policyName).Warnf("TracingPolicy 'message' field too long, truncated to %d characters", TpMaxMessageLen) + } + argRetprobe = nil // holds pointer to arg for return handler // Parse Arguments @@ -789,10 +786,6 @@ func addKprobe(funcName string, f *v1alpha1.KProbeSpec, in *addKprobeIn) (id idt config.Syscall = 0 } - if selectors.HasEarlyBinaryFilter(f.Selectors) { - config.Flags |= flagsEarlyFilter - } - // create a new entry on the table, and pass its id to BPF-side // so that we can do the matching at event-generation time kprobeEntry := genericKprobe{ @@ -809,6 +802,7 @@ func addKprobe(funcName string, f *v1alpha1.KProbeSpec, in *addKprobeIn) (id idt policyName: in.policyName, hasOverride: selectors.HasOverride(f), customHandler: in.customHandler, + message: msgField, } // Parse Filters into kernel filter logic @@ -943,8 +937,7 @@ func createKprobeSensorFromEntry(kprobeEntry *genericKprobe, sensorPath string, } } - logger.GetLogger().WithField("flags", flagsString(kprobeEntry.loadArgs.config.Flags)). - WithField("override", kprobeEntry.hasOverride). + logger.GetLogger().WithField("override", kprobeEntry.hasOverride). Infof("Added generic kprobe sensor: %s -> %s", load.Name, load.Attach) return progs, maps } @@ -1222,6 +1215,7 @@ func handleMsgGenericKprobe(m *api.MsgGenericKprobe, gk *genericKprobe, r *bytes unix.Namespaces = m.Namespaces unix.Capabilities = m.Capabilities unix.PolicyName = gk.policyName + unix.Message = gk.message returnEvent := m.Common.Flags&processapi.MSG_COMMON_FLAG_RETURN != 0 diff --git a/pkg/sensors/tracing/generictracepoint.go b/pkg/sensors/tracing/generictracepoint.go index 308e0a81c3a..aa1df0dbb93 100644 --- a/pkg/sensors/tracing/generictracepoint.go +++ b/pkg/sensors/tracing/generictracepoint.go @@ -81,6 +81,9 @@ type genericTracepoint struct { // policyName is the name of the policy that this tracepoint belongs to policyName string + // message field of the Tracing Policy + message string + // parsed kernel selector state selectors *selectors.KernelSelectorState @@ -322,6 +325,13 @@ func createGenericTracepoint( Event: conf.Event, } + msgField, err := getPolicyMessage(conf.Message) + if errors.Is(err, ErrMsgSyntaxShort) || errors.Is(err, ErrMsgSyntaxEscape) { + return nil, err + } else if errors.Is(err, ErrMsgSyntaxLong) { + logger.GetLogger().WithField("policy-name", policyName).Warnf("TracingPolicy 'message' field too long, truncated to %d characters", TpMaxMessageLen) + } + if err := tp.LoadFormat(); err != nil { return nil, fmt.Errorf("tracepoint %s/%s not supported: %w", tp.Subsys, tp.Event, err) } @@ -338,6 +348,7 @@ func createGenericTracepoint( policyID: policyID, policyName: policyName, customHandler: customHandler, + message: msgField, } genericTracepointTable.addTracepoint(ret) @@ -559,10 +570,6 @@ func (tp *genericTracepoint) EventConfig() (api.EventConfig, error) { config.ArgM[i] = uint32(0) } - if selectors.HasEarlyBinaryFilter(tp.Spec.Selectors) { - config.Flags |= flagsEarlyFilter - } - return config, nil } @@ -598,8 +605,7 @@ func LoadGenericTracepointSensor(bpfDir, mapDir string, load *program.Program, v load.MapLoad = append(load.MapLoad, cfg) if err := program.LoadTracepointProgram(bpfDir, mapDir, load, verbose); err == nil { - logger.GetLogger().WithField("flags", flagsString(config.Flags)). - Infof("Loaded generic tracepoint program: %s -> %s", load.Name, load.Attach) + logger.GetLogger().Infof("Loaded generic tracepoint program: %s -> %s", load.Name, load.Attach) } else { return err } @@ -665,6 +671,7 @@ func handleMsgGenericTracepoint( unix.Subsys = tp.Info.Subsys unix.Event = tp.Info.Event unix.PolicyName = tp.policyName + unix.Message = tp.message for idx, out := range tp.args { diff --git a/pkg/sensors/tracing/genericuprobe.go b/pkg/sensors/tracing/genericuprobe.go index d395f5f08aa..6afac6764cc 100644 --- a/pkg/sensors/tracing/genericuprobe.go +++ b/pkg/sensors/tracing/genericuprobe.go @@ -6,6 +6,7 @@ package tracing import ( "bytes" "encoding/binary" + "errors" "fmt" "path" "sync/atomic" @@ -44,6 +45,8 @@ type genericUprobe struct { selectors *selectors.KernelSelectorState // policyName is the name of the policy that this uprobe belongs to policyName string + // message field of the Tracing Policy + message string } func (g *genericUprobe) SetID(id idtable.EntryID) { @@ -92,6 +95,7 @@ func handleGenericUprobe(r *bytes.Reader) ([]observer.Event, error) { unix.Path = uprobeEntry.path unix.Symbol = uprobeEntry.symbol unix.PolicyName = uprobeEntry.policyName + unix.Message = uprobeEntry.message return []observer.Event{unix}, err } @@ -136,8 +140,7 @@ func (k *observerUprobeSensor) LoadProbe(args sensors.LoadProbeArgs) error { return err } - logger.GetLogger().WithField("flags", flagsString(uprobeEntry.config.Flags)). - Infof("Loaded generic uprobe program: %s -> %s [%s]", args.Load.Name, uprobeEntry.path, uprobeEntry.symbol) + logger.GetLogger().Infof("Loaded generic uprobe program: %s -> %s [%s]", args.Load.Name, uprobeEntry.path, uprobeEntry.symbol) return nil } @@ -189,6 +192,13 @@ func createGenericUprobeSensor( return nil, err } + msgField, err := getPolicyMessage(spec.Message) + if errors.Is(err, ErrMsgSyntaxShort) || errors.Is(err, ErrMsgSyntaxEscape) { + return nil, err + } else if errors.Is(err, ErrMsgSyntaxLong) { + logger.GetLogger().WithField("policy-name", policyName).Warnf("TracingPolicy 'message' field too long, truncated to %d characters", TpMaxMessageLen) + } + uprobeEntry := &genericUprobe{ tableId: idtable.UninitializedEntryID, config: config, @@ -196,6 +206,7 @@ func createGenericUprobeSensor( symbol: spec.Symbol, selectors: uprobeSelectorState, policyName: policyName, + message: msgField, } uprobeTable.AddEntry(uprobeEntry) @@ -204,10 +215,6 @@ func createGenericUprobeSensor( uprobeEntry.pinPathPrefix = sensors.PathJoin(sensorPath, fmt.Sprintf("%d", id)) config.FuncId = uint32(id) - if selectors.HasEarlyBinaryFilter(spec.Selectors) { - config.Flags |= flagsEarlyFilter - } - pinPath := uprobeEntry.pinPathPrefix pinProg := sensors.PathJoin(pinPath, "prog") diff --git a/pkg/sensors/tracing/kprobe_test.go b/pkg/sensors/tracing/kprobe_test.go index 28cdeeb3df5..158d89c2fdb 100644 --- a/pkg/sensors/tracing/kprobe_test.go +++ b/pkg/sensors/tracing/kprobe_test.go @@ -4142,7 +4142,7 @@ func TestLoadKprobeSensor(t *testing.T) { tus.SensorMap{Name: "override_tasks", Progs: []uint{5}}, // all kprobe but generic_kprobe_process_filter,generic_retkprobe_event - tus.SensorMap{Name: "config_map", Progs: []uint{0, 1, 2, 3}}, + tus.SensorMap{Name: "config_map", Progs: []uint{0, 1, 2}}, // generic_kprobe_process_event*,generic_kprobe_actions,retkprobe tus.SensorMap{Name: "fdinstall_map", Progs: []uint{1, 2, 5, 7, 9}}, @@ -4153,7 +4153,7 @@ func TestLoadKprobeSensor(t *testing.T) { if kernels.EnableLargeProgs() { // shared with base sensor - sensorMaps = append(sensorMaps, tus.SensorMap{Name: "execve_map", Progs: []uint{0, 3, 4, 5, 6, 7, 9}}) + sensorMaps = append(sensorMaps, tus.SensorMap{Name: "execve_map", Progs: []uint{4, 5, 6, 7, 9}}) // generic_kprobe_process_event*,generic_kprobe_output,generic_retkprobe_output sensorMaps = append(sensorMaps, tus.SensorMap{Name: "tcpmon_map", Progs: []uint{1, 2, 6, 10}}) @@ -4162,7 +4162,7 @@ func TestLoadKprobeSensor(t *testing.T) { sensorMaps = append(sensorMaps, tus.SensorMap{Name: "socktrack_map", Progs: []uint{1, 2, 5, 7, 9}}) } else { // shared with base sensor - sensorMaps = append(sensorMaps, tus.SensorMap{Name: "execve_map", Progs: []uint{0, 3, 4, 7}}) + sensorMaps = append(sensorMaps, tus.SensorMap{Name: "execve_map", Progs: []uint{4, 7}}) // generic_kprobe_output,generic_retkprobe_output sensorMaps = append(sensorMaps, tus.SensorMap{Name: "tcpmon_map", Progs: []uint{6, 10}}) @@ -5959,6 +5959,7 @@ spec: - call: "security_file_permission" syscall: false return: true + message: "Access sensitive files /etc/passwd" args: - index: 0 type: "file" # (struct file *) used for getting the path @@ -5981,6 +5982,7 @@ spec: - call: "security_mmap_file" syscall: false return: true + message: "Access sensitive files /etc/shadow" args: - index: 0 type: "file" # (struct file *) used for getting the path @@ -6026,6 +6028,7 @@ spec: readMmapFile(t, "/etc/shadow") kpCheckersRead := ec.NewProcessKprobeChecker(""). + WithMessage(sm.Full("Access sensitive files /etc/passwd")). WithFunctionName(sm.Full("security_file_permission")). WithArgs(ec.NewKprobeArgumentListMatcher(). WithOperator(lc.Ordered). @@ -6035,6 +6038,7 @@ spec: )) kpCheckersMmap := ec.NewProcessKprobeChecker(""). + WithMessage(sm.Full("Access sensitive files /etc/shadow")). WithFunctionName(sm.Full("security_mmap_file")). WithArgs(ec.NewKprobeArgumentListMatcher(). WithOperator(lc.Ordered). diff --git a/pkg/sensors/tracing/message.go b/pkg/sensors/tracing/message.go new file mode 100644 index 00000000000..5db201edc6b --- /dev/null +++ b/pkg/sensors/tracing/message.go @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Authors of Tetragon + +package tracing + +import ( + "errors" + "fmt" +) + +const ( + // Max length of message field of a Tracing Policy + TpMaxMessageLen = 256 + // Minimum length of message field ot a Tracing Policy + // so it makes sense and we ensure it is not single + // quoted character, we want double quoted string + TpMinMessageLen = 2 +) + +var ( + ErrMsgSyntaxLong = errors.New("message field is too long") + ErrMsgSyntaxShort = errors.New("message field is too short") + ErrMsgSyntaxEmpty = errors.New("message field is empty") + ErrMsgSyntaxEscape = errors.New("message field escape failed") +) + +// getPolicyMessage() Validates and escapes the passed message. +// +// Returns: On success the validated message of max length TpMaxMessageLen. +// On failures an error is set. +// +// If the message length is more than TpMaxMessageLen +// then the truncated message to TpMaxMessageLen with the error +// ErrMsgTooLong will be returned. +func getPolicyMessage(message string) (string, error) { + if message == "" { + return "", ErrMsgSyntaxEmpty + } + + var err error + msgLen := len(message) + if msgLen < TpMinMessageLen { + return "", ErrMsgSyntaxShort + } else if msgLen > TpMaxMessageLen { + msgLen = TpMaxMessageLen + err = ErrMsgSyntaxLong + } + + msg := fmt.Sprintf("%q", message[:msgLen]) + newLen := len(msg) + if newLen <= msgLen || msg[0] != '"' || msg[newLen-1] != '"' { + return "", ErrMsgSyntaxEscape + } + + // Remove double quoted string so we pretty print it later in the events + return msg[1 : newLen-1], err +} diff --git a/pkg/sensors/tracing/message_test.go b/pkg/sensors/tracing/message_test.go new file mode 100644 index 00000000000..dc57bc64a75 --- /dev/null +++ b/pkg/sensors/tracing/message_test.go @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Authors of Tetragon + +package tracing + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestGetPolicyMessage(t *testing.T) { + msg, err := getPolicyMessage("") + require.Empty(t, msg) + require.Equal(t, err, ErrMsgSyntaxEmpty) + + msg, err = getPolicyMessage("a") + require.Empty(t, msg) + require.Equal(t, err, ErrMsgSyntaxShort) + + msg, err = getPolicyMessage("test") + require.NoError(t, err) + require.Equal(t, msg, "test") + + msg, err = getPolicyMessage(strings.Repeat("a", TpMaxMessageLen+1)) + require.Equal(t, err, ErrMsgSyntaxLong) + require.Equal(t, TpMaxMessageLen, len(msg)) +} diff --git a/pkg/sensors/tracing/tracepoint_test.go b/pkg/sensors/tracing/tracepoint_test.go index eeb0169d40c..0fcc51e5d73 100644 --- a/pkg/sensors/tracing/tracepoint_test.go +++ b/pkg/sensors/tracing/tracepoint_test.go @@ -25,6 +25,7 @@ import ( "github.com/cilium/tetragon/pkg/kernels" "github.com/cilium/tetragon/pkg/logger" lc "github.com/cilium/tetragon/pkg/matchers/listmatcher" + sm "github.com/cilium/tetragon/pkg/matchers/stringmatcher" smatcher "github.com/cilium/tetragon/pkg/matchers/stringmatcher" "github.com/cilium/tetragon/pkg/observer/observertesthelper" "github.com/cilium/tetragon/pkg/policyfilter" @@ -443,7 +444,7 @@ func TestLoadTracepointSensor(t *testing.T) { tus.SensorMap{Name: "tcpmon_map", Progs: []uint{5}}, // all kprobe but generic_tracepoint_filter - tus.SensorMap{Name: "config_map", Progs: []uint{0, 1, 2}}, + tus.SensorMap{Name: "config_map", Progs: []uint{0, 2}}, // generic_tracepoint_event tus.SensorMap{Name: "tg_conf_map", Progs: []uint{0}}, @@ -451,10 +452,10 @@ func TestLoadTracepointSensor(t *testing.T) { if kernels.EnableLargeProgs() { // shared with base sensor - sensorMaps = append(sensorMaps, tus.SensorMap{Name: "execve_map", Progs: []uint{0, 1, 3, 4, 5}}) + sensorMaps = append(sensorMaps, tus.SensorMap{Name: "execve_map", Progs: []uint{3, 4, 5}}) } else { // shared with base sensor - sensorMaps = append(sensorMaps, tus.SensorMap{Name: "execve_map", Progs: []uint{0, 1, 3}}) + sensorMaps = append(sensorMaps, tus.SensorMap{Name: "execve_map", Progs: []uint{3}}) } readHook := ` @@ -610,6 +611,7 @@ spec: tracepoints: - subsystem: "syscalls" event: "sys_enter_lseek" + message: "System call lseek tracepoint test" # args: add both the syscall id, and the array with the arguments args: # fd argument @@ -673,6 +675,7 @@ spec: child1TpChecker := ec.NewProcessTracepointChecker(""). WithSubsys(smatcher.Full("syscalls")). WithEvent(smatcher.Full("sys_enter_lseek")). + WithMessage(sm.Full("System call lseek tracepoint test")). WithArgs(ec.NewKprobeArgumentListMatcher(). WithOperator(lc.Ordered). WithValues( @@ -688,6 +691,7 @@ spec: thread1TpChecker := ec.NewProcessTracepointChecker(""). WithSubsys(smatcher.Full("syscalls")). WithEvent(smatcher.Full("sys_enter_lseek")). + WithMessage(sm.Full("System call lseek tracepoint test")). WithArgs(ec.NewKprobeArgumentListMatcher(). WithOperator(lc.Ordered). WithValues( diff --git a/pkg/sensors/tracing/uprobe_test.go b/pkg/sensors/tracing/uprobe_test.go index dccda614e82..2eec2457976 100644 --- a/pkg/sensors/tracing/uprobe_test.go +++ b/pkg/sensors/tracing/uprobe_test.go @@ -53,10 +53,10 @@ func TestLoadUprobeSensor(t *testing.T) { if kernels.EnableLargeProgs() { // shared with base sensor - sensorMaps = append(sensorMaps, tus.SensorMap{Name: "execve_map", Progs: []uint{0, 3, 4, 5, 6}}) + sensorMaps = append(sensorMaps, tus.SensorMap{Name: "execve_map", Progs: []uint{4, 5, 6}}) } else { // shared with base sensor - sensorMaps = append(sensorMaps, tus.SensorMap{Name: "execve_map", Progs: []uint{0, 3, 4}}) + sensorMaps = append(sensorMaps, tus.SensorMap{Name: "execve_map", Progs: []uint{4}}) } nopHook := ` @@ -281,6 +281,7 @@ spec: uprobes: - path: "` + testBin + `" symbol: "do_uprobe" + message: "Uprobe test" selectors: - matchBinaries: - operator: "In" @@ -340,6 +341,7 @@ spec: WithTid(cti.Child1Tid) child1UpChecker := ec.NewProcessUprobeChecker(""). + WithMessage(sm.Full("Uprobe test")). WithSymbol(sm.Full("do_uprobe")). WithProcess(child1Checker).WithParent(parentCheck) @@ -349,6 +351,7 @@ spec: WithTid(cti.Thread1Tid) thread1UpChecker := ec.NewProcessUprobeChecker(""). + WithMessage(sm.Full("Uprobe test")). WithSymbol(sm.Full("do_uprobe")). WithProcess(thread1Checker).WithParent(parentCheck) diff --git a/pkg/vmtests/list.go b/pkg/vmtests/list.go index 8962f1c7824..04d31f80a5a 100644 --- a/pkg/vmtests/list.go +++ b/pkg/vmtests/list.go @@ -27,18 +27,31 @@ func (t *GoTest) ToString() string { return fmt.Sprintf("%s:%s", t.PackageProg, t.Test) } -func fromString(s string) GoTest { +func fromString(testDir, s string) []GoTest { + sl := strings.SplitN(s, ":", 2) - ret := GoTest{ - PackageProg: sl[0], + prog := sl[0] + if len(sl) < 2 { + return []GoTest{{PackageProg: prog}} + } + + pattern := sl[1] + tests, err := listTests(testDir, prog, pattern) + if err != nil { + // NB: we failed to list the tests of a package. Just append the prog. + return []GoTest{{PackageProg: prog}} } - if len(sl) == 2 { - ret.Test = sl[1] + + ret := []GoTest{} + for _, test := range tests { + t := GoTest{PackageProg: prog, Test: test} + ret = append(ret, t) } + return ret } -func LoadTestsFromFile(fname string) ([]GoTest, error) { +func LoadTestsFromFile(testDir string, fname string) ([]GoTest, error) { f, err := os.Open(fname) if err != nil { return nil, err @@ -49,7 +62,10 @@ func LoadTestsFromFile(fname string) ([]GoTest, error) { var ret []GoTest for scanner.Scan() { txt := scanner.Text() - ret = append(ret, fromString(txt)) + if strings.HasPrefix(txt, "#") { + continue + } + ret = append(ret, fromString(testDir, txt)...) } if err := scanner.Err(); err != nil { @@ -85,7 +101,7 @@ func ListTests( continue } - tests, err := listTests(testDir, prog) + tests, err := listTests(testDir, prog, ".") if err != nil { // NB: we failed to list the tests of a package. Just append the prog. ret = append(ret, GoTest{PackageProg: prog}) @@ -136,12 +152,19 @@ func listTestProgs(testDir string, blacklist []GoTest) ([]string, error) { return ret, nil } -// listTests list the test of a test program by passing "-test.list ." to it. -func listTests(testDir string, testProg string) ([]string, error) { +// listTests list the test of a test program by passing "-test.list " to it. +func listTests(testDir string, testProg string, testPattern string) ([]string, error) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() + + // Callers should use ".", but as a sanity check if pattern is empty, we set the pattern to + // "." + if testPattern == "" { + testPattern = "." + } + prog := filepath.Join(testDir, testProg) - listCmd := exec.CommandContext(ctx, prog, "-test.list", ".") + listCmd := exec.CommandContext(ctx, prog, "-test.list", testPattern) out, err := listCmd.CombinedOutput() if err != nil { return nil, err diff --git a/pkg/vmtests/vmtests.go b/pkg/vmtests/vmtests.go index eece19bd843..55274ffd5a5 100644 --- a/pkg/vmtests/vmtests.go +++ b/pkg/vmtests/vmtests.go @@ -122,7 +122,7 @@ func Run(cnf *Conf) error { if testFile[0] != '/' { testFile = filepath.Join(cnf.TetragonDir, testFile) } - tests, err = LoadTestsFromFile(testFile) + tests, err = LoadTestsFromFile(testDir, testFile) if err != nil { return err } @@ -160,8 +160,10 @@ func Run(cnf *Conf) error { prog := filepath.Join(testDir, name) progArgs := []string{"-test.v"} if test.Test != "" { - t := test.Test - name = fmt.Sprintf("%s.%s", name, t) + name = fmt.Sprintf("%s.%s", name, test.Test) + // It is possible that a test is a substring of another. Use a strict + // pattern so that we execute only the specified test. + t := fmt.Sprintf("^%s$", test.Test) progArgs = append(progArgs, "-test.run", t) } diff --git a/tests/e2e/tests/policyfilter/policyfilter_test.go b/tests/e2e/tests/policyfilter/policyfilter_test.go index f3b831fcfb9..2dc3e4a45e4 100644 --- a/tests/e2e/tests/policyfilter/policyfilter_test.go +++ b/tests/e2e/tests/policyfilter/policyfilter_test.go @@ -118,6 +118,14 @@ func TestNamespacedPolicy(t *testing.T) { } return ctx }). + Assess("Uninstall policy", func(ctx context.Context, _ *testing.T, c *envconf.Config) context.Context { + ctx, err := helpers.UnloadCRDString(policyNamespace, namespacedPolicy, false)(ctx, c) + if err != nil { + klog.ErrorS(err, "failed to uninstall policy") + t.Fail() + } + return ctx + }). Feature() runner.TestInParallel(t, runWorkload, runEventChecker) @@ -241,6 +249,14 @@ func TestPodLabelFilters(t *testing.T) { } return ctx }). + Assess("Uninstall policy", func(ctx context.Context, _ *testing.T, c *envconf.Config) context.Context { + ctx, err := helpers.UnloadCRDString(podlblNamespace, podlblPolicy, false)(ctx, c) + if err != nil { + klog.ErrorS(err, "failed to uninstall policy") + t.Fail() + } + return ctx + }). Feature() runner.TestInParallel(t, runWorkload, runEventChecker) diff --git a/tests/e2e/tests/skeleton/skeleton_test.go b/tests/e2e/tests/skeleton/skeleton_test.go index 76a45f48d4f..f72f9f3fe9f 100644 --- a/tests/e2e/tests/skeleton/skeleton_test.go +++ b/tests/e2e/tests/skeleton/skeleton_test.go @@ -113,6 +113,14 @@ func TestSkeletonBasic(t *testing.T) { t.Fail() } return ctx + }). + Assess("Uninstall policy", func(ctx context.Context, _ *testing.T, c *envconf.Config) context.Context { + ctx, err := helpers.UnloadCRDString(namespace, curlPod, true)(ctx, c) + if err != nil { + klog.ErrorS(err, "failed to spawn workload") + t.Fail() + } + return ctx }).Feature() // We run our features using testenv.Test() or testenv.TestInParallel(). These take diff --git a/vendor/github.com/cilium/tetragon/api/v1/tetragon/capabilities.pb.go b/vendor/github.com/cilium/tetragon/api/v1/tetragon/capabilities.pb.go index be5ac6df28b..2663ed583b5 100644 --- a/vendor/github.com/cilium/tetragon/api/v1/tetragon/capabilities.pb.go +++ b/vendor/github.com/cilium/tetragon/api/v1/tetragon/capabilities.pb.go @@ -373,6 +373,89 @@ func (SecureBitsType) EnumDescriptor() ([]byte, []int) { return file_tetragon_capabilities_proto_rawDescGZIP(), []int{1} } +// Reasons of why the process privileges changed. +type ProcessPrivilegesChanged int32 + +const ( + ProcessPrivilegesChanged_PRIVILEGES_CHANGED_UNSET ProcessPrivilegesChanged = 0 + // A privilege elevation happened due to the execution of a binary with file capability sets. + // The kernel supports associating capability sets with an executable file using `setcap` command. + // The file capability sets are stored in an extended attribute (see https://man7.org/linux/man-pages/man7/xattr.7.html) + // named `security.capability`. The file capability sets, in conjunction with the capability sets + // of the process, determine the process capabilities and privileges after the `execve` system call. + // For further reference, please check sections `File capability extended attribute versioning` and + // `Namespaced file capabilities` of the capabilities man pages: https://man7.org/linux/man-pages/man7/capabilities.7.html. + // The new granted capabilities can be listed inside the `process` object. + ProcessPrivilegesChanged_PRIVILEGES_RAISED_EXEC_FILE_CAP ProcessPrivilegesChanged = 1 + // A privilege elevation happened due to the execution of a binary with set-user-ID to root. + // When a process with nonzero UIDs executes a binary with a set-user-ID to root also + // known as suid-root executable, then the kernel switches the effective user ID to 0 (root) which + // is a privilege elevation operation since it grants access to resources owned by the root user. + // The effective user ID is listed inside the `process_credentials` part of the `process` object. + // For further reading, section `Capabilities and execution of programs by root` of https://man7.org/linux/man-pages/man7/capabilities.7.html. + // Afterward the kernel recalculates the capability sets of the process and grants all capabilities + // in the permitted and effective capability sets, except those masked out by the capability bounding set. + // If the binary also have file capability sets then these bits are honored and the process gains just + // the capabilities granted by the file capability sets (i.e., not all capabilities, as it would occur + // when executing a set-user-ID to root binary that does not have any associated file capabilities). This + // is described in section `Set-user-ID-root programs that have file capabilities` of https://man7.org/linux/man-pages/man7/capabilities.7.html. + // The new granted capabilities can be listed inside the `process` object. + // There is one exception for the special treatments of set-user-ID to root execution receiving all + // capabilities, if the `SecBitNoRoot` bit of the Secure bits is set, then the kernel does not grant + // any capability. Please check section: `The securebits flags: establishing a capabilities-only environment` + // of the capabilities man pages: https://man7.org/linux/man-pages/man7/capabilities.7.html + ProcessPrivilegesChanged_PRIVILEGES_RAISED_EXEC_FILE_SETUID ProcessPrivilegesChanged = 2 + // A privilege elevation happened due to the execution of a binary with set-group-ID to root. + // When a process with nonzero GIDs executes a binary with a set-group-ID to root, the kernel switches + // the effective group ID to 0 (root) which is a privilege elevation operation since it grants access to + // resources owned by the root group. + // The effective group ID is listed inside the `process_credentials` part of the `process` object. + ProcessPrivilegesChanged_PRIVILEGES_RAISED_EXEC_FILE_SETGID ProcessPrivilegesChanged = 3 +) + +// Enum value maps for ProcessPrivilegesChanged. +var ( + ProcessPrivilegesChanged_name = map[int32]string{ + 0: "PRIVILEGES_CHANGED_UNSET", + 1: "PRIVILEGES_RAISED_EXEC_FILE_CAP", + 2: "PRIVILEGES_RAISED_EXEC_FILE_SETUID", + 3: "PRIVILEGES_RAISED_EXEC_FILE_SETGID", + } + ProcessPrivilegesChanged_value = map[string]int32{ + "PRIVILEGES_CHANGED_UNSET": 0, + "PRIVILEGES_RAISED_EXEC_FILE_CAP": 1, + "PRIVILEGES_RAISED_EXEC_FILE_SETUID": 2, + "PRIVILEGES_RAISED_EXEC_FILE_SETGID": 3, + } +) + +func (x ProcessPrivilegesChanged) Enum() *ProcessPrivilegesChanged { + p := new(ProcessPrivilegesChanged) + *p = x + return p +} + +func (x ProcessPrivilegesChanged) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ProcessPrivilegesChanged) Descriptor() protoreflect.EnumDescriptor { + return file_tetragon_capabilities_proto_enumTypes[2].Descriptor() +} + +func (ProcessPrivilegesChanged) Type() protoreflect.EnumType { + return &file_tetragon_capabilities_proto_enumTypes[2] +} + +func (x ProcessPrivilegesChanged) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ProcessPrivilegesChanged.Descriptor instead. +func (ProcessPrivilegesChanged) EnumDescriptor() ([]byte, []int) { + return file_tetragon_capabilities_proto_rawDescGZIP(), []int{2} +} + var File_tetragon_capabilities_proto protoreflect.FileDescriptor var file_tetragon_capabilities_proto_rawDesc = []byte{ @@ -444,7 +527,18 @@ var file_tetragon_capabilities_proto_rawDesc = []byte{ 0x61, 0x70, 0x41, 0x6d, 0x62, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x61, 0x69, 0x73, 0x65, 0x10, 0x40, 0x12, 0x22, 0x0a, 0x1d, 0x53, 0x65, 0x63, 0x42, 0x69, 0x74, 0x4e, 0x6f, 0x43, 0x61, 0x70, 0x41, 0x6d, 0x62, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x61, 0x69, 0x73, 0x65, 0x4c, 0x6f, 0x63, 0x6b, 0x65, - 0x64, 0x10, 0x80, 0x01, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x64, 0x10, 0x80, 0x01, 0x2a, 0xad, 0x01, 0x0a, 0x18, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, + 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x64, 0x12, 0x1c, 0x0a, 0x18, 0x50, 0x52, 0x49, 0x56, 0x49, 0x4c, 0x45, 0x47, 0x45, 0x53, 0x5f, + 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x45, 0x54, 0x10, 0x00, 0x12, + 0x23, 0x0a, 0x1f, 0x50, 0x52, 0x49, 0x56, 0x49, 0x4c, 0x45, 0x47, 0x45, 0x53, 0x5f, 0x52, 0x41, + 0x49, 0x53, 0x45, 0x44, 0x5f, 0x45, 0x58, 0x45, 0x43, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x5f, 0x43, + 0x41, 0x50, 0x10, 0x01, 0x12, 0x26, 0x0a, 0x22, 0x50, 0x52, 0x49, 0x56, 0x49, 0x4c, 0x45, 0x47, + 0x45, 0x53, 0x5f, 0x52, 0x41, 0x49, 0x53, 0x45, 0x44, 0x5f, 0x45, 0x58, 0x45, 0x43, 0x5f, 0x46, + 0x49, 0x4c, 0x45, 0x5f, 0x53, 0x45, 0x54, 0x55, 0x49, 0x44, 0x10, 0x02, 0x12, 0x26, 0x0a, 0x22, + 0x50, 0x52, 0x49, 0x56, 0x49, 0x4c, 0x45, 0x47, 0x45, 0x53, 0x5f, 0x52, 0x41, 0x49, 0x53, 0x45, + 0x44, 0x5f, 0x45, 0x58, 0x45, 0x43, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x5f, 0x53, 0x45, 0x54, 0x47, + 0x49, 0x44, 0x10, 0x03, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -459,10 +553,11 @@ func file_tetragon_capabilities_proto_rawDescGZIP() []byte { return file_tetragon_capabilities_proto_rawDescData } -var file_tetragon_capabilities_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_tetragon_capabilities_proto_enumTypes = make([]protoimpl.EnumInfo, 3) var file_tetragon_capabilities_proto_goTypes = []interface{}{ - (CapabilitiesType)(0), // 0: tetragon.CapabilitiesType - (SecureBitsType)(0), // 1: tetragon.SecureBitsType + (CapabilitiesType)(0), // 0: tetragon.CapabilitiesType + (SecureBitsType)(0), // 1: tetragon.SecureBitsType + (ProcessPrivilegesChanged)(0), // 2: tetragon.ProcessPrivilegesChanged } var file_tetragon_capabilities_proto_depIdxs = []int32{ 0, // [0:0] is the sub-list for method output_type @@ -482,7 +577,7 @@ func file_tetragon_capabilities_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_tetragon_capabilities_proto_rawDesc, - NumEnums: 2, + NumEnums: 3, NumMessages: 0, NumExtensions: 0, NumServices: 0, diff --git a/vendor/github.com/cilium/tetragon/api/v1/tetragon/capabilities.proto b/vendor/github.com/cilium/tetragon/api/v1/tetragon/capabilities.proto index 9b097083a2f..c453a534f44 100644 --- a/vendor/github.com/cilium/tetragon/api/v1/tetragon/capabilities.proto +++ b/vendor/github.com/cilium/tetragon/api/v1/tetragon/capabilities.proto @@ -306,3 +306,44 @@ enum SecureBitsType { /* Make bit-6 SecBitNoCapAmbientRaise immutable */ SecBitNoCapAmbientRaiseLocked = 128; } + +// Reasons of why the process privileges changed. +enum ProcessPrivilegesChanged { + PRIVILEGES_CHANGED_UNSET = 0; + + // A privilege elevation happened due to the execution of a binary with file capability sets. + // The kernel supports associating capability sets with an executable file using `setcap` command. + // The file capability sets are stored in an extended attribute (see https://man7.org/linux/man-pages/man7/xattr.7.html) + // named `security.capability`. The file capability sets, in conjunction with the capability sets + // of the process, determine the process capabilities and privileges after the `execve` system call. + // For further reference, please check sections `File capability extended attribute versioning` and + // `Namespaced file capabilities` of the capabilities man pages: https://man7.org/linux/man-pages/man7/capabilities.7.html. + // The new granted capabilities can be listed inside the `process` object. + PRIVILEGES_RAISED_EXEC_FILE_CAP = 1; + + // A privilege elevation happened due to the execution of a binary with set-user-ID to root. + // When a process with nonzero UIDs executes a binary with a set-user-ID to root also + // known as suid-root executable, then the kernel switches the effective user ID to 0 (root) which + // is a privilege elevation operation since it grants access to resources owned by the root user. + // The effective user ID is listed inside the `process_credentials` part of the `process` object. + // For further reading, section `Capabilities and execution of programs by root` of https://man7.org/linux/man-pages/man7/capabilities.7.html. + // Afterward the kernel recalculates the capability sets of the process and grants all capabilities + // in the permitted and effective capability sets, except those masked out by the capability bounding set. + // If the binary also have file capability sets then these bits are honored and the process gains just + // the capabilities granted by the file capability sets (i.e., not all capabilities, as it would occur + // when executing a set-user-ID to root binary that does not have any associated file capabilities). This + // is described in section `Set-user-ID-root programs that have file capabilities` of https://man7.org/linux/man-pages/man7/capabilities.7.html. + // The new granted capabilities can be listed inside the `process` object. + // There is one exception for the special treatments of set-user-ID to root execution receiving all + // capabilities, if the `SecBitNoRoot` bit of the Secure bits is set, then the kernel does not grant + // any capability. Please check section: `The securebits flags: establishing a capabilities-only environment` + // of the capabilities man pages: https://man7.org/linux/man-pages/man7/capabilities.7.html + PRIVILEGES_RAISED_EXEC_FILE_SETUID = 2; + + // A privilege elevation happened due to the execution of a binary with set-group-ID to root. + // When a process with nonzero GIDs executes a binary with a set-group-ID to root, the kernel switches + // the effective group ID to 0 (root) which is a privilege elevation operation since it grants access to + // resources owned by the root group. + // The effective group ID is listed inside the `process_credentials` part of the `process` object. + PRIVILEGES_RAISED_EXEC_FILE_SETGID = 3; +} diff --git a/vendor/github.com/cilium/tetragon/api/v1/tetragon/codegen/eventchecker/eventchecker.pb.go b/vendor/github.com/cilium/tetragon/api/v1/tetragon/codegen/eventchecker/eventchecker.pb.go index f7767721367..e2eb02f785f 100644 --- a/vendor/github.com/cilium/tetragon/api/v1/tetragon/codegen/eventchecker/eventchecker.pb.go +++ b/vendor/github.com/cilium/tetragon/api/v1/tetragon/codegen/eventchecker/eventchecker.pb.go @@ -706,6 +706,7 @@ type ProcessKprobeChecker struct { StackTrace *StackTraceEntryListMatcher `json:"stackTrace,omitempty"` PolicyName *stringmatcher.StringMatcher `json:"policyName,omitempty"` ReturnAction *KprobeActionChecker `json:"returnAction,omitempty"` + Message *stringmatcher.StringMatcher `json:"message,omitempty"` } // CheckEvent checks a single event and implements the EventChecker interface @@ -792,6 +793,11 @@ func (checker *ProcessKprobeChecker) Check(event *tetragon.ProcessKprobe) error return fmt.Errorf("ReturnAction check failed: %w", err) } } + if checker.Message != nil { + if err := checker.Message.Match(event.Message); err != nil { + return fmt.Errorf("Message check failed: %w", err) + } + } return nil } if err := fieldChecks(); err != nil { @@ -856,6 +862,12 @@ func (checker *ProcessKprobeChecker) WithReturnAction(check tetragon.KprobeActio return checker } +// WithMessage adds a Message check to the ProcessKprobeChecker +func (checker *ProcessKprobeChecker) WithMessage(check *stringmatcher.StringMatcher) *ProcessKprobeChecker { + checker.Message = check + return checker +} + //FromProcessKprobe populates the ProcessKprobeChecker using data from a ProcessKprobe event func (checker *ProcessKprobeChecker) FromProcessKprobe(event *tetragon.ProcessKprobe) *ProcessKprobeChecker { if event == nil { @@ -900,6 +912,7 @@ func (checker *ProcessKprobeChecker) FromProcessKprobe(event *tetragon.ProcessKp } checker.PolicyName = stringmatcher.Full(event.PolicyName) checker.ReturnAction = NewKprobeActionChecker(event.ReturnAction) + checker.Message = stringmatcher.Full(event.Message) return checker } @@ -1113,6 +1126,7 @@ type ProcessTracepointChecker struct { Args *KprobeArgumentListMatcher `json:"args,omitempty"` PolicyName *stringmatcher.StringMatcher `json:"policyName,omitempty"` Action *KprobeActionChecker `json:"action,omitempty"` + Message *stringmatcher.StringMatcher `json:"message,omitempty"` } // CheckEvent checks a single event and implements the EventChecker interface @@ -1189,6 +1203,11 @@ func (checker *ProcessTracepointChecker) Check(event *tetragon.ProcessTracepoint return fmt.Errorf("Action check failed: %w", err) } } + if checker.Message != nil { + if err := checker.Message.Match(event.Message); err != nil { + return fmt.Errorf("Message check failed: %w", err) + } + } return nil } if err := fieldChecks(); err != nil { @@ -1240,6 +1259,12 @@ func (checker *ProcessTracepointChecker) WithAction(check tetragon.KprobeAction) return checker } +// WithMessage adds a Message check to the ProcessTracepointChecker +func (checker *ProcessTracepointChecker) WithMessage(check *stringmatcher.StringMatcher) *ProcessTracepointChecker { + checker.Message = check + return checker +} + //FromProcessTracepoint populates the ProcessTracepointChecker using data from a ProcessTracepoint event func (checker *ProcessTracepointChecker) FromProcessTracepoint(event *tetragon.ProcessTracepoint) *ProcessTracepointChecker { if event == nil { @@ -1268,6 +1293,7 @@ func (checker *ProcessTracepointChecker) FromProcessTracepoint(event *tetragon.P } checker.PolicyName = stringmatcher.Full(event.PolicyName) checker.Action = NewKprobeActionChecker(event.Action) + checker.Message = stringmatcher.Full(event.Message) return checker } @@ -1279,6 +1305,7 @@ type ProcessUprobeChecker struct { Path *stringmatcher.StringMatcher `json:"path,omitempty"` Symbol *stringmatcher.StringMatcher `json:"symbol,omitempty"` PolicyName *stringmatcher.StringMatcher `json:"policyName,omitempty"` + Message *stringmatcher.StringMatcher `json:"message,omitempty"` } // CheckEvent checks a single event and implements the EventChecker interface @@ -1345,6 +1372,11 @@ func (checker *ProcessUprobeChecker) Check(event *tetragon.ProcessUprobe) error return fmt.Errorf("PolicyName check failed: %w", err) } } + if checker.Message != nil { + if err := checker.Message.Match(event.Message); err != nil { + return fmt.Errorf("Message check failed: %w", err) + } + } return nil } if err := fieldChecks(); err != nil { @@ -1383,6 +1415,12 @@ func (checker *ProcessUprobeChecker) WithPolicyName(check *stringmatcher.StringM return checker } +// WithMessage adds a Message check to the ProcessUprobeChecker +func (checker *ProcessUprobeChecker) WithMessage(check *stringmatcher.StringMatcher) *ProcessUprobeChecker { + checker.Message = check + return checker +} + //FromProcessUprobe populates the ProcessUprobeChecker using data from a ProcessUprobe event func (checker *ProcessUprobeChecker) FromProcessUprobe(event *tetragon.ProcessUprobe) *ProcessUprobeChecker { if event == nil { @@ -1397,6 +1435,7 @@ func (checker *ProcessUprobeChecker) FromProcessUprobe(event *tetragon.ProcessUp checker.Path = stringmatcher.Full(event.Path) checker.Symbol = stringmatcher.Full(event.Symbol) checker.PolicyName = stringmatcher.Full(event.PolicyName) + checker.Message = stringmatcher.Full(event.Message) return checker } @@ -2943,8 +2982,9 @@ nextCheck: // BinaryPropertiesChecker implements a checker struct to check a BinaryProperties field type BinaryPropertiesChecker struct { - Setuid *uint32 `json:"setuid,omitempty"` - Setgid *uint32 `json:"setgid,omitempty"` + Setuid *uint32 `json:"setuid,omitempty"` + Setgid *uint32 `json:"setgid,omitempty"` + PrivilegesChanged *ProcessPrivilegesChangedListMatcher `json:"privilegesChanged,omitempty"` } // NewBinaryPropertiesChecker creates a new BinaryPropertiesChecker @@ -2980,6 +3020,11 @@ func (checker *BinaryPropertiesChecker) Check(event *tetragon.BinaryProperties) return fmt.Errorf("Setgid has value %v which does not match expected value %v", event.Setgid.Value, *checker.Setgid) } } + if checker.PrivilegesChanged != nil { + if err := checker.PrivilegesChanged.Check(event.PrivilegesChanged); err != nil { + return fmt.Errorf("PrivilegesChanged check failed: %w", err) + } + } return nil } if err := fieldChecks(); err != nil { @@ -3000,6 +3045,12 @@ func (checker *BinaryPropertiesChecker) WithSetgid(check uint32) *BinaryProperti return checker } +// WithPrivilegesChanged adds a PrivilegesChanged check to the BinaryPropertiesChecker +func (checker *BinaryPropertiesChecker) WithPrivilegesChanged(check *ProcessPrivilegesChangedListMatcher) *BinaryPropertiesChecker { + checker.PrivilegesChanged = check + return checker +} + //FromBinaryProperties populates the BinaryPropertiesChecker using data from a BinaryProperties field func (checker *BinaryPropertiesChecker) FromBinaryProperties(event *tetragon.BinaryProperties) *BinaryPropertiesChecker { if event == nil { @@ -3013,9 +3064,120 @@ func (checker *BinaryPropertiesChecker) FromBinaryProperties(event *tetragon.Bin val := event.Setgid.Value checker.Setgid = &val } + { + var checks []*ProcessPrivilegesChangedChecker + for _, check := range event.PrivilegesChanged { + var convertedCheck *ProcessPrivilegesChangedChecker + convertedCheck = NewProcessPrivilegesChangedChecker(check) + checks = append(checks, convertedCheck) + } + lm := NewProcessPrivilegesChangedListMatcher().WithOperator(listmatcher.Ordered). + WithValues(checks...) + checker.PrivilegesChanged = lm + } return checker } +// ProcessPrivilegesChangedListMatcher checks a list of tetragon.ProcessPrivilegesChanged fields +type ProcessPrivilegesChangedListMatcher struct { + Operator listmatcher.Operator `json:"operator"` + Values []*ProcessPrivilegesChangedChecker `json:"values"` +} + +// NewProcessPrivilegesChangedListMatcher creates a new ProcessPrivilegesChangedListMatcher. The checker defaults to a subset checker unless otherwise specified using WithOperator() +func NewProcessPrivilegesChangedListMatcher() *ProcessPrivilegesChangedListMatcher { + return &ProcessPrivilegesChangedListMatcher{ + Operator: listmatcher.Subset, + } +} + +// WithOperator sets the match kind for the ProcessPrivilegesChangedListMatcher +func (checker *ProcessPrivilegesChangedListMatcher) WithOperator(operator listmatcher.Operator) *ProcessPrivilegesChangedListMatcher { + checker.Operator = operator + return checker +} + +// WithValues sets the checkers that the ProcessPrivilegesChangedListMatcher should use +func (checker *ProcessPrivilegesChangedListMatcher) WithValues(values ...*ProcessPrivilegesChangedChecker) *ProcessPrivilegesChangedListMatcher { + checker.Values = values + return checker +} + +// Check checks a list of tetragon.ProcessPrivilegesChanged fields +func (checker *ProcessPrivilegesChangedListMatcher) Check(values []tetragon.ProcessPrivilegesChanged) error { + switch checker.Operator { + case listmatcher.Ordered: + return checker.orderedCheck(values) + case listmatcher.Unordered: + return checker.unorderedCheck(values) + case listmatcher.Subset: + return checker.subsetCheck(values) + default: + return fmt.Errorf("Unhandled ListMatcher operator %s", checker.Operator) + } +} + +// orderedCheck checks a list of ordered tetragon.ProcessPrivilegesChanged fields +func (checker *ProcessPrivilegesChangedListMatcher) orderedCheck(values []tetragon.ProcessPrivilegesChanged) error { + innerCheck := func(check *ProcessPrivilegesChangedChecker, value tetragon.ProcessPrivilegesChanged) error { + if err := check.Check(&value); err != nil { + return fmt.Errorf("PrivilegesChanged check failed: %w", err) + } + return nil + } + + if len(checker.Values) != len(values) { + return fmt.Errorf("ProcessPrivilegesChangedListMatcher: Wanted %d elements, got %d", len(checker.Values), len(values)) + } + + for i, check := range checker.Values { + value := values[i] + if err := innerCheck(check, value); err != nil { + return fmt.Errorf("ProcessPrivilegesChangedListMatcher: Check failed on element %d: %w", i, err) + } + } + + return nil +} + +// unorderedCheck checks a list of unordered tetragon.ProcessPrivilegesChanged fields +func (checker *ProcessPrivilegesChangedListMatcher) unorderedCheck(values []tetragon.ProcessPrivilegesChanged) error { + if len(checker.Values) != len(values) { + return fmt.Errorf("ProcessPrivilegesChangedListMatcher: Wanted %d elements, got %d", len(checker.Values), len(values)) + } + + return checker.subsetCheck(values) +} + +// subsetCheck checks a subset of tetragon.ProcessPrivilegesChanged fields +func (checker *ProcessPrivilegesChangedListMatcher) subsetCheck(values []tetragon.ProcessPrivilegesChanged) error { + innerCheck := func(check *ProcessPrivilegesChangedChecker, value tetragon.ProcessPrivilegesChanged) error { + if err := check.Check(&value); err != nil { + return fmt.Errorf("PrivilegesChanged check failed: %w", err) + } + return nil + } + + numDesired := len(checker.Values) + numMatched := 0 + +nextCheck: + for _, check := range checker.Values { + for _, value := range values { + if err := innerCheck(check, value); err == nil { + numMatched += 1 + continue nextCheck + } + } + } + + if numMatched < numDesired { + return fmt.Errorf("ProcessPrivilegesChangedListMatcher: Check failed, only matched %d elements but wanted %d", numMatched, numDesired) + } + + return nil +} + // ProcessChecker implements a checker struct to check a Process field type ProcessChecker struct { ExecId *stringmatcher.StringMatcher `json:"execId,omitempty"` @@ -5428,6 +5590,58 @@ func (enum *SecureBitsTypeChecker) Check(val *tetragon.SecureBitsType) error { return nil } +// ProcessPrivilegesChangedChecker checks a tetragon.ProcessPrivilegesChanged +type ProcessPrivilegesChangedChecker tetragon.ProcessPrivilegesChanged + +// MarshalJSON implements json.Marshaler interface +func (enum ProcessPrivilegesChangedChecker) MarshalJSON() ([]byte, error) { + if name, ok := tetragon.ProcessPrivilegesChanged_name[int32(enum)]; ok { + name = strings.TrimPrefix(name, "PRIVILEGES_") + return json.Marshal(name) + } + + return nil, fmt.Errorf("Unknown ProcessPrivilegesChanged %d", enum) +} + +// UnmarshalJSON implements json.Unmarshaler interface +func (enum *ProcessPrivilegesChangedChecker) UnmarshalJSON(b []byte) error { + var str string + if err := yaml.UnmarshalStrict(b, &str); err != nil { + return err + } + + // Convert to uppercase if not already + str = strings.ToUpper(str) + + // Look up the value from the enum values map + if n, ok := tetragon.ProcessPrivilegesChanged_value[str]; ok { + *enum = ProcessPrivilegesChangedChecker(n) + } else if n, ok := tetragon.ProcessPrivilegesChanged_value["PRIVILEGES_"+str]; ok { + *enum = ProcessPrivilegesChangedChecker(n) + } else { + return fmt.Errorf("Unknown ProcessPrivilegesChanged %s", str) + } + + return nil +} + +// NewProcessPrivilegesChangedChecker creates a new ProcessPrivilegesChangedChecker +func NewProcessPrivilegesChangedChecker(val tetragon.ProcessPrivilegesChanged) *ProcessPrivilegesChangedChecker { + enum := ProcessPrivilegesChangedChecker(val) + return &enum +} + +// Check checks a ProcessPrivilegesChanged against the checker +func (enum *ProcessPrivilegesChangedChecker) Check(val *tetragon.ProcessPrivilegesChanged) error { + if val == nil { + return fmt.Errorf("ProcessPrivilegesChangedChecker: ProcessPrivilegesChanged is nil and does not match expected value %s", tetragon.ProcessPrivilegesChanged(*enum)) + } + if *enum != ProcessPrivilegesChangedChecker(*val) { + return fmt.Errorf("ProcessPrivilegesChangedChecker: ProcessPrivilegesChanged has value %s which does not match expected value %s", (*val), tetragon.ProcessPrivilegesChanged(*enum)) + } + return nil +} + // KprobeActionChecker checks a tetragon.KprobeAction type KprobeActionChecker tetragon.KprobeAction diff --git a/vendor/github.com/cilium/tetragon/api/v1/tetragon/tetragon.pb.go b/vendor/github.com/cilium/tetragon/api/v1/tetragon/tetragon.pb.go index 4aa6cac53ac..99bfda02d31 100644 --- a/vendor/github.com/cilium/tetragon/api/v1/tetragon/tetragon.pb.go +++ b/vendor/github.com/cilium/tetragon/api/v1/tetragon/tetragon.pb.go @@ -1027,6 +1027,10 @@ type BinaryProperties struct { Setuid *wrapperspb.UInt32Value `protobuf:"bytes,1,opt,name=setuid,proto3" json:"setuid,omitempty"` // If set then this is the set group ID used for execution Setgid *wrapperspb.UInt32Value `protobuf:"bytes,2,opt,name=setgid,proto3" json:"setgid,omitempty"` + // The reasons why this binary execution changed privileges. Usually this happens when the process executes + // a binary with the set-user-ID to root or file capability sets. + // The final granted privileges can be listed inside the `process_credentials` or capabilities fields part of of the `process` object. + PrivilegesChanged []ProcessPrivilegesChanged `protobuf:"varint,3,rep,packed,name=privileges_changed,json=privilegesChanged,proto3,enum=tetragon.ProcessPrivilegesChanged" json:"privileges_changed,omitempty"` } func (x *BinaryProperties) Reset() { @@ -1075,6 +1079,13 @@ func (x *BinaryProperties) GetSetgid() *wrapperspb.UInt32Value { return nil } +func (x *BinaryProperties) GetPrivilegesChanged() []ProcessPrivilegesChanged { + if x != nil { + return x.PrivilegesChanged + } + return nil +} + type Process struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2705,6 +2716,8 @@ type ProcessKprobe struct { PolicyName string `protobuf:"bytes,8,opt,name=policy_name,json=policyName,proto3" json:"policy_name,omitempty"` // Action performed when the return kprobe executed. ReturnAction KprobeAction `protobuf:"varint,9,opt,name=return_action,json=returnAction,proto3,enum=tetragon.KprobeAction" json:"return_action,omitempty"` + // Short message of the Tracing Policy to inform users what is going on. + Message string `protobuf:"bytes,10,opt,name=message,proto3" json:"message,omitempty"` } func (x *ProcessKprobe) Reset() { @@ -2802,6 +2815,13 @@ func (x *ProcessKprobe) GetReturnAction() KprobeAction { return KprobeAction_KPROBE_ACTION_UNKNOWN } +func (x *ProcessKprobe) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + type ProcessTracepoint struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2822,6 +2842,8 @@ type ProcessTracepoint struct { PolicyName string `protobuf:"bytes,7,opt,name=policy_name,json=policyName,proto3" json:"policy_name,omitempty"` // Action performed when the tracepoint matched. Action KprobeAction `protobuf:"varint,8,opt,name=action,proto3,enum=tetragon.KprobeAction" json:"action,omitempty"` + // Short message of the Tracing Policy to inform users what is going on. + Message string `protobuf:"bytes,9,opt,name=message,proto3" json:"message,omitempty"` } func (x *ProcessTracepoint) Reset() { @@ -2905,6 +2927,13 @@ func (x *ProcessTracepoint) GetAction() KprobeAction { return KprobeAction_KPROBE_ACTION_UNKNOWN } +func (x *ProcessTracepoint) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + type ProcessUprobe struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2916,6 +2945,8 @@ type ProcessUprobe struct { Symbol string `protobuf:"bytes,4,opt,name=symbol,proto3" json:"symbol,omitempty"` // Name of the policy that created that uprobe. PolicyName string `protobuf:"bytes,5,opt,name=policy_name,json=policyName,proto3" json:"policy_name,omitempty"` + // Short message of the Tracing Policy to inform users what is going on. + Message string `protobuf:"bytes,6,opt,name=message,proto3" json:"message,omitempty"` } func (x *ProcessUprobe) Reset() { @@ -2985,6 +3016,13 @@ func (x *ProcessUprobe) GetPolicyName() string { return "" } +func (x *ProcessUprobe) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + type KernelModule struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3729,442 +3767,452 @@ var file_tetragon_tetragon_proto_rawDesc = []byte{ 0x74, 0x69, 0x65, 0x73, 0x52, 0x04, 0x63, 0x61, 0x70, 0x73, 0x12, 0x30, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x73, 0x22, 0x7e, 0x0a, 0x10, - 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, - 0x12, 0x34, 0x0a, 0x06, 0x73, 0x65, 0x74, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, - 0x73, 0x65, 0x74, 0x75, 0x69, 0x64, 0x12, 0x34, 0x0a, 0x06, 0x73, 0x65, 0x74, 0x67, 0x69, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x73, 0x65, 0x74, 0x67, 0x69, 0x64, 0x22, 0xdc, 0x05, 0x0a, - 0x07, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x65, 0x78, 0x65, 0x63, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x65, 0x78, 0x65, 0x63, 0x49, - 0x64, 0x12, 0x2e, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x03, 0x70, 0x69, - 0x64, 0x12, 0x2e, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x03, 0x75, 0x69, - 0x64, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x77, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x63, 0x77, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x61, - 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, - 0x67, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x12, - 0x39, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, - 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x30, 0x0a, 0x04, 0x61, 0x75, - 0x69, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, - 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x04, 0x61, 0x75, 0x69, 0x64, 0x12, 0x1f, 0x0a, 0x03, - 0x70, 0x6f, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x74, 0x65, 0x74, 0x72, - 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x6f, 0x64, 0x52, 0x03, 0x70, 0x6f, 0x64, 0x12, 0x16, 0x0a, - 0x06, 0x64, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, - 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, - 0x65, 0x78, 0x65, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, - 0x61, 0x72, 0x65, 0x6e, 0x74, 0x45, 0x78, 0x65, 0x63, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x72, - 0x65, 0x66, 0x63, 0x6e, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x72, 0x65, 0x66, - 0x63, 0x6e, 0x74, 0x12, 0x28, 0x0a, 0x03, 0x63, 0x61, 0x70, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x70, 0x61, - 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x03, 0x63, 0x61, 0x70, 0x12, 0x24, 0x0a, - 0x02, 0x6e, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x65, 0x74, 0x72, - 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, - 0x02, 0x6e, 0x73, 0x12, 0x2e, 0x0a, 0x03, 0x74, 0x69, 0x64, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x03, - 0x74, 0x69, 0x64, 0x12, 0x4d, 0x0a, 0x13, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, - 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1c, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, - 0x65, 0x73, 0x73, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x52, 0x12, - 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, - 0x6c, 0x73, 0x12, 0x47, 0x0a, 0x11, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x5f, 0x70, 0x72, 0x6f, - 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, - 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x50, - 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x52, 0x10, 0x62, 0x69, 0x6e, 0x61, 0x72, - 0x79, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0x96, 0x01, 0x0a, 0x0b, - 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, 0x65, 0x63, 0x12, 0x2b, 0x0a, 0x07, 0x70, - 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, - 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, - 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x29, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, - 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, - 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, - 0x65, 0x6e, 0x74, 0x12, 0x2f, 0x0a, 0x09, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, - 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, - 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x09, 0x61, 0x6e, 0x63, 0x65, 0x73, - 0x74, 0x6f, 0x72, 0x73, 0x22, 0xc5, 0x01, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, - 0x45, 0x78, 0x69, 0x74, 0x12, 0x2b, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, - 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, - 0x73, 0x12, 0x29, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, - 0x63, 0x65, 0x73, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, - 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x69, - 0x67, 0x6e, 0x61, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2e, 0x0a, 0x04, - 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x8a, 0x02, 0x0a, - 0x0a, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x53, 0x6f, 0x63, 0x6b, 0x12, 0x16, 0x0a, 0x06, 0x66, - 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x61, 0x6d, - 0x69, 0x6c, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x63, 0x6f, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x63, 0x6f, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x61, 0x72, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x04, 0x6d, 0x61, 0x72, 0x6b, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, - 0x69, 0x74, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, - 0x69, 0x74, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x61, 0x64, 0x64, 0x72, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x73, 0x61, 0x64, 0x64, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x61, 0x64, - 0x64, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x64, 0x61, 0x64, 0x64, 0x72, 0x12, - 0x14, 0x0a, 0x05, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, - 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x09, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x64, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x63, - 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x63, 0x6f, 0x6f, - 0x6b, 0x69, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x0b, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0xc9, 0x02, 0x0a, 0x09, 0x4b, 0x70, - 0x72, 0x6f, 0x62, 0x65, 0x53, 0x6b, 0x62, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x10, 0x0a, 0x03, 0x6c, - 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6c, 0x65, 0x6e, 0x12, 0x1a, 0x0a, - 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x61, 0x72, - 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x6d, 0x61, 0x72, 0x6b, 0x12, 0x14, 0x0a, - 0x05, 0x73, 0x61, 0x64, 0x64, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x61, - 0x64, 0x64, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x61, 0x64, 0x64, 0x72, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x64, 0x61, 0x64, 0x64, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x70, 0x6f, - 0x72, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, - 0x14, 0x0a, 0x05, 0x64, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, - 0x64, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x18, 0x09, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x20, 0x0a, 0x0c, 0x73, - 0x65, 0x63, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x6c, 0x65, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x0a, 0x73, 0x65, 0x63, 0x50, 0x61, 0x74, 0x68, 0x4c, 0x65, 0x6e, 0x12, 0x22, 0x0a, - 0x0d, 0x73, 0x65, 0x63, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x6f, 0x6c, 0x65, 0x6e, 0x18, 0x0b, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x73, 0x65, 0x63, 0x50, 0x61, 0x74, 0x68, 0x4f, 0x6c, 0x65, - 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x0c, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x16, 0x0a, - 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, - 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x22, 0x4c, 0x0a, 0x0a, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x50, - 0x61, 0x74, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, - 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x14, 0x0a, - 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x66, 0x6c, - 0x61, 0x67, 0x73, 0x22, 0x4c, 0x0a, 0x0a, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x46, 0x69, 0x6c, - 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x66, - 0x6c, 0x61, 0x67, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, - 0x73, 0x22, 0x50, 0x0a, 0x14, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x54, 0x72, 0x75, 0x6e, 0x63, - 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x79, 0x74, - 0x65, 0x73, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x62, 0x79, - 0x74, 0x65, 0x73, 0x41, 0x72, 0x67, 0x12, 0x1b, 0x0a, 0x09, 0x6f, 0x72, 0x69, 0x67, 0x5f, 0x73, - 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x6f, 0x72, 0x69, 0x67, 0x53, - 0x69, 0x7a, 0x65, 0x22, 0xbe, 0x01, 0x0a, 0x0a, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x43, 0x72, - 0x65, 0x64, 0x12, 0x38, 0x0a, 0x09, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, - 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x54, 0x79, 0x70, - 0x65, 0x52, 0x09, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x12, 0x38, 0x0a, 0x09, - 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0e, 0x32, - 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, - 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, 0x09, 0x65, 0x66, 0x66, - 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x3c, 0x0a, 0x0b, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x65, - 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, - 0x69, 0x65, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x22, 0x59, 0x0a, 0x10, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x43, 0x61, - 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x31, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, - 0xd5, 0x01, 0x0a, 0x13, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x61, - 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x31, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x32, 0x0a, 0x05, 0x6f, 0x77, - 0x6e, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, - 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x32, - 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x67, 0x72, 0x6f, - 0x75, 0x70, 0x12, 0x23, 0x0a, 0x02, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, - 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x52, 0x02, 0x6e, 0x73, 0x22, 0x61, 0x0a, 0x0d, 0x4b, 0x70, 0x72, 0x6f, 0x62, - 0x65, 0x42, 0x70, 0x66, 0x41, 0x74, 0x74, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x67, - 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x67, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x49, 0x6e, 0x73, 0x6e, 0x43, 0x6e, 0x74, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x49, 0x6e, 0x73, 0x6e, 0x43, 0x6e, 0x74, 0x12, 0x1a, - 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x50, 0x72, 0x6f, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x7f, 0x0a, 0x0f, 0x4b, 0x70, - 0x72, 0x6f, 0x62, 0x65, 0x50, 0x65, 0x72, 0x66, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1e, 0x0a, - 0x0a, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x46, 0x75, 0x6e, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0a, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x46, 0x75, 0x6e, 0x63, 0x12, 0x12, 0x0a, - 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x16, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x20, 0x0a, 0x0b, 0x50, 0x72, 0x6f, - 0x62, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, - 0x50, 0x72, 0x6f, 0x62, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x22, 0x9a, 0x01, 0x0a, 0x0c, - 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x42, 0x70, 0x66, 0x4d, 0x61, 0x70, 0x12, 0x18, 0x0a, 0x07, - 0x4d, 0x61, 0x70, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x4d, - 0x61, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x7a, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x7a, 0x65, - 0x12, 0x1c, 0x0a, 0x09, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x09, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1e, - 0x0a, 0x0a, 0x4d, 0x61, 0x78, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x0a, 0x4d, 0x61, 0x78, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x18, - 0x0a, 0x07, 0x4d, 0x61, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x4d, 0x61, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xcb, 0x08, 0x0a, 0x0e, 0x4b, 0x70, 0x72, - 0x6f, 0x62, 0x65, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0a, 0x73, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, - 0x00, 0x52, 0x09, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x41, 0x72, 0x67, 0x12, 0x19, 0x0a, 0x07, - 0x69, 0x6e, 0x74, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, - 0x06, 0x69, 0x6e, 0x74, 0x41, 0x72, 0x67, 0x12, 0x2e, 0x0a, 0x07, 0x73, 0x6b, 0x62, 0x5f, 0x61, - 0x72, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, - 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x53, 0x6b, 0x62, 0x48, 0x00, 0x52, - 0x06, 0x73, 0x6b, 0x62, 0x41, 0x72, 0x67, 0x12, 0x1b, 0x0a, 0x08, 0x73, 0x69, 0x7a, 0x65, 0x5f, - 0x61, 0x72, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, 0x07, 0x73, 0x69, 0x7a, - 0x65, 0x41, 0x72, 0x67, 0x12, 0x1d, 0x0a, 0x09, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x61, 0x72, - 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x08, 0x62, 0x79, 0x74, 0x65, 0x73, - 0x41, 0x72, 0x67, 0x12, 0x31, 0x0a, 0x08, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x61, 0x72, 0x67, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, - 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x50, 0x61, 0x74, 0x68, 0x48, 0x00, 0x52, 0x07, 0x70, - 0x61, 0x74, 0x68, 0x41, 0x72, 0x67, 0x12, 0x31, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x61, - 0x72, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, - 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x48, 0x00, - 0x52, 0x07, 0x66, 0x69, 0x6c, 0x65, 0x41, 0x72, 0x67, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x75, - 0x6e, 0x63, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x61, 0x72, 0x67, - 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, - 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x54, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, - 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x48, 0x00, 0x52, 0x11, 0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, - 0x74, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x41, 0x72, 0x67, 0x12, 0x31, 0x0a, 0x08, 0x73, - 0x6f, 0x63, 0x6b, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, - 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x53, - 0x6f, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x07, 0x73, 0x6f, 0x63, 0x6b, 0x41, 0x72, 0x67, 0x12, 0x31, - 0x0a, 0x08, 0x63, 0x72, 0x65, 0x64, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x14, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, - 0x62, 0x65, 0x43, 0x72, 0x65, 0x64, 0x48, 0x00, 0x52, 0x07, 0x63, 0x72, 0x65, 0x64, 0x41, 0x72, - 0x67, 0x12, 0x1b, 0x0a, 0x08, 0x6c, 0x6f, 0x6e, 0x67, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x0b, 0x20, - 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x07, 0x6c, 0x6f, 0x6e, 0x67, 0x41, 0x72, 0x67, 0x12, 0x3b, - 0x0a, 0x0c, 0x62, 0x70, 0x66, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x0c, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, - 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x42, 0x70, 0x66, 0x41, 0x74, 0x74, 0x72, 0x48, 0x00, 0x52, - 0x0a, 0x62, 0x70, 0x66, 0x41, 0x74, 0x74, 0x72, 0x41, 0x72, 0x67, 0x12, 0x41, 0x0a, 0x0e, 0x70, - 0x65, 0x72, 0x66, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x0d, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, - 0x70, 0x72, 0x6f, 0x62, 0x65, 0x50, 0x65, 0x72, 0x66, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, - 0x52, 0x0c, 0x70, 0x65, 0x72, 0x66, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x41, 0x72, 0x67, 0x12, 0x38, - 0x0a, 0x0b, 0x62, 0x70, 0x66, 0x5f, 0x6d, 0x61, 0x70, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x0e, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, - 0x70, 0x72, 0x6f, 0x62, 0x65, 0x42, 0x70, 0x66, 0x4d, 0x61, 0x70, 0x48, 0x00, 0x52, 0x09, 0x62, - 0x70, 0x66, 0x4d, 0x61, 0x70, 0x41, 0x72, 0x67, 0x12, 0x1b, 0x0a, 0x08, 0x75, 0x69, 0x6e, 0x74, - 0x5f, 0x61, 0x72, 0x67, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x07, 0x75, 0x69, - 0x6e, 0x74, 0x41, 0x72, 0x67, 0x12, 0x51, 0x0a, 0x12, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x10, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, - 0x6f, 0x62, 0x65, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x42, 0x02, 0x18, 0x01, 0x48, 0x00, 0x52, 0x10, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x72, 0x67, 0x12, 0x43, 0x0a, 0x0e, 0x63, 0x61, 0x70, 0x61, - 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, - 0x62, 0x65, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x48, 0x00, 0x52, 0x0d, - 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x41, 0x72, 0x67, 0x12, 0x56, 0x0a, - 0x17, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, - 0x69, 0x61, 0x6c, 0x73, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, - 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, - 0x73, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x48, 0x00, 0x52, 0x15, - 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, - 0x6c, 0x73, 0x41, 0x72, 0x67, 0x12, 0x39, 0x0a, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x73, - 0x5f, 0x61, 0x72, 0x67, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, - 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x48, 0x00, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x73, 0x41, 0x72, 0x67, - 0x12, 0x37, 0x0a, 0x0a, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x15, + 0x70, 0x61, 0x63, 0x65, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x73, 0x22, 0xd1, 0x01, 0x0a, + 0x10, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, + 0x73, 0x12, 0x34, 0x0a, 0x06, 0x73, 0x65, 0x74, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, + 0x06, 0x73, 0x65, 0x74, 0x75, 0x69, 0x64, 0x12, 0x34, 0x0a, 0x06, 0x73, 0x65, 0x74, 0x67, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x73, 0x65, 0x74, 0x67, 0x69, 0x64, 0x12, 0x51, 0x0a, + 0x12, 0x70, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x73, 0x5f, 0x63, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x64, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x74, 0x65, 0x74, 0x72, + 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x50, 0x72, 0x69, 0x76, + 0x69, 0x6c, 0x65, 0x67, 0x65, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x52, 0x11, 0x70, + 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, + 0x22, 0xdc, 0x05, 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x17, 0x0a, 0x07, + 0x65, 0x78, 0x65, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x65, + 0x78, 0x65, 0x63, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, 0x2e, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x77, 0x64, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x63, 0x77, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x69, 0x6e, 0x61, 0x72, + 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x12, + 0x1c, 0x0a, 0x09, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x14, 0x0a, + 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x66, 0x6c, + 0x61, 0x67, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, + 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x30, + 0x0a, 0x04, 0x61, 0x75, 0x69, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, + 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x04, 0x61, 0x75, 0x69, 0x64, + 0x12, 0x1f, 0x0a, 0x03, 0x70, 0x6f, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, + 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x6f, 0x64, 0x52, 0x03, 0x70, 0x6f, + 0x64, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x64, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x5f, 0x65, 0x78, 0x65, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0c, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x45, 0x78, 0x65, 0x63, 0x49, 0x64, 0x12, + 0x16, 0x0a, 0x06, 0x72, 0x65, 0x66, 0x63, 0x6e, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x06, 0x72, 0x65, 0x66, 0x63, 0x6e, 0x74, 0x12, 0x28, 0x0a, 0x03, 0x63, 0x61, 0x70, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, - 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x48, 0x00, 0x52, 0x09, - 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x41, 0x72, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, - 0x65, 0x6c, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x42, - 0x05, 0x0a, 0x03, 0x61, 0x72, 0x67, 0x22, 0xb6, 0x03, 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x63, 0x65, - 0x73, 0x73, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, + 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x03, 0x63, 0x61, + 0x70, 0x12, 0x24, 0x0a, 0x02, 0x6e, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, + 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x73, 0x52, 0x02, 0x6e, 0x73, 0x12, 0x2e, 0x0a, 0x03, 0x74, 0x69, 0x64, 0x18, 0x10, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x03, 0x74, 0x69, 0x64, 0x12, 0x4d, 0x0a, 0x13, 0x70, 0x72, 0x6f, 0x63, 0x65, + 0x73, 0x73, 0x5f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x18, 0x11, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, + 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, + 0x6c, 0x73, 0x52, 0x12, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x72, 0x65, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x47, 0x0a, 0x11, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, + 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x12, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x42, 0x69, 0x6e, + 0x61, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x52, 0x10, 0x62, + 0x69, 0x6e, 0x61, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, + 0x96, 0x01, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, 0x65, 0x63, 0x12, + 0x2b, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x29, 0x0a, 0x06, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, + 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, + 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x2f, 0x0a, 0x09, 0x61, 0x6e, 0x63, 0x65, 0x73, + 0x74, 0x6f, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, + 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x09, 0x61, + 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x22, 0xc5, 0x01, 0x0a, 0x0b, 0x50, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, 0x69, 0x74, 0x12, 0x2b, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x29, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, - 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2c, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x73, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, - 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x04, 0x61, - 0x72, 0x67, 0x73, 0x12, 0x30, 0x0a, 0x06, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, - 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x72, - 0x65, 0x74, 0x75, 0x72, 0x6e, 0x12, 0x2e, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, - 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3a, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5f, 0x74, - 0x72, 0x61, 0x63, 0x65, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x65, 0x74, - 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x54, 0x72, 0x61, 0x63, 0x65, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x54, 0x72, 0x61, 0x63, - 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x0d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, - 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x0c, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, - 0x98, 0x02, 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x72, 0x61, 0x63, 0x65, - 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x2b, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, - 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, - 0x73, 0x73, 0x12, 0x29, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, - 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, - 0x06, 0x73, 0x75, 0x62, 0x73, 0x79, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, - 0x75, 0x62, 0x73, 0x79, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x04, 0x61, - 0x72, 0x67, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x74, 0x72, - 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x72, 0x67, 0x75, 0x6d, - 0x65, 0x6e, 0x74, 0x52, 0x04, 0x61, 0x72, 0x67, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, - 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x06, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, - 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xb4, 0x01, 0x0a, 0x0d, 0x50, - 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x55, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x12, 0x2b, 0x0a, 0x07, + 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, + 0x22, 0x8a, 0x02, 0x0a, 0x0a, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x53, 0x6f, 0x63, 0x6b, 0x12, + 0x16, 0x0a, 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x61, 0x72, 0x6b, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x6d, 0x61, 0x72, 0x6b, 0x12, 0x1a, 0x0a, 0x08, 0x70, + 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x70, + 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x61, 0x64, 0x64, 0x72, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x61, 0x64, 0x64, 0x72, 0x12, 0x14, 0x0a, + 0x05, 0x64, 0x61, 0x64, 0x64, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x64, 0x61, + 0x64, 0x64, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x05, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x70, 0x6f, + 0x72, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x64, 0x70, 0x6f, 0x72, 0x74, 0x12, + 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x06, 0x63, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0xc9, 0x02, + 0x0a, 0x09, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x53, 0x6b, 0x62, 0x12, 0x12, 0x0a, 0x04, 0x68, + 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, + 0x10, 0x0a, 0x03, 0x6c, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6c, 0x65, + 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x12, 0x0a, + 0x04, 0x6d, 0x61, 0x72, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x6d, 0x61, 0x72, + 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x61, 0x64, 0x64, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x73, 0x61, 0x64, 0x64, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x61, 0x64, 0x64, 0x72, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x64, 0x61, 0x64, 0x64, 0x72, 0x12, 0x14, 0x0a, + 0x05, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x73, 0x70, + 0x6f, 0x72, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x05, 0x64, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x20, 0x0a, 0x0c, 0x73, 0x65, 0x63, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x6c, 0x65, 0x6e, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x73, 0x65, 0x63, 0x50, 0x61, 0x74, 0x68, 0x4c, 0x65, + 0x6e, 0x12, 0x22, 0x0a, 0x0d, 0x73, 0x65, 0x63, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x6f, 0x6c, + 0x65, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x73, 0x65, 0x63, 0x50, 0x61, 0x74, + 0x68, 0x4f, 0x6c, 0x65, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6c, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x22, 0x4c, 0x0a, 0x0a, 0x4b, 0x70, 0x72, + 0x6f, 0x62, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f, 0x75, 0x6e, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, + 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, + 0x68, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x22, 0x4c, 0x0a, 0x0a, 0x4b, 0x70, 0x72, 0x6f, 0x62, + 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, + 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, + 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x66, 0x6c, 0x61, 0x67, 0x73, 0x22, 0x50, 0x0a, 0x14, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x54, + 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1b, 0x0a, + 0x09, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x08, 0x62, 0x79, 0x74, 0x65, 0x73, 0x41, 0x72, 0x67, 0x12, 0x1b, 0x0a, 0x09, 0x6f, 0x72, + 0x69, 0x67, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x6f, + 0x72, 0x69, 0x67, 0x53, 0x69, 0x7a, 0x65, 0x22, 0xbe, 0x01, 0x0a, 0x0a, 0x4b, 0x70, 0x72, 0x6f, + 0x62, 0x65, 0x43, 0x72, 0x65, 0x64, 0x12, 0x38, 0x0a, 0x09, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x74, + 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, + 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, + 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, 0x09, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, + 0x12, 0x38, 0x0a, 0x09, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, + 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, + 0x09, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x3c, 0x0a, 0x0b, 0x69, 0x6e, + 0x68, 0x65, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, + 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, + 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x69, 0x6e, 0x68, + 0x65, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x59, 0x0a, 0x10, 0x4b, 0x70, 0x72, 0x6f, + 0x62, 0x65, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x31, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, + 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x22, 0xd5, 0x01, 0x0a, 0x13, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x55, 0x73, + 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x31, 0x0a, 0x05, 0x6c, + 0x65, 0x76, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, + 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x32, + 0x0a, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x6f, 0x77, 0x6e, + 0x65, 0x72, 0x12, 0x32, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, + 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x23, 0x0a, 0x02, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4e, 0x61, + 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x02, 0x6e, 0x73, 0x22, 0x61, 0x0a, 0x0d, 0x4b, + 0x70, 0x72, 0x6f, 0x62, 0x65, 0x42, 0x70, 0x66, 0x41, 0x74, 0x74, 0x72, 0x12, 0x1a, 0x0a, 0x08, + 0x50, 0x72, 0x6f, 0x67, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x50, 0x72, 0x6f, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x49, 0x6e, 0x73, 0x6e, + 0x43, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x49, 0x6e, 0x73, 0x6e, 0x43, + 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x7f, + 0x0a, 0x0f, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x50, 0x65, 0x72, 0x66, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x46, 0x75, 0x6e, 0x63, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x46, 0x75, 0x6e, + 0x63, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x20, 0x0a, + 0x0b, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x0b, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x22, + 0x9a, 0x01, 0x0a, 0x0c, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x42, 0x70, 0x66, 0x4d, 0x61, 0x70, + 0x12, 0x18, 0x0a, 0x07, 0x4d, 0x61, 0x70, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x4d, 0x61, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x4b, 0x65, + 0x79, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x4b, 0x65, 0x79, + 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x69, 0x7a, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x69, + 0x7a, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x4d, 0x61, 0x78, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x4d, 0x61, 0x78, 0x45, 0x6e, 0x74, 0x72, 0x69, + 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x4d, 0x61, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x4d, 0x61, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xcb, 0x08, 0x0a, + 0x0e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x12, + 0x1f, 0x0a, 0x0a, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x09, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x41, 0x72, 0x67, + 0x12, 0x19, 0x0a, 0x07, 0x69, 0x6e, 0x74, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x05, 0x48, 0x00, 0x52, 0x06, 0x69, 0x6e, 0x74, 0x41, 0x72, 0x67, 0x12, 0x2e, 0x0a, 0x07, 0x73, + 0x6b, 0x62, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, + 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x53, 0x6b, + 0x62, 0x48, 0x00, 0x52, 0x06, 0x73, 0x6b, 0x62, 0x41, 0x72, 0x67, 0x12, 0x1b, 0x0a, 0x08, 0x73, + 0x69, 0x7a, 0x65, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, + 0x07, 0x73, 0x69, 0x7a, 0x65, 0x41, 0x72, 0x67, 0x12, 0x1d, 0x0a, 0x09, 0x62, 0x79, 0x74, 0x65, + 0x73, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x08, 0x62, + 0x79, 0x74, 0x65, 0x73, 0x41, 0x72, 0x67, 0x12, 0x31, 0x0a, 0x08, 0x70, 0x61, 0x74, 0x68, 0x5f, + 0x61, 0x72, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x65, 0x74, 0x72, + 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x50, 0x61, 0x74, 0x68, 0x48, + 0x00, 0x52, 0x07, 0x70, 0x61, 0x74, 0x68, 0x41, 0x72, 0x67, 0x12, 0x31, 0x0a, 0x08, 0x66, 0x69, + 0x6c, 0x65, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, + 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x46, 0x69, + 0x6c, 0x65, 0x48, 0x00, 0x52, 0x07, 0x66, 0x69, 0x6c, 0x65, 0x41, 0x72, 0x67, 0x12, 0x50, 0x0a, + 0x13, 0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, + 0x5f, 0x61, 0x72, 0x67, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x65, 0x74, + 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x54, 0x72, 0x75, 0x6e, + 0x63, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x48, 0x00, 0x52, 0x11, 0x74, 0x72, + 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x41, 0x72, 0x67, 0x12, + 0x31, 0x0a, 0x08, 0x73, 0x6f, 0x63, 0x6b, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x09, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, + 0x6f, 0x62, 0x65, 0x53, 0x6f, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x07, 0x73, 0x6f, 0x63, 0x6b, 0x41, + 0x72, 0x67, 0x12, 0x31, 0x0a, 0x08, 0x63, 0x72, 0x65, 0x64, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, + 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x43, 0x72, 0x65, 0x64, 0x48, 0x00, 0x52, 0x07, 0x63, 0x72, + 0x65, 0x64, 0x41, 0x72, 0x67, 0x12, 0x1b, 0x0a, 0x08, 0x6c, 0x6f, 0x6e, 0x67, 0x5f, 0x61, 0x72, + 0x67, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x07, 0x6c, 0x6f, 0x6e, 0x67, 0x41, + 0x72, 0x67, 0x12, 0x3b, 0x0a, 0x0c, 0x62, 0x70, 0x66, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x5f, 0x61, + 0x72, 0x67, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, + 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x42, 0x70, 0x66, 0x41, 0x74, 0x74, + 0x72, 0x48, 0x00, 0x52, 0x0a, 0x62, 0x70, 0x66, 0x41, 0x74, 0x74, 0x72, 0x41, 0x72, 0x67, 0x12, + 0x41, 0x0a, 0x0e, 0x70, 0x65, 0x72, 0x66, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x72, + 0x67, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, + 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x50, 0x65, 0x72, 0x66, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0c, 0x70, 0x65, 0x72, 0x66, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x41, + 0x72, 0x67, 0x12, 0x38, 0x0a, 0x0b, 0x62, 0x70, 0x66, 0x5f, 0x6d, 0x61, 0x70, 0x5f, 0x61, 0x72, + 0x67, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, + 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x42, 0x70, 0x66, 0x4d, 0x61, 0x70, 0x48, + 0x00, 0x52, 0x09, 0x62, 0x70, 0x66, 0x4d, 0x61, 0x70, 0x41, 0x72, 0x67, 0x12, 0x1b, 0x0a, 0x08, + 0x75, 0x69, 0x6e, 0x74, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, + 0x52, 0x07, 0x75, 0x69, 0x6e, 0x74, 0x41, 0x72, 0x67, 0x12, 0x51, 0x0a, 0x12, 0x75, 0x73, 0x65, + 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x61, 0x72, 0x67, 0x18, + 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, + 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x42, 0x02, 0x18, 0x01, 0x48, 0x00, 0x52, 0x10, 0x75, 0x73, 0x65, 0x72, + 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x72, 0x67, 0x12, 0x43, 0x0a, 0x0e, + 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x11, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, + 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, + 0x48, 0x00, 0x52, 0x0d, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x41, 0x72, + 0x67, 0x12, 0x56, 0x0a, 0x17, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x72, 0x65, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x13, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, + 0x48, 0x00, 0x52, 0x15, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x72, 0x65, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x41, 0x72, 0x67, 0x12, 0x39, 0x0a, 0x0b, 0x75, 0x73, 0x65, + 0x72, 0x5f, 0x6e, 0x73, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, + 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x61, + 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x48, 0x00, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x4e, + 0x73, 0x41, 0x72, 0x67, 0x12, 0x37, 0x0a, 0x0a, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x61, + 0x72, 0x67, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, + 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x48, 0x00, 0x52, 0x09, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x41, 0x72, 0x67, 0x12, 0x14, 0x0a, + 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x42, 0x05, 0x0a, 0x03, 0x61, 0x72, 0x67, 0x22, 0xd0, 0x03, 0x0a, 0x0d, 0x50, + 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x29, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x06, 0x70, 0x61, - 0x72, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, 0x6d, 0x62, - 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, - 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4e, 0x61, 0x6d, - 0x65, 0x22, 0x96, 0x01, 0x0a, 0x0c, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x4d, 0x6f, 0x64, 0x75, - 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3d, 0x0a, 0x0c, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, - 0x75, 0x72, 0x65, 0x5f, 0x6f, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, - 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, - 0x75, 0x72, 0x65, 0x4f, 0x6b, 0x12, 0x33, 0x0a, 0x07, 0x74, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x64, - 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, - 0x6e, 0x2e, 0x54, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x64, 0x42, 0x69, 0x74, 0x73, 0x54, 0x79, 0x70, - 0x65, 0x52, 0x07, 0x74, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x64, 0x22, 0x56, 0x0a, 0x04, 0x54, 0x65, - 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x30, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x04, 0x61, 0x72, 0x67, 0x30, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x31, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x61, 0x72, 0x67, 0x31, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, - 0x67, 0x32, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x61, 0x72, 0x67, 0x32, 0x12, 0x12, - 0x0a, 0x04, 0x61, 0x72, 0x67, 0x33, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x61, 0x72, - 0x67, 0x33, 0x22, 0x51, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x37, 0x0a, 0x09, - 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, - 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, - 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x65, 0x76, 0x65, - 0x6e, 0x74, 0x53, 0x65, 0x74, 0x22, 0x90, 0x01, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x30, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, - 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x54, 0x79, 0x70, - 0x65, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x34, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, - 0x67, 0x6f, 0x6e, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, - 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x56, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x48, - 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x0d, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x5f, 0x73, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, + 0x72, 0x65, 0x6e, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2c, 0x0a, 0x04, 0x61, 0x72, 0x67, + 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, + 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x52, 0x04, 0x61, 0x72, 0x67, 0x73, 0x12, 0x30, 0x0a, 0x06, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, + 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x52, 0x06, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x12, 0x2e, 0x0a, 0x06, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, + 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3a, 0x0a, 0x0b, 0x73, 0x74, 0x61, + 0x63, 0x6b, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, + 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x54, + 0x72, 0x61, 0x63, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x54, 0x72, 0x61, 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x0d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, + 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x41, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xb2, 0x02, + 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x72, 0x61, 0x63, 0x65, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x12, 0x2b, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, + 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, + 0x12, 0x29, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, + 0x75, 0x62, 0x73, 0x79, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x75, 0x62, + 0x73, 0x79, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x04, 0x61, 0x72, 0x67, + 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, + 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x52, 0x04, 0x61, 0x72, 0x67, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, + 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x22, 0xce, 0x01, 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x55, 0x70, + 0x72, 0x6f, 0x62, 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, + 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, + 0x73, 0x12, 0x29, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, + 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, + 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x22, 0x96, 0x01, 0x0a, 0x0c, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x4d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3d, 0x0a, 0x0c, 0x73, 0x69, 0x67, 0x6e, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x6f, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0b, 0x73, 0x69, 0x67, 0x6e, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x4f, 0x6b, 0x12, 0x33, 0x0a, 0x07, 0x74, 0x61, 0x69, 0x6e, 0x74, + 0x65, 0x64, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, + 0x67, 0x6f, 0x6e, 0x2e, 0x54, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x64, 0x42, 0x69, 0x74, 0x73, 0x54, + 0x79, 0x70, 0x65, 0x52, 0x07, 0x74, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x64, 0x22, 0x56, 0x0a, 0x04, + 0x54, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x30, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x04, 0x61, 0x72, 0x67, 0x30, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x31, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x61, 0x72, 0x67, 0x31, 0x12, 0x12, 0x0a, 0x04, + 0x61, 0x72, 0x67, 0x32, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x61, 0x72, 0x67, 0x32, + 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x33, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, + 0x61, 0x72, 0x67, 0x33, 0x22, 0x51, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x48, 0x65, 0x61, 0x6c, 0x74, + 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x37, + 0x0a, 0x09, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x48, 0x65, 0x61, + 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x74, 0x22, 0x90, 0x01, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x6c, + 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x30, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, + 0x6f, 0x6e, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x54, + 0x79, 0x70, 0x65, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x34, 0x0a, 0x06, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x52, 0x0c, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x22, 0x6a, 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x61, 0x64, 0x65, - 0x72, 0x12, 0x2b, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, - 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x12, - 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, - 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x64, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x64, 0x22, 0x64, 0x0a, 0x12, - 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x45, 0x0a, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x65, - 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x48, 0x00, 0x52, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, - 0x6e, 0x74, 0x22, 0x15, 0x0a, 0x13, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x48, 0x6f, 0x6f, - 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xdb, 0x01, 0x0a, 0x0f, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x20, 0x0a, - 0x0b, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x50, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0b, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x50, 0x61, 0x74, 0x68, 0x12, - 0x18, 0x0a, 0x07, 0x72, 0x6f, 0x6f, 0x74, 0x44, 0x69, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x72, 0x6f, 0x6f, 0x74, 0x44, 0x69, 0x72, 0x12, 0x4c, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, - 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, - 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x3e, 0x0a, 0x10, 0x41, 0x6e, 0x6e, 0x6f, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x5b, 0x0a, 0x0f, 0x53, 0x74, 0x61, 0x63, 0x6b, - 0x54, 0x72, 0x61, 0x63, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x61, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x16, 0x0a, 0x06, - 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x79, - 0x6d, 0x62, 0x6f, 0x6c, 0x2a, 0x93, 0x03, 0x0a, 0x0c, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x15, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, - 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, - 0x12, 0x16, 0x0a, 0x12, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x4b, 0x50, 0x52, 0x4f, - 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x46, 0x4f, 0x4c, 0x4c, 0x4f, 0x57, - 0x46, 0x44, 0x10, 0x02, 0x12, 0x19, 0x0a, 0x15, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, - 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x49, 0x47, 0x4b, 0x49, 0x4c, 0x4c, 0x10, 0x03, 0x12, - 0x1c, 0x0a, 0x18, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, - 0x5f, 0x55, 0x4e, 0x46, 0x4f, 0x4c, 0x4c, 0x4f, 0x57, 0x46, 0x44, 0x10, 0x04, 0x12, 0x1a, 0x0a, - 0x16, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4f, - 0x56, 0x45, 0x52, 0x52, 0x49, 0x44, 0x45, 0x10, 0x05, 0x12, 0x18, 0x0a, 0x14, 0x4b, 0x50, 0x52, - 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4f, 0x50, 0x59, 0x46, - 0x44, 0x10, 0x06, 0x12, 0x18, 0x0a, 0x14, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, - 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x47, 0x45, 0x54, 0x55, 0x52, 0x4c, 0x10, 0x07, 0x12, 0x1b, 0x0a, - 0x17, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, - 0x4e, 0x53, 0x4c, 0x4f, 0x4f, 0x4b, 0x55, 0x50, 0x10, 0x08, 0x12, 0x18, 0x0a, 0x14, 0x4b, 0x50, - 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x4f, 0x50, 0x4f, - 0x53, 0x54, 0x10, 0x09, 0x12, 0x18, 0x0a, 0x14, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, - 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x41, 0x4c, 0x10, 0x0a, 0x12, 0x1b, - 0x0a, 0x17, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, - 0x54, 0x52, 0x41, 0x43, 0x4b, 0x53, 0x4f, 0x43, 0x4b, 0x10, 0x0b, 0x12, 0x1d, 0x0a, 0x19, 0x4b, - 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x54, - 0x52, 0x41, 0x43, 0x4b, 0x53, 0x4f, 0x43, 0x4b, 0x10, 0x0c, 0x12, 0x1e, 0x0a, 0x1a, 0x4b, 0x50, - 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x4f, 0x54, 0x49, - 0x46, 0x59, 0x4b, 0x49, 0x4c, 0x4c, 0x45, 0x52, 0x10, 0x0d, 0x2a, 0x4f, 0x0a, 0x10, 0x48, 0x65, - 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1c, - 0x0a, 0x18, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, - 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x10, 0x00, 0x12, 0x1d, 0x0a, 0x19, - 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x54, 0x59, - 0x50, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x10, 0x01, 0x2a, 0x7c, 0x0a, 0x12, 0x48, - 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x12, 0x17, 0x0a, 0x13, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, - 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x48, 0x45, - 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x55, 0x4e, 0x4e, - 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, - 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x53, 0x54, 0x4f, 0x50, 0x50, 0x45, 0x44, 0x10, 0x02, - 0x12, 0x17, 0x0a, 0x13, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, - 0x53, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x2a, 0x8d, 0x02, 0x0a, 0x0f, 0x54, 0x61, - 0x69, 0x6e, 0x74, 0x65, 0x64, 0x42, 0x69, 0x74, 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0f, 0x0a, - 0x0b, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x45, 0x54, 0x10, 0x00, 0x12, 0x1c, - 0x0a, 0x18, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x50, 0x52, 0x4f, 0x50, 0x52, 0x49, 0x45, 0x54, - 0x41, 0x52, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, - 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x44, 0x5f, 0x4d, 0x4f, 0x44, - 0x55, 0x4c, 0x45, 0x10, 0x02, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x46, - 0x4f, 0x52, 0x43, 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x4d, 0x4f, 0x44, - 0x55, 0x4c, 0x45, 0x10, 0x04, 0x12, 0x18, 0x0a, 0x13, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x53, - 0x54, 0x41, 0x47, 0x45, 0x44, 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x80, 0x08, 0x12, - 0x1d, 0x0a, 0x18, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, - 0x54, 0x52, 0x45, 0x45, 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x80, 0x20, 0x12, 0x1a, - 0x0a, 0x15, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x49, 0x47, 0x4e, 0x45, 0x44, - 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x80, 0x40, 0x12, 0x24, 0x0a, 0x1e, 0x54, 0x41, - 0x49, 0x4e, 0x54, 0x5f, 0x4b, 0x45, 0x52, 0x4e, 0x45, 0x4c, 0x5f, 0x4c, 0x49, 0x56, 0x45, 0x5f, - 0x50, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x80, 0x80, 0x02, - 0x12, 0x17, 0x0a, 0x11, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x4d, - 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x80, 0x80, 0x10, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x75, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x56, 0x0a, 0x17, 0x47, 0x65, + 0x74, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x0d, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x5f, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, + 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x0c, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x22, 0x6a, 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x61, + 0x64, 0x65, 0x72, 0x12, 0x2b, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, + 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, + 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x70, 0x61, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x64, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x64, 0x22, 0x64, + 0x0a, 0x12, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x45, 0x0a, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, + 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x48, 0x00, 0x52, 0x0f, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x42, 0x07, 0x0a, 0x05, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x22, 0x15, 0x0a, 0x13, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x48, + 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xdb, 0x01, 0x0a, 0x0f, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, + 0x20, 0x0a, 0x0b, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x50, 0x61, 0x74, 0x68, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x50, 0x61, 0x74, + 0x68, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x6f, 0x6f, 0x74, 0x44, 0x69, 0x72, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x72, 0x6f, 0x6f, 0x74, 0x44, 0x69, 0x72, 0x12, 0x4c, 0x0a, 0x0b, 0x61, + 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x2a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, + 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x3e, 0x0a, 0x10, 0x41, 0x6e, 0x6e, + 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x5b, 0x0a, 0x0f, 0x53, 0x74, 0x61, + 0x63, 0x6b, 0x54, 0x72, 0x61, 0x63, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x18, 0x0a, 0x07, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x16, + 0x0a, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x2a, 0x93, 0x03, 0x0a, 0x0c, 0x4b, 0x70, 0x72, 0x6f, 0x62, + 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x15, 0x4b, 0x50, 0x52, 0x4f, 0x42, + 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, + 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x4b, 0x50, + 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x46, 0x4f, 0x4c, 0x4c, + 0x4f, 0x57, 0x46, 0x44, 0x10, 0x02, 0x12, 0x19, 0x0a, 0x15, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, + 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x49, 0x47, 0x4b, 0x49, 0x4c, 0x4c, 0x10, + 0x03, 0x12, 0x1c, 0x0a, 0x18, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, + 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x46, 0x4f, 0x4c, 0x4c, 0x4f, 0x57, 0x46, 0x44, 0x10, 0x04, 0x12, + 0x1a, 0x0a, 0x16, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x52, 0x49, 0x44, 0x45, 0x10, 0x05, 0x12, 0x18, 0x0a, 0x14, 0x4b, + 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4f, 0x50, + 0x59, 0x46, 0x44, 0x10, 0x06, 0x12, 0x18, 0x0a, 0x14, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, + 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x47, 0x45, 0x54, 0x55, 0x52, 0x4c, 0x10, 0x07, 0x12, + 0x1b, 0x0a, 0x17, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x44, 0x4e, 0x53, 0x4c, 0x4f, 0x4f, 0x4b, 0x55, 0x50, 0x10, 0x08, 0x12, 0x18, 0x0a, 0x14, + 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x4f, + 0x50, 0x4f, 0x53, 0x54, 0x10, 0x09, 0x12, 0x18, 0x0a, 0x14, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, + 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x41, 0x4c, 0x10, 0x0a, + 0x12, 0x1b, 0x0a, 0x17, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, + 0x4e, 0x5f, 0x54, 0x52, 0x41, 0x43, 0x4b, 0x53, 0x4f, 0x43, 0x4b, 0x10, 0x0b, 0x12, 0x1d, 0x0a, + 0x19, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, + 0x4e, 0x54, 0x52, 0x41, 0x43, 0x4b, 0x53, 0x4f, 0x43, 0x4b, 0x10, 0x0c, 0x12, 0x1e, 0x0a, 0x1a, + 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x4f, + 0x54, 0x49, 0x46, 0x59, 0x4b, 0x49, 0x4c, 0x4c, 0x45, 0x52, 0x10, 0x0d, 0x2a, 0x4f, 0x0a, 0x10, + 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x1c, 0x0a, 0x18, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, + 0x53, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x10, 0x00, 0x12, 0x1d, + 0x0a, 0x19, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x10, 0x01, 0x2a, 0x7c, 0x0a, + 0x12, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x12, 0x17, 0x0a, 0x13, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x53, 0x54, + 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, + 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x55, + 0x4e, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x48, 0x45, 0x41, 0x4c, 0x54, + 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x53, 0x54, 0x4f, 0x50, 0x50, 0x45, 0x44, + 0x10, 0x02, 0x12, 0x17, 0x0a, 0x13, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x53, 0x54, 0x41, + 0x54, 0x55, 0x53, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x2a, 0x8d, 0x02, 0x0a, 0x0f, + 0x54, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x64, 0x42, 0x69, 0x74, 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x0f, 0x0a, 0x0b, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x45, 0x54, 0x10, 0x00, + 0x12, 0x1c, 0x0a, 0x18, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x50, 0x52, 0x4f, 0x50, 0x52, 0x49, + 0x45, 0x54, 0x41, 0x52, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x17, + 0x0a, 0x13, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x44, 0x5f, 0x4d, + 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x02, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x41, 0x49, 0x4e, 0x54, + 0x5f, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x4d, + 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x04, 0x12, 0x18, 0x0a, 0x13, 0x54, 0x41, 0x49, 0x4e, 0x54, + 0x5f, 0x53, 0x54, 0x41, 0x47, 0x45, 0x44, 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x80, + 0x08, 0x12, 0x1d, 0x0a, 0x18, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, + 0x46, 0x5f, 0x54, 0x52, 0x45, 0x45, 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x80, 0x20, + 0x12, 0x1a, 0x0a, 0x15, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x49, 0x47, 0x4e, + 0x45, 0x44, 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x80, 0x40, 0x12, 0x24, 0x0a, 0x1e, + 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x4b, 0x45, 0x52, 0x4e, 0x45, 0x4c, 0x5f, 0x4c, 0x49, 0x56, + 0x45, 0x5f, 0x50, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x80, + 0x80, 0x02, 0x12, 0x17, 0x0a, 0x11, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x54, 0x45, 0x53, 0x54, + 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x80, 0x80, 0x10, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( @@ -4230,7 +4278,8 @@ var file_tetragon_tetragon_proto_goTypes = []interface{}{ (CapabilitiesType)(0), // 45: tetragon.CapabilitiesType (*wrapperspb.Int32Value)(nil), // 46: google.protobuf.Int32Value (SecureBitsType)(0), // 47: tetragon.SecureBitsType - (*wrapperspb.BoolValue)(nil), // 48: google.protobuf.BoolValue + (ProcessPrivilegesChanged)(0), // 48: tetragon.ProcessPrivilegesChanged + (*wrapperspb.BoolValue)(nil), // 49: google.protobuf.BoolValue } var file_tetragon_tetragon_proto_depIdxs = []int32{ 4, // 0: tetragon.Container.image:type_name -> tetragon.Image @@ -4268,71 +4317,72 @@ var file_tetragon_tetragon_proto_depIdxs = []int32{ 10, // 32: tetragon.ProcessCredentials.user_ns:type_name -> tetragon.UserNamespace 44, // 33: tetragon.BinaryProperties.setuid:type_name -> google.protobuf.UInt32Value 44, // 34: tetragon.BinaryProperties.setgid:type_name -> google.protobuf.UInt32Value - 44, // 35: tetragon.Process.pid:type_name -> google.protobuf.UInt32Value - 44, // 36: tetragon.Process.uid:type_name -> google.protobuf.UInt32Value - 43, // 37: tetragon.Process.start_time:type_name -> google.protobuf.Timestamp - 44, // 38: tetragon.Process.auid:type_name -> google.protobuf.UInt32Value - 6, // 39: tetragon.Process.pod:type_name -> tetragon.Pod - 7, // 40: tetragon.Process.cap:type_name -> tetragon.Capabilities - 9, // 41: tetragon.Process.ns:type_name -> tetragon.Namespaces - 44, // 42: tetragon.Process.tid:type_name -> google.protobuf.UInt32Value - 11, // 43: tetragon.Process.process_credentials:type_name -> tetragon.ProcessCredentials - 12, // 44: tetragon.Process.binary_properties:type_name -> tetragon.BinaryProperties - 13, // 45: tetragon.ProcessExec.process:type_name -> tetragon.Process - 13, // 46: tetragon.ProcessExec.parent:type_name -> tetragon.Process - 13, // 47: tetragon.ProcessExec.ancestors:type_name -> tetragon.Process - 13, // 48: tetragon.ProcessExit.process:type_name -> tetragon.Process - 13, // 49: tetragon.ProcessExit.parent:type_name -> tetragon.Process - 43, // 50: tetragon.ProcessExit.time:type_name -> google.protobuf.Timestamp - 45, // 51: tetragon.KprobeCred.permitted:type_name -> tetragon.CapabilitiesType - 45, // 52: tetragon.KprobeCred.effective:type_name -> tetragon.CapabilitiesType - 45, // 53: tetragon.KprobeCred.inheritable:type_name -> tetragon.CapabilitiesType - 46, // 54: tetragon.KprobeCapability.value:type_name -> google.protobuf.Int32Value - 46, // 55: tetragon.KprobeUserNamespace.level:type_name -> google.protobuf.Int32Value - 44, // 56: tetragon.KprobeUserNamespace.owner:type_name -> google.protobuf.UInt32Value - 44, // 57: tetragon.KprobeUserNamespace.group:type_name -> google.protobuf.UInt32Value - 8, // 58: tetragon.KprobeUserNamespace.ns:type_name -> tetragon.Namespace - 17, // 59: tetragon.KprobeArgument.skb_arg:type_name -> tetragon.KprobeSkb - 18, // 60: tetragon.KprobeArgument.path_arg:type_name -> tetragon.KprobePath - 19, // 61: tetragon.KprobeArgument.file_arg:type_name -> tetragon.KprobeFile - 20, // 62: tetragon.KprobeArgument.truncated_bytes_arg:type_name -> tetragon.KprobeTruncatedBytes - 16, // 63: tetragon.KprobeArgument.sock_arg:type_name -> tetragon.KprobeSock - 21, // 64: tetragon.KprobeArgument.cred_arg:type_name -> tetragon.KprobeCred - 24, // 65: tetragon.KprobeArgument.bpf_attr_arg:type_name -> tetragon.KprobeBpfAttr - 25, // 66: tetragon.KprobeArgument.perf_event_arg:type_name -> tetragon.KprobePerfEvent - 26, // 67: tetragon.KprobeArgument.bpf_map_arg:type_name -> tetragon.KprobeBpfMap - 23, // 68: tetragon.KprobeArgument.user_namespace_arg:type_name -> tetragon.KprobeUserNamespace - 22, // 69: tetragon.KprobeArgument.capability_arg:type_name -> tetragon.KprobeCapability - 11, // 70: tetragon.KprobeArgument.process_credentials_arg:type_name -> tetragon.ProcessCredentials - 10, // 71: tetragon.KprobeArgument.user_ns_arg:type_name -> tetragon.UserNamespace - 31, // 72: tetragon.KprobeArgument.module_arg:type_name -> tetragon.KernelModule - 13, // 73: tetragon.ProcessKprobe.process:type_name -> tetragon.Process - 13, // 74: tetragon.ProcessKprobe.parent:type_name -> tetragon.Process - 27, // 75: tetragon.ProcessKprobe.args:type_name -> tetragon.KprobeArgument - 27, // 76: tetragon.ProcessKprobe.return:type_name -> tetragon.KprobeArgument - 0, // 77: tetragon.ProcessKprobe.action:type_name -> tetragon.KprobeAction - 40, // 78: tetragon.ProcessKprobe.stack_trace:type_name -> tetragon.StackTraceEntry - 0, // 79: tetragon.ProcessKprobe.return_action:type_name -> tetragon.KprobeAction - 13, // 80: tetragon.ProcessTracepoint.process:type_name -> tetragon.Process - 13, // 81: tetragon.ProcessTracepoint.parent:type_name -> tetragon.Process - 27, // 82: tetragon.ProcessTracepoint.args:type_name -> tetragon.KprobeArgument - 0, // 83: tetragon.ProcessTracepoint.action:type_name -> tetragon.KprobeAction - 13, // 84: tetragon.ProcessUprobe.process:type_name -> tetragon.Process - 13, // 85: tetragon.ProcessUprobe.parent:type_name -> tetragon.Process - 48, // 86: tetragon.KernelModule.signature_ok:type_name -> google.protobuf.BoolValue - 3, // 87: tetragon.KernelModule.tainted:type_name -> tetragon.TaintedBitsType - 1, // 88: tetragon.GetHealthStatusRequest.event_set:type_name -> tetragon.HealthStatusType - 1, // 89: tetragon.HealthStatus.event:type_name -> tetragon.HealthStatusType - 2, // 90: tetragon.HealthStatus.status:type_name -> tetragon.HealthStatusResult - 34, // 91: tetragon.GetHealthStatusResponse.health_status:type_name -> tetragon.HealthStatus - 13, // 92: tetragon.ProcessLoader.process:type_name -> tetragon.Process - 39, // 93: tetragon.RuntimeHookRequest.createContainer:type_name -> tetragon.CreateContainer - 42, // 94: tetragon.CreateContainer.annotations:type_name -> tetragon.CreateContainer.AnnotationsEntry - 95, // [95:95] is the sub-list for method output_type - 95, // [95:95] is the sub-list for method input_type - 95, // [95:95] is the sub-list for extension type_name - 95, // [95:95] is the sub-list for extension extendee - 0, // [0:95] is the sub-list for field type_name + 48, // 35: tetragon.BinaryProperties.privileges_changed:type_name -> tetragon.ProcessPrivilegesChanged + 44, // 36: tetragon.Process.pid:type_name -> google.protobuf.UInt32Value + 44, // 37: tetragon.Process.uid:type_name -> google.protobuf.UInt32Value + 43, // 38: tetragon.Process.start_time:type_name -> google.protobuf.Timestamp + 44, // 39: tetragon.Process.auid:type_name -> google.protobuf.UInt32Value + 6, // 40: tetragon.Process.pod:type_name -> tetragon.Pod + 7, // 41: tetragon.Process.cap:type_name -> tetragon.Capabilities + 9, // 42: tetragon.Process.ns:type_name -> tetragon.Namespaces + 44, // 43: tetragon.Process.tid:type_name -> google.protobuf.UInt32Value + 11, // 44: tetragon.Process.process_credentials:type_name -> tetragon.ProcessCredentials + 12, // 45: tetragon.Process.binary_properties:type_name -> tetragon.BinaryProperties + 13, // 46: tetragon.ProcessExec.process:type_name -> tetragon.Process + 13, // 47: tetragon.ProcessExec.parent:type_name -> tetragon.Process + 13, // 48: tetragon.ProcessExec.ancestors:type_name -> tetragon.Process + 13, // 49: tetragon.ProcessExit.process:type_name -> tetragon.Process + 13, // 50: tetragon.ProcessExit.parent:type_name -> tetragon.Process + 43, // 51: tetragon.ProcessExit.time:type_name -> google.protobuf.Timestamp + 45, // 52: tetragon.KprobeCred.permitted:type_name -> tetragon.CapabilitiesType + 45, // 53: tetragon.KprobeCred.effective:type_name -> tetragon.CapabilitiesType + 45, // 54: tetragon.KprobeCred.inheritable:type_name -> tetragon.CapabilitiesType + 46, // 55: tetragon.KprobeCapability.value:type_name -> google.protobuf.Int32Value + 46, // 56: tetragon.KprobeUserNamespace.level:type_name -> google.protobuf.Int32Value + 44, // 57: tetragon.KprobeUserNamespace.owner:type_name -> google.protobuf.UInt32Value + 44, // 58: tetragon.KprobeUserNamespace.group:type_name -> google.protobuf.UInt32Value + 8, // 59: tetragon.KprobeUserNamespace.ns:type_name -> tetragon.Namespace + 17, // 60: tetragon.KprobeArgument.skb_arg:type_name -> tetragon.KprobeSkb + 18, // 61: tetragon.KprobeArgument.path_arg:type_name -> tetragon.KprobePath + 19, // 62: tetragon.KprobeArgument.file_arg:type_name -> tetragon.KprobeFile + 20, // 63: tetragon.KprobeArgument.truncated_bytes_arg:type_name -> tetragon.KprobeTruncatedBytes + 16, // 64: tetragon.KprobeArgument.sock_arg:type_name -> tetragon.KprobeSock + 21, // 65: tetragon.KprobeArgument.cred_arg:type_name -> tetragon.KprobeCred + 24, // 66: tetragon.KprobeArgument.bpf_attr_arg:type_name -> tetragon.KprobeBpfAttr + 25, // 67: tetragon.KprobeArgument.perf_event_arg:type_name -> tetragon.KprobePerfEvent + 26, // 68: tetragon.KprobeArgument.bpf_map_arg:type_name -> tetragon.KprobeBpfMap + 23, // 69: tetragon.KprobeArgument.user_namespace_arg:type_name -> tetragon.KprobeUserNamespace + 22, // 70: tetragon.KprobeArgument.capability_arg:type_name -> tetragon.KprobeCapability + 11, // 71: tetragon.KprobeArgument.process_credentials_arg:type_name -> tetragon.ProcessCredentials + 10, // 72: tetragon.KprobeArgument.user_ns_arg:type_name -> tetragon.UserNamespace + 31, // 73: tetragon.KprobeArgument.module_arg:type_name -> tetragon.KernelModule + 13, // 74: tetragon.ProcessKprobe.process:type_name -> tetragon.Process + 13, // 75: tetragon.ProcessKprobe.parent:type_name -> tetragon.Process + 27, // 76: tetragon.ProcessKprobe.args:type_name -> tetragon.KprobeArgument + 27, // 77: tetragon.ProcessKprobe.return:type_name -> tetragon.KprobeArgument + 0, // 78: tetragon.ProcessKprobe.action:type_name -> tetragon.KprobeAction + 40, // 79: tetragon.ProcessKprobe.stack_trace:type_name -> tetragon.StackTraceEntry + 0, // 80: tetragon.ProcessKprobe.return_action:type_name -> tetragon.KprobeAction + 13, // 81: tetragon.ProcessTracepoint.process:type_name -> tetragon.Process + 13, // 82: tetragon.ProcessTracepoint.parent:type_name -> tetragon.Process + 27, // 83: tetragon.ProcessTracepoint.args:type_name -> tetragon.KprobeArgument + 0, // 84: tetragon.ProcessTracepoint.action:type_name -> tetragon.KprobeAction + 13, // 85: tetragon.ProcessUprobe.process:type_name -> tetragon.Process + 13, // 86: tetragon.ProcessUprobe.parent:type_name -> tetragon.Process + 49, // 87: tetragon.KernelModule.signature_ok:type_name -> google.protobuf.BoolValue + 3, // 88: tetragon.KernelModule.tainted:type_name -> tetragon.TaintedBitsType + 1, // 89: tetragon.GetHealthStatusRequest.event_set:type_name -> tetragon.HealthStatusType + 1, // 90: tetragon.HealthStatus.event:type_name -> tetragon.HealthStatusType + 2, // 91: tetragon.HealthStatus.status:type_name -> tetragon.HealthStatusResult + 34, // 92: tetragon.GetHealthStatusResponse.health_status:type_name -> tetragon.HealthStatus + 13, // 93: tetragon.ProcessLoader.process:type_name -> tetragon.Process + 39, // 94: tetragon.RuntimeHookRequest.createContainer:type_name -> tetragon.CreateContainer + 42, // 95: tetragon.CreateContainer.annotations:type_name -> tetragon.CreateContainer.AnnotationsEntry + 96, // [96:96] is the sub-list for method output_type + 96, // [96:96] is the sub-list for method input_type + 96, // [96:96] is the sub-list for extension type_name + 96, // [96:96] is the sub-list for extension extendee + 0, // [0:96] is the sub-list for field type_name } func init() { file_tetragon_tetragon_proto_init() } diff --git a/vendor/github.com/cilium/tetragon/api/v1/tetragon/tetragon.proto b/vendor/github.com/cilium/tetragon/api/v1/tetragon/tetragon.proto index 70b52f6a924..ad0bf214197 100644 --- a/vendor/github.com/cilium/tetragon/api/v1/tetragon/tetragon.proto +++ b/vendor/github.com/cilium/tetragon/api/v1/tetragon/tetragon.proto @@ -141,6 +141,10 @@ message BinaryProperties { google.protobuf.UInt32Value setuid = 1; // If set then this is the set group ID used for execution google.protobuf.UInt32Value setgid = 2; + // The reasons why this binary execution changed privileges. Usually this happens when the process executes + // a binary with the set-user-ID to root or file capability sets. + // The final granted privileges can be listed inside the `process_credentials` or capabilities fields part of of the `process` object. + repeated ProcessPrivilegesChanged privileges_changed = 3; } message Process { @@ -427,6 +431,8 @@ message ProcessKprobe { string policy_name = 8; // Action performed when the return kprobe executed. KprobeAction return_action = 9; + // Short message of the Tracing Policy to inform users what is going on. + string message = 10; } message ProcessTracepoint { @@ -445,6 +451,8 @@ message ProcessTracepoint { string policy_name = 7; // Action performed when the tracepoint matched. KprobeAction action = 8; + // Short message of the Tracing Policy to inform users what is going on. + string message = 9; } message ProcessUprobe { @@ -454,6 +462,8 @@ message ProcessUprobe { string symbol = 4; // Name of the policy that created that uprobe. string policy_name = 5; + // Short message of the Tracing Policy to inform users what is going on. + string message = 6; } message KernelModule { diff --git a/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_tracingpolicies.yaml b/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_tracingpolicies.yaml index 31ad24954e1..c7d189a7095 100644 --- a/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_tracingpolicies.yaml +++ b/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_tracingpolicies.yaml @@ -131,6 +131,11 @@ spec: call: description: Name of the function to apply the kprobe spec to. type: string + message: + description: A short message of 256 characters max that will + be included in the event output to inform users what is going + on. + type: string return: default: false description: Indicates whether to collect return value of the @@ -831,6 +836,11 @@ spec: event: description: Tracepoint event type: string + message: + description: A short message of 256 characters max that will + be included in the event output to inform users what is going + on. + type: string selectors: description: Selectors to apply before producing trace output. Selectors are ORed. @@ -1270,6 +1280,11 @@ spec: description: A list of uprobe specs. items: properties: + message: + description: A short message of 256 characters max that will + be included in the event output to inform users what is going + on. + type: string path: description: Name of the traced binary type: string diff --git a/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_tracingpoliciesnamespaced.yaml b/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_tracingpoliciesnamespaced.yaml index 1ed3b1fb9bc..4e40f35c8b7 100644 --- a/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_tracingpoliciesnamespaced.yaml +++ b/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_tracingpoliciesnamespaced.yaml @@ -131,6 +131,11 @@ spec: call: description: Name of the function to apply the kprobe spec to. type: string + message: + description: A short message of 256 characters max that will + be included in the event output to inform users what is going + on. + type: string return: default: false description: Indicates whether to collect return value of the @@ -831,6 +836,11 @@ spec: event: description: Tracepoint event type: string + message: + description: A short message of 256 characters max that will + be included in the event output to inform users what is going + on. + type: string selectors: description: Selectors to apply before producing trace output. Selectors are ORed. @@ -1270,6 +1280,11 @@ spec: description: A list of uprobe specs. items: properties: + message: + description: A short message of 256 characters max that will + be included in the event output to inform users what is going + on. + type: string path: description: Name of the traced binary type: string diff --git a/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1/types.go b/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1/types.go index 998911f2bc8..191f37c91e0 100644 --- a/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1/types.go +++ b/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1/types.go @@ -33,6 +33,10 @@ type KProbeSpec struct { // Indicates whether the traced function is a syscall. Syscall bool `json:"syscall"` // +kubebuilder:validation:Optional + // A short message of 256 characters max that will be included + // in the event output to inform users what is going on. + Message string `json:"message"` + // +kubebuilder:validation:Optional // A list of function arguments to include in the trace output. Args []KProbeArg `json:"args,omitempty"` // +kubebuilder:validation:Optional @@ -227,6 +231,10 @@ type TracepointSpec struct { // Tracepoint event Event string `json:"event"` // +kubebuilder:validation:Optional + // A short message of 256 characters max that will be included + // in the event output to inform users what is going on. + Message string `json:"message"` + // +kubebuilder:validation:Optional // A list of function arguments to include in the trace output. Args []KProbeArg `json:"args,omitempty"` // +kubebuilder:validation:Optional @@ -240,6 +248,10 @@ type UProbeSpec struct { // Name of the traced symbol Symbol string `json:"symbol"` // +kubebuilder:validation:Optional + // A short message of 256 characters max that will be included + // in the event output to inform users what is going on. + Message string `json:"message"` + // +kubebuilder:validation:Optional // Selectors to apply before producing trace output. Selectors are ORed. Selectors []KProbeSelector `json:"selectors,omitempty"` } diff --git a/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1/version.go b/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1/version.go index 65a30f7ebe8..f54cef27815 100644 --- a/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1/version.go +++ b/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1/version.go @@ -7,4 +7,4 @@ package v1alpha1 // Used to determine if CRD needs to be updated in cluster // // Developers: Bump patch for each change in the CRD schema. -const CustomResourceDefinitionSchemaVersion = "1.1.1" +const CustomResourceDefinitionSchemaVersion = "1.1.2" diff --git a/vendor/golang.org/x/sync/errgroup/errgroup.go b/vendor/golang.org/x/sync/errgroup/errgroup.go index b18efb743fe..948a3ee63d4 100644 --- a/vendor/golang.org/x/sync/errgroup/errgroup.go +++ b/vendor/golang.org/x/sync/errgroup/errgroup.go @@ -4,6 +4,9 @@ // Package errgroup provides synchronization, error propagation, and Context // cancelation for groups of goroutines working on subtasks of a common task. +// +// [errgroup.Group] is related to [sync.WaitGroup] but adds handling of tasks +// returning errors. package errgroup import ( diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh index 6202638bae8..c6492020ec7 100644 --- a/vendor/golang.org/x/sys/unix/mkerrors.sh +++ b/vendor/golang.org/x/sys/unix/mkerrors.sh @@ -248,6 +248,7 @@ struct ltchars { #include #include #include +#include #include #include #include @@ -283,10 +284,6 @@ struct ltchars { #include #endif -#ifndef MSG_FASTOPEN -#define MSG_FASTOPEN 0x20000000 -#endif - #ifndef PTRACE_GETREGS #define PTRACE_GETREGS 0xc #endif @@ -295,14 +292,6 @@ struct ltchars { #define PTRACE_SETREGS 0xd #endif -#ifndef SOL_NETLINK -#define SOL_NETLINK 270 -#endif - -#ifndef SOL_SMC -#define SOL_SMC 286 -#endif - #ifdef SOL_BLUETOOTH // SPARC includes this in /usr/include/sparc64-linux-gnu/bits/socket.h // but it is already in bluetooth_linux.go @@ -319,10 +308,23 @@ struct ltchars { #undef TIPC_WAIT_FOREVER #define TIPC_WAIT_FOREVER 0xffffffff -// Copied from linux/l2tp.h -// Including linux/l2tp.h here causes conflicts between linux/in.h -// and netinet/in.h included via net/route.h above. -#define IPPROTO_L2TP 115 +// Copied from linux/netfilter/nf_nat.h +// Including linux/netfilter/nf_nat.h here causes conflicts between linux/in.h +// and netinet/in.h. +#define NF_NAT_RANGE_MAP_IPS (1 << 0) +#define NF_NAT_RANGE_PROTO_SPECIFIED (1 << 1) +#define NF_NAT_RANGE_PROTO_RANDOM (1 << 2) +#define NF_NAT_RANGE_PERSISTENT (1 << 3) +#define NF_NAT_RANGE_PROTO_RANDOM_FULLY (1 << 4) +#define NF_NAT_RANGE_PROTO_OFFSET (1 << 5) +#define NF_NAT_RANGE_NETMAP (1 << 6) +#define NF_NAT_RANGE_PROTO_RANDOM_ALL \ + (NF_NAT_RANGE_PROTO_RANDOM | NF_NAT_RANGE_PROTO_RANDOM_FULLY) +#define NF_NAT_RANGE_MASK \ + (NF_NAT_RANGE_MAP_IPS | NF_NAT_RANGE_PROTO_SPECIFIED | \ + NF_NAT_RANGE_PROTO_RANDOM | NF_NAT_RANGE_PERSISTENT | \ + NF_NAT_RANGE_PROTO_RANDOM_FULLY | NF_NAT_RANGE_PROTO_OFFSET | \ + NF_NAT_RANGE_NETMAP) // Copied from linux/hid.h. // Keep in sync with the size of the referenced fields. @@ -603,6 +605,9 @@ ccflags="$@" $2 ~ /^FSOPT_/ || $2 ~ /^WDIO[CFS]_/ || $2 ~ /^NFN/ || + $2 !~ /^NFT_META_IIFTYPE/ && + $2 ~ /^NFT_/ || + $2 ~ /^NF_NAT_/ || $2 ~ /^XDP_/ || $2 ~ /^RWF_/ || $2 ~ /^(HDIO|WIN|SMART)_/ || diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go index c73cfe2f10b..a5d3ff8df95 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go @@ -2127,6 +2127,60 @@ const ( NFNL_SUBSYS_QUEUE = 0x3 NFNL_SUBSYS_ULOG = 0x4 NFS_SUPER_MAGIC = 0x6969 + NFT_CHAIN_FLAGS = 0x7 + NFT_CHAIN_MAXNAMELEN = 0x100 + NFT_CT_MAX = 0x17 + NFT_DATA_RESERVED_MASK = 0xffffff00 + NFT_DATA_VALUE_MAXLEN = 0x40 + NFT_EXTHDR_OP_MAX = 0x4 + NFT_FIB_RESULT_MAX = 0x3 + NFT_INNER_MASK = 0xf + NFT_LOGLEVEL_MAX = 0x8 + NFT_NAME_MAXLEN = 0x100 + NFT_NG_MAX = 0x1 + NFT_OBJECT_CONNLIMIT = 0x5 + NFT_OBJECT_COUNTER = 0x1 + NFT_OBJECT_CT_EXPECT = 0x9 + NFT_OBJECT_CT_HELPER = 0x3 + NFT_OBJECT_CT_TIMEOUT = 0x7 + NFT_OBJECT_LIMIT = 0x4 + NFT_OBJECT_MAX = 0xa + NFT_OBJECT_QUOTA = 0x2 + NFT_OBJECT_SECMARK = 0x8 + NFT_OBJECT_SYNPROXY = 0xa + NFT_OBJECT_TUNNEL = 0x6 + NFT_OBJECT_UNSPEC = 0x0 + NFT_OBJ_MAXNAMELEN = 0x100 + NFT_OSF_MAXGENRELEN = 0x10 + NFT_QUEUE_FLAG_BYPASS = 0x1 + NFT_QUEUE_FLAG_CPU_FANOUT = 0x2 + NFT_QUEUE_FLAG_MASK = 0x3 + NFT_REG32_COUNT = 0x10 + NFT_REG32_SIZE = 0x4 + NFT_REG_MAX = 0x4 + NFT_REG_SIZE = 0x10 + NFT_REJECT_ICMPX_MAX = 0x3 + NFT_RT_MAX = 0x4 + NFT_SECMARK_CTX_MAXLEN = 0x100 + NFT_SET_MAXNAMELEN = 0x100 + NFT_SOCKET_MAX = 0x3 + NFT_TABLE_F_MASK = 0x3 + NFT_TABLE_MAXNAMELEN = 0x100 + NFT_TRACETYPE_MAX = 0x3 + NFT_TUNNEL_F_MASK = 0x7 + NFT_TUNNEL_MAX = 0x1 + NFT_TUNNEL_MODE_MAX = 0x2 + NFT_USERDATA_MAXLEN = 0x100 + NFT_XFRM_KEY_MAX = 0x6 + NF_NAT_RANGE_MAP_IPS = 0x1 + NF_NAT_RANGE_MASK = 0x7f + NF_NAT_RANGE_NETMAP = 0x40 + NF_NAT_RANGE_PERSISTENT = 0x8 + NF_NAT_RANGE_PROTO_OFFSET = 0x20 + NF_NAT_RANGE_PROTO_RANDOM = 0x4 + NF_NAT_RANGE_PROTO_RANDOM_ALL = 0x14 + NF_NAT_RANGE_PROTO_RANDOM_FULLY = 0x10 + NF_NAT_RANGE_PROTO_SPECIFIED = 0x2 NILFS_SUPER_MAGIC = 0x3434 NL0 = 0x0 NL1 = 0x100 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go index a1d061597cc..9dc42410b78 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go index 5b2a7409778..0d3a0751cd4 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go index f6eda1344a8..c39f7776db3 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go index 55df20ae9d8..57571d072fe 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go index 8c1155cbc08..e62963e67e2 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go index 7cc80c58d98..00831354c82 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go index 0688737f494..79029ed5848 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go index 47dc5796769..ffb8708ccf8 100644 --- a/vendor/golang.org/x/sys/windows/syscall_windows.go +++ b/vendor/golang.org/x/sys/windows/syscall_windows.go @@ -194,6 +194,7 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys GetComputerName(buf *uint16, n *uint32) (err error) = GetComputerNameW //sys GetComputerNameEx(nametype uint32, buf *uint16, n *uint32) (err error) = GetComputerNameExW //sys SetEndOfFile(handle Handle) (err error) +//sys SetFileValidData(handle Handle, validDataLength int64) (err error) //sys GetSystemTimeAsFileTime(time *Filetime) //sys GetSystemTimePreciseAsFileTime(time *Filetime) //sys GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) [failretval==0xffffffff] diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go index 146a1f0196f..e8791c82c30 100644 --- a/vendor/golang.org/x/sys/windows/zsyscall_windows.go +++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go @@ -342,6 +342,7 @@ var ( procSetDefaultDllDirectories = modkernel32.NewProc("SetDefaultDllDirectories") procSetDllDirectoryW = modkernel32.NewProc("SetDllDirectoryW") procSetEndOfFile = modkernel32.NewProc("SetEndOfFile") + procSetFileValidData = modkernel32.NewProc("SetFileValidData") procSetEnvironmentVariableW = modkernel32.NewProc("SetEnvironmentVariableW") procSetErrorMode = modkernel32.NewProc("SetErrorMode") procSetEvent = modkernel32.NewProc("SetEvent") @@ -2988,6 +2989,14 @@ func SetEndOfFile(handle Handle) (err error) { return } +func SetFileValidData(handle Handle, validDataLength int64) (err error) { + r1, _, e1 := syscall.Syscall(procSetFileValidData.Addr(), 2, uintptr(handle), uintptr(validDataLength), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func SetEnvironmentVariable(name *uint16, value *uint16) (err error) { r1, _, e1 := syscall.Syscall(procSetEnvironmentVariableW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(value)), 0) if r1 == 0 { diff --git a/vendor/modules.txt b/vendor/modules.txt index 5ce8cbb4ebe..c86883d03c5 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -867,12 +867,12 @@ golang.org/x/net/trace ## explicit; go 1.18 golang.org/x/oauth2 golang.org/x/oauth2/internal -# golang.org/x/sync v0.5.0 +# golang.org/x/sync v0.6.0 ## explicit; go 1.18 golang.org/x/sync/errgroup golang.org/x/sync/semaphore golang.org/x/sync/singleflight -# golang.org/x/sys v0.15.0 +# golang.org/x/sys v0.16.0 ## explicit; go 1.18 golang.org/x/sys/plan9 golang.org/x/sys/unix