From 29679c8111adb410b002283967d73f946b16b52b Mon Sep 17 00:00:00 2001 From: Mike Cohen Date: Tue, 11 Apr 2023 21:44:28 +1000 Subject: [PATCH] Added a lockdown mode to the server config. (#2619) When a server is locked down certain permissions are removed (even from admins). The lockdown is set in the config file. This helps to mitigate the risk of a Velociraptor server admin account compromise. After initial deployment, the administrator can set the server in lockdown by adding the following config directive: lockdown: true to the server.config.yaml. After this the following permissions will be denied: - ARTIFACT_WRITER - SERVER_ARTIFACT_WRITER - EXECVE - SERVER_ADMIN - FILESYSTEM_WRITE - FILESYSTEM_READ - MACHINE_STATE During an active IR the server may be taken out of lockdown by removing the directive from the config file and restarting the service. Usually the config file is only writable by root and the Velociraptor server is running as a low privilege account which can not write to the config file. Also added Content-Length to VFS download handler. --- acls/lockdown.go | 24 +++ api/api.go | 54 +++--- api/artifacts.go | 4 +- api/clients.go | 10 +- api/datastore.go | 8 +- api/download.go | 54 ++++++ api/events.go | 2 +- api/hunts.go | 22 ++- api/notebooks.go | 21 +-- api/proto/api.pb.go | 4 +- api/proto/api.pb.gw.go | 50 +++--- api/proto/api_grpc.pb.go | 182 ++++++++++----------- api/reformat.go | 4 +- api/status.go | 9 + api/tools.go | 6 +- api/vfs.go | 4 +- config/proto/config.pb.go | 54 +++++- config/proto/config.proto | 20 +++ docs/references/server.config.yaml | 5 +- gui/velociraptor/src/components/i8n/en.jsx | 4 +- proto/flow_metadata.pb.go | 10 +- proto/semantic.pb.go | 28 ++-- services/acl_manager/acl_manager.go | 25 +++ services/launcher/acls.go | 12 +- services/sanity/lockdown.go | 47 ++++++ services/sanity/sanity.go | 5 + vql/acl_managers/server.go | 26 +++ vql/acls.go | 17 +- 28 files changed, 483 insertions(+), 228 deletions(-) create mode 100644 acls/lockdown.go create mode 100644 services/sanity/lockdown.go diff --git a/acls/lockdown.go b/acls/lockdown.go new file mode 100644 index 00000000000..b78dc036ada --- /dev/null +++ b/acls/lockdown.go @@ -0,0 +1,24 @@ +package acls + +import ( + "sync" + + acl_proto "www.velocidex.com/golang/velociraptor/acls/proto" +) + +var ( + mu sync.Mutex + lockdown_token *acl_proto.ApiClientACL +) + +func LockdownToken() *acl_proto.ApiClientACL { + mu.Lock() + defer mu.Unlock() + return lockdown_token +} + +func SetLockdownToken(token *acl_proto.ApiClientACL) { + mu.Lock() + defer mu.Unlock() + lockdown_token = token +} diff --git a/api/api.go b/api/api.go index a69480e41ca..b6ee72d8d5d 100644 --- a/api/api.go +++ b/api/api.go @@ -92,7 +92,7 @@ func (self *ApiServer) CancelFlow( perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to cancel flows.") } @@ -132,7 +132,7 @@ func (self *ApiServer) GetReport( permissions := acls.READ_RESULTS perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to view reports.") } @@ -182,7 +182,7 @@ func (self *ApiServer) CollectArtifact( perm, err := acl_manager.CheckAccess(permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to launch flows.") } } @@ -236,7 +236,7 @@ func (self *ApiServer) ListClients( permissions := acls.READ_RESULTS perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to view clients.") } @@ -279,7 +279,7 @@ func (self *ApiServer) NotifyClients( permissions := acls.COLLECT_CLIENT perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to launch flows.") } @@ -365,7 +365,7 @@ func (self *ApiServer) GetFlowDetails( permissions := acls.READ_RESULTS perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to launch flows.") } @@ -397,7 +397,7 @@ func (self *ApiServer) GetFlowRequests( permissions := acls.READ_RESULTS perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to view flows.") } @@ -494,7 +494,7 @@ func (self *ApiServer) VFSListDirectory( permissions := acls.READ_RESULTS perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to view the VFS.") } @@ -524,7 +524,7 @@ func (self *ApiServer) VFSStatDirectory( permissions := acls.READ_RESULTS perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to launch flows.") } @@ -554,7 +554,7 @@ func (self *ApiServer) VFSStatDownload( permissions := acls.READ_RESULTS perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to view the VFS.") } @@ -585,7 +585,7 @@ func (self *ApiServer) VFSRefreshDirectory( permissions := acls.COLLECT_CLIENT perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to launch flows.") } @@ -611,7 +611,7 @@ func (self *ApiServer) VFSGetBuffer( permissions := acls.READ_RESULTS perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to view the VFS.") } @@ -652,7 +652,7 @@ func (self *ApiServer) GetTable( permissions := acls.READ_RESULTS perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to view results.") } @@ -681,7 +681,7 @@ func (self *ApiServer) GetArtifacts( permissions := acls.READ_RESULTS perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to view custom artifacts.") } @@ -734,7 +734,7 @@ func (self *ApiServer) GetArtifactFile( permissions := acls.READ_RESULTS perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to view custom artifacts.") } @@ -787,8 +787,8 @@ func (self *ApiServer) SetArtifactFile( perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, fmt.Sprintf( - "User is not allowed to modify artifacts (%v).", permissions)) + return nil, PermissionDenied(err, + fmt.Sprintf("User is not allowed to modify artifacts (%v).", permissions)) } definition, err := setArtifactFile(ctx, org_config_obj, principal, in, "") @@ -873,8 +873,8 @@ func (self *ApiServer) GetServerMonitoringState( permissions := acls.READ_RESULTS perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, fmt.Sprintf( - "User is not allowed to read results (%v).", permissions)) + return nil, PermissionDenied(err, + fmt.Sprintf("User is not allowed to read results (%v).", permissions)) } result, err := getServerMonitoringState(org_config_obj) @@ -900,8 +900,8 @@ func (self *ApiServer) SetServerMonitoringState( permissions := acls.COLLECT_SERVER perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, fmt.Sprintf( - "User is not allowed to modify artifacts (%v).", permissions)) + return nil, PermissionDenied(err, + fmt.Sprintf("User is not allowed to modify artifacts (%v).", permissions)) } err = setServerMonitoringState(org_config_obj, principal, in) @@ -924,8 +924,8 @@ func (self *ApiServer) GetClientMonitoringState( permissions := acls.READ_RESULTS perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, fmt.Sprintf( - "User is not allowed to read monitoring artifacts (%v).", permissions)) + return nil, PermissionDenied(err, + fmt.Sprintf("User is not allowed to read monitoring artifacts (%v).", permissions)) } manager, err := services.ClientEventManager(org_config_obj) @@ -959,8 +959,8 @@ func (self *ApiServer) SetClientMonitoringState( permissions := acls.COLLECT_CLIENT perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, fmt.Sprintf( - "User is not allowed to modify monitoring artifacts (%v).", permissions)) + return nil, PermissionDenied(err, + fmt.Sprintf("User is not allowed to modify monitoring artifacts (%v).", permissions)) } manager, err := services.ClientEventManager(org_config_obj) @@ -991,8 +991,8 @@ func (self *ApiServer) CreateDownloadFile(ctx context.Context, permissions := acls.PREPARE_RESULTS perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, fmt.Sprintf( - "User is not allowed to create downloads (%v).", permissions)) + return nil, PermissionDenied(err, + fmt.Sprintf("User is not allowed to create downloads (%v).", permissions)) } // Log an audit event. diff --git a/api/artifacts.go b/api/artifacts.go index 42f17fdd9ae..8a87b1161e3 100644 --- a/api/artifacts.go +++ b/api/artifacts.go @@ -25,8 +25,6 @@ import ( "github.com/sirupsen/logrus" context "golang.org/x/net/context" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" "www.velocidex.com/golang/velociraptor/acls" actions_proto "www.velocidex.com/golang/velociraptor/actions/proto" api_proto "www.velocidex.com/golang/velociraptor/api/proto" @@ -314,7 +312,7 @@ func (self *ApiServer) LoadArtifactPack( permissions := acls.SERVER_ARTIFACT_WRITER perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to upload artifact packs.") } diff --git a/api/clients.go b/api/clients.go index ee71e91a113..5c18cf4a199 100644 --- a/api/clients.go +++ b/api/clients.go @@ -25,8 +25,6 @@ import ( "time" "github.com/Velocidex/ordereddict" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/emptypb" "www.velocidex.com/golang/velociraptor/acls" api_proto "www.velocidex.com/golang/velociraptor/api/proto" @@ -54,7 +52,7 @@ func (self *ApiServer) GetClientMetadata( perm, err := services.CheckAccess(org_config_obj, user_name, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to view clients.") } @@ -87,7 +85,7 @@ func (self *ApiServer) SetClientMetadata( permissions := acls.LABEL_CLIENT perm, err := services.CheckAccess(org_config_obj, user_name, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to modify client labels.") } @@ -126,7 +124,7 @@ func (self *ApiServer) GetClient( permissions := acls.READ_RESULTS perm, err := services.CheckAccess(org_config_obj, user_name, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to view clients.") } @@ -179,7 +177,7 @@ func (self *ApiServer) GetClientFlows( permissions := acls.READ_RESULTS perm, err := services.CheckAccess(org_config_obj, user_name, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to view flows.") } diff --git a/api/datastore.go b/api/datastore.go index 8212494a247..11bd1aca5a7 100644 --- a/api/datastore.go +++ b/api/datastore.go @@ -36,7 +36,7 @@ func (self *ApiServer) GetSubject( perm, err := services.CheckAccessWithToken(token, acls.DATASTORE_ACCESS) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to access datastore.") } @@ -88,7 +88,7 @@ func (self *ApiServer) SetSubject( perm, err := services.CheckAccessWithToken(token, acls.DATASTORE_ACCESS) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to access datastore.") } @@ -152,7 +152,7 @@ func (self *ApiServer) ListChildren( perm, err := services.CheckAccessWithToken(token, acls.DATASTORE_ACCESS) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to access datastore.") } @@ -211,7 +211,7 @@ func (self *ApiServer) DeleteSubject( perm, err := services.CheckAccessWithToken(token, acls.DATASTORE_ACCESS) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to access datastore.") } diff --git a/api/download.go b/api/download.go index aa3fb07346f..48a8e87a8b3 100644 --- a/api/download.go +++ b/api/download.go @@ -27,6 +27,7 @@ package api import ( "bytes" + "fmt" "html" "io" "io/ioutil" @@ -178,7 +179,14 @@ func vfsFileDownloadHandler() http.Handler { return } + // We need to figure out the total size of the upload to set + // in the Content Length header. There are three + // possibilities: + // 1. The file is not sparse + // 2. The file is sparse and we are not padding. + // 3. The file is sparse and we are padding it. var reader_at io.ReaderAt = utils.MakeReaderAtter(file) + var total_size int index, err := getIndex(org_config_obj, path_spec) @@ -193,8 +201,14 @@ func vfsFileDownloadHandler() http.Handler { ReaderAt: reader_at, Index: index, } + + total_size = calculateTotalSizeWithPadding(index) + } else { + total_size = calculateTotalReaderSize(file) } + emitContentLength(w, int(request.Offset), int(request.Length), total_size) + offset := request.Offset // Read the first buffer now so we can report errors @@ -582,3 +596,43 @@ func filterColumns(columns []string, row *ordereddict.Dict) *ordereddict.Dict { } return new_row } + +func calculateTotalSizeWithPadding(index *actions_proto.Index) int { + size := 0 + for _, r := range index.Ranges { + size += int(r.Length) + } + return size +} + +func calculateTotalReaderSize(reader api.FileReader) int { + stat, err := reader.Stat() + if err == nil { + return int(stat.Size()) + } + return 0 +} + +func emitContentLength(w http.ResponseWriter, offset int, req_length int, size int) { + // Size is not known or 0, do not send a Content Length + if size == 0 || offset > size { + return + } + + // How much data is available to read in the file. + available := size - offset + + // If the user asked for less data than is available, then we will + // return less, otherwise we only return how much data is + // available. + if req_length > BUFSIZE { + req_length = BUFSIZE + } + + // req_length of 0 means download the entire file without byte ranges. + if req_length > 0 && req_length < available { + available = req_length + } + + w.Header().Set("Content-Length", fmt.Sprintf("%v", available)) +} diff --git a/api/events.go b/api/events.go index b28f164fd77..d34e2d37b66 100644 --- a/api/events.go +++ b/api/events.go @@ -146,7 +146,7 @@ func (self *ApiServer) ListAvailableEventResults( permissions := acls.READ_RESULTS perm, err := services.CheckAccess(org_config_obj, user_record.Name, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to view results.") } diff --git a/api/hunts.go b/api/hunts.go index cce156a3ac5..af7ddcd6136 100644 --- a/api/hunts.go +++ b/api/hunts.go @@ -35,7 +35,7 @@ func (self *ApiServer) GetHuntFlows( permissions := acls.READ_RESULTS perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to view hunt results.") } @@ -120,7 +120,7 @@ func (self *ApiServer) CreateHunt( perm, err := services.CheckAccess(org_config_obj, in.Creator, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to launch hunts.") } @@ -131,7 +131,7 @@ func (self *ApiServer) CreateHunt( permissions := acls.ORG_ADMIN perm, err := services.CheckAccess(org_config_obj, in.Creator, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to launch hunts in other orgs.") } } else { @@ -156,7 +156,11 @@ func (self *ApiServer) CreateHunt( // Make sure the user is allowed to collect in that org perm, err := services.CheckAccess( org_config_obj, in.Creator, permissions) - if !perm || err != nil { + if !perm { + if err != nil { + logger.Error("%v: CreateHunt: User is not allowed to launch hunts in "+ + "org %v.", err, org_id) + } logger.Error("CreateHunt: User is not allowed to launch hunts in "+ "org %v.", org_id) continue @@ -219,7 +223,7 @@ func (self *ApiServer) ModifyHunt( perm, err := services.CheckAccess(org_config_obj, in.Creator, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to modify hunts.") } @@ -259,7 +263,7 @@ func (self *ApiServer) ListHunts( permissions := acls.READ_RESULTS perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to view hunts.") } @@ -315,7 +319,7 @@ func (self *ApiServer) GetHunt( permissions := acls.READ_RESULTS perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to view hunts.") } @@ -348,7 +352,7 @@ func (self *ApiServer) GetHuntResults( permissions := acls.READ_RESULTS perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to view results.") } @@ -384,7 +388,7 @@ func (self *ApiServer) EstimateHunt( permissions := acls.READ_RESULTS perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to view hunt results.") } diff --git a/api/notebooks.go b/api/notebooks.go index 3e4facbb937..df21e1c86e2 100644 --- a/api/notebooks.go +++ b/api/notebooks.go @@ -12,8 +12,6 @@ import ( errors "github.com/go-errors/errors" "github.com/sirupsen/logrus" context "golang.org/x/net/context" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/emptypb" "www.velocidex.com/golang/velociraptor/acls" api_proto "www.velocidex.com/golang/velociraptor/api/proto" @@ -47,8 +45,7 @@ func (self *ApiServer) GetNotebooks( permissions := acls.READ_RESULTS perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, - "User is not allowed to read notebooks.") + return nil, PermissionDenied(err, "User is not allowed to read notebooks.") } result := &api_proto.Notebooks{} @@ -116,7 +113,7 @@ func (self *ApiServer) NewNotebook( permissions := acls.NOTEBOOK_EDITOR perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to create notebooks.") } @@ -149,7 +146,7 @@ func (self *ApiServer) NewNotebookCell( permissions := acls.NOTEBOOK_EDITOR perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to edit notebooks.") } @@ -180,7 +177,7 @@ func (self *ApiServer) UpdateNotebook( permissions := acls.NOTEBOOK_EDITOR perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to edit notebooks.") } @@ -248,7 +245,7 @@ func (self *ApiServer) GetNotebookCell( permissions := acls.READ_RESULTS perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to read notebooks.") } @@ -293,7 +290,7 @@ func (self *ApiServer) UpdateNotebookCell( permissions := acls.NOTEBOOK_EDITOR perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to edit notebooks.") } @@ -340,7 +337,7 @@ func (self *ApiServer) CancelNotebookCell( permissions := acls.NOTEBOOK_EDITOR perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to edit notebooks.") } @@ -369,7 +366,7 @@ func (self *ApiServer) UploadNotebookAttachment( permissions := acls.NOTEBOOK_EDITOR perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to edit notebooks.") } @@ -396,7 +393,7 @@ func (self *ApiServer) CreateNotebookDownloadFile( permissions := acls.PREPARE_RESULTS perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to export notebooks.") } diff --git a/api/proto/api.pb.go b/api/proto/api.pb.go index 6b00472824a..e0baedc4532 100644 --- a/api/proto/api.pb.go +++ b/api/proto/api.pb.go @@ -4,10 +4,10 @@ package proto import ( + empty "github.com/golang/protobuf/ptypes/empty" _ "google.golang.org/genproto/googleapis/api/annotations" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - emptypb "google.golang.org/protobuf/types/known/emptypb" reflect "reflect" sync "sync" proto2 "www.velocidex.com/golang/velociraptor/actions/proto" @@ -1120,7 +1120,7 @@ var file_api_proto_goTypes = []interface{}{ (*GetClientRequest)(nil), // 17: proto.GetClientRequest (*SetClientMetadataRequest)(nil), // 18: proto.SetClientMetadataRequest (*ApiFlowRequest)(nil), // 19: proto.ApiFlowRequest - (*emptypb.Empty)(nil), // 20: google.protobuf.Empty + (*empty.Empty)(nil), // 20: google.protobuf.Empty (*SetGUIOptionsRequest)(nil), // 21: proto.SetGUIOptionsRequest (*UserRequest)(nil), // 22: proto.UserRequest (*UserRoles)(nil), // 23: proto.UserRoles diff --git a/api/proto/api.pb.gw.go b/api/proto/api.pb.gw.go index aafdb1ea5e3..bcdd206ed09 100644 --- a/api/proto/api.pb.gw.go +++ b/api/proto/api.pb.gw.go @@ -13,6 +13,7 @@ import ( "io" "net/http" + "github.com/golang/protobuf/ptypes/empty" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" "google.golang.org/grpc" @@ -21,9 +22,8 @@ import ( "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/types/known/emptypb" - proto_1 "www.velocidex.com/golang/velociraptor/artifacts/proto" - proto_5 "www.velocidex.com/golang/velociraptor/flows/proto" + proto_6 "www.velocidex.com/golang/velociraptor/artifacts/proto" + proto_1 "www.velocidex.com/golang/velociraptor/flows/proto" ) // Suppress "imported and not used" errors @@ -699,7 +699,7 @@ func local_request_API_GetClientFlows_1(ctx context.Context, marshaler runtime.M } func request_API_GetUserUITraits_0(ctx context.Context, marshaler runtime.Marshaler, client APIClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq emptypb.Empty + var protoReq empty.Empty var metadata runtime.ServerMetadata msg, err := client.GetUserUITraits(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -708,7 +708,7 @@ func request_API_GetUserUITraits_0(ctx context.Context, marshaler runtime.Marsha } func local_request_API_GetUserUITraits_0(ctx context.Context, marshaler runtime.Marshaler, server APIServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq emptypb.Empty + var protoReq empty.Empty var metadata runtime.ServerMetadata msg, err := server.GetUserUITraits(ctx, &protoReq) @@ -751,7 +751,7 @@ func local_request_API_SetGUIOptions_0(ctx context.Context, marshaler runtime.Ma } func request_API_GetUsers_0(ctx context.Context, marshaler runtime.Marshaler, client APIClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq emptypb.Empty + var protoReq empty.Empty var metadata runtime.ServerMetadata msg, err := client.GetUsers(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -760,7 +760,7 @@ func request_API_GetUsers_0(ctx context.Context, marshaler runtime.Marshaler, cl } func local_request_API_GetUsers_0(ctx context.Context, marshaler runtime.Marshaler, server APIServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq emptypb.Empty + var protoReq empty.Empty var metadata runtime.ServerMetadata msg, err := server.GetUsers(ctx, &protoReq) @@ -769,7 +769,7 @@ func local_request_API_GetUsers_0(ctx context.Context, marshaler runtime.Marshal } func request_API_GetGlobalUsers_0(ctx context.Context, marshaler runtime.Marshaler, client APIClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq emptypb.Empty + var protoReq empty.Empty var metadata runtime.ServerMetadata msg, err := client.GetGlobalUsers(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -778,7 +778,7 @@ func request_API_GetGlobalUsers_0(ctx context.Context, marshaler runtime.Marshal } func local_request_API_GetGlobalUsers_0(ctx context.Context, marshaler runtime.Marshaler, server APIServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq emptypb.Empty + var protoReq empty.Empty var metadata runtime.ServerMetadata msg, err := server.GetGlobalUsers(ctx, &protoReq) @@ -1279,7 +1279,7 @@ func local_request_API_GetTable_0(ctx context.Context, marshaler runtime.Marshal } func request_API_CollectArtifact_0(ctx context.Context, marshaler runtime.Marshaler, client APIClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq proto_5.ArtifactCollectorArgs + var protoReq proto_1.ArtifactCollectorArgs var metadata runtime.ServerMetadata newReader, berr := utilities.IOReaderFactory(req.Body) @@ -1296,7 +1296,7 @@ func request_API_CollectArtifact_0(ctx context.Context, marshaler runtime.Marsha } func local_request_API_CollectArtifact_0(ctx context.Context, marshaler runtime.Marshaler, server APIServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq proto_5.ArtifactCollectorArgs + var protoReq proto_1.ArtifactCollectorArgs var metadata runtime.ServerMetadata newReader, berr := utilities.IOReaderFactory(req.Body) @@ -1419,7 +1419,7 @@ func local_request_API_GetFlowRequests_0(ctx context.Context, marshaler runtime. } func request_API_GetKeywordCompletions_0(ctx context.Context, marshaler runtime.Marshaler, client APIClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq emptypb.Empty + var protoReq empty.Empty var metadata runtime.ServerMetadata msg, err := client.GetKeywordCompletions(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -1428,7 +1428,7 @@ func request_API_GetKeywordCompletions_0(ctx context.Context, marshaler runtime. } func local_request_API_GetKeywordCompletions_0(ctx context.Context, marshaler runtime.Marshaler, server APIServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq emptypb.Empty + var protoReq empty.Empty var metadata runtime.ServerMetadata msg, err := server.GetKeywordCompletions(ctx, &protoReq) @@ -1613,7 +1613,7 @@ var ( ) func request_API_GetToolInfo_0(ctx context.Context, marshaler runtime.Marshaler, client APIClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq proto_1.Tool + var protoReq proto_6.Tool var metadata runtime.ServerMetadata if err := req.ParseForm(); err != nil { @@ -1629,7 +1629,7 @@ func request_API_GetToolInfo_0(ctx context.Context, marshaler runtime.Marshaler, } func local_request_API_GetToolInfo_0(ctx context.Context, marshaler runtime.Marshaler, server APIServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq proto_1.Tool + var protoReq proto_6.Tool var metadata runtime.ServerMetadata if err := req.ParseForm(); err != nil { @@ -1645,7 +1645,7 @@ func local_request_API_GetToolInfo_0(ctx context.Context, marshaler runtime.Mars } func request_API_SetToolInfo_0(ctx context.Context, marshaler runtime.Marshaler, client APIClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq proto_1.Tool + var protoReq proto_6.Tool var metadata runtime.ServerMetadata newReader, berr := utilities.IOReaderFactory(req.Body) @@ -1662,7 +1662,7 @@ func request_API_SetToolInfo_0(ctx context.Context, marshaler runtime.Marshaler, } func local_request_API_SetToolInfo_0(ctx context.Context, marshaler runtime.Marshaler, server APIServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq proto_1.Tool + var protoReq proto_6.Tool var metadata runtime.ServerMetadata newReader, berr := utilities.IOReaderFactory(req.Body) @@ -1713,7 +1713,7 @@ func local_request_API_GetReport_0(ctx context.Context, marshaler runtime.Marsha } func request_API_GetServerMonitoringState_0(ctx context.Context, marshaler runtime.Marshaler, client APIClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq emptypb.Empty + var protoReq empty.Empty var metadata runtime.ServerMetadata msg, err := client.GetServerMonitoringState(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -1722,7 +1722,7 @@ func request_API_GetServerMonitoringState_0(ctx context.Context, marshaler runti } func local_request_API_GetServerMonitoringState_0(ctx context.Context, marshaler runtime.Marshaler, server APIServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq emptypb.Empty + var protoReq empty.Empty var metadata runtime.ServerMetadata msg, err := server.GetServerMonitoringState(ctx, &protoReq) @@ -1731,7 +1731,7 @@ func local_request_API_GetServerMonitoringState_0(ctx context.Context, marshaler } func request_API_SetServerMonitoringState_0(ctx context.Context, marshaler runtime.Marshaler, client APIClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq proto_5.ArtifactCollectorArgs + var protoReq proto_1.ArtifactCollectorArgs var metadata runtime.ServerMetadata newReader, berr := utilities.IOReaderFactory(req.Body) @@ -1748,7 +1748,7 @@ func request_API_SetServerMonitoringState_0(ctx context.Context, marshaler runti } func local_request_API_SetServerMonitoringState_0(ctx context.Context, marshaler runtime.Marshaler, server APIServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq proto_5.ArtifactCollectorArgs + var protoReq proto_1.ArtifactCollectorArgs var metadata runtime.ServerMetadata newReader, berr := utilities.IOReaderFactory(req.Body) @@ -1769,7 +1769,7 @@ var ( ) func request_API_GetClientMonitoringState_0(ctx context.Context, marshaler runtime.Marshaler, client APIClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq proto_5.GetClientMonitoringStateRequest + var protoReq proto_1.GetClientMonitoringStateRequest var metadata runtime.ServerMetadata if err := req.ParseForm(); err != nil { @@ -1785,7 +1785,7 @@ func request_API_GetClientMonitoringState_0(ctx context.Context, marshaler runti } func local_request_API_GetClientMonitoringState_0(ctx context.Context, marshaler runtime.Marshaler, server APIServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq proto_5.GetClientMonitoringStateRequest + var protoReq proto_1.GetClientMonitoringStateRequest var metadata runtime.ServerMetadata if err := req.ParseForm(); err != nil { @@ -1801,7 +1801,7 @@ func local_request_API_GetClientMonitoringState_0(ctx context.Context, marshaler } func request_API_SetClientMonitoringState_0(ctx context.Context, marshaler runtime.Marshaler, client APIClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq proto_5.ClientEventTable + var protoReq proto_1.ClientEventTable var metadata runtime.ServerMetadata newReader, berr := utilities.IOReaderFactory(req.Body) @@ -1818,7 +1818,7 @@ func request_API_SetClientMonitoringState_0(ctx context.Context, marshaler runti } func local_request_API_SetClientMonitoringState_0(ctx context.Context, marshaler runtime.Marshaler, server APIServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq proto_5.ClientEventTable + var protoReq proto_1.ClientEventTable var metadata runtime.ServerMetadata newReader, berr := utilities.IOReaderFactory(req.Body) diff --git a/api/proto/api_grpc.pb.go b/api/proto/api_grpc.pb.go index 6538be66db6..f0ce53e4479 100644 --- a/api/proto/api_grpc.pb.go +++ b/api/proto/api_grpc.pb.go @@ -4,10 +4,10 @@ package proto import ( context "context" + empty "github.com/golang/protobuf/ptypes/empty" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" - emptypb "google.golang.org/protobuf/types/known/emptypb" proto2 "www.velocidex.com/golang/velociraptor/actions/proto" proto1 "www.velocidex.com/golang/velociraptor/artifacts/proto" proto "www.velocidex.com/golang/velociraptor/flows/proto" @@ -29,30 +29,30 @@ type APIClient interface { EstimateHunt(ctx context.Context, in *HuntEstimateRequest, opts ...grpc.CallOption) (*HuntStats, error) ListHunts(ctx context.Context, in *ListHuntsRequest, opts ...grpc.CallOption) (*ListHuntsResponse, error) GetHunt(ctx context.Context, in *GetHuntRequest, opts ...grpc.CallOption) (*Hunt, error) - ModifyHunt(ctx context.Context, in *Hunt, opts ...grpc.CallOption) (*emptypb.Empty, error) + ModifyHunt(ctx context.Context, in *Hunt, opts ...grpc.CallOption) (*empty.Empty, error) GetHuntFlows(ctx context.Context, in *GetTableRequest, opts ...grpc.CallOption) (*GetTableResponse, error) GetHuntResults(ctx context.Context, in *GetHuntResultsRequest, opts ...grpc.CallOption) (*GetTableResponse, error) // Clients. - NotifyClients(ctx context.Context, in *NotificationRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + NotifyClients(ctx context.Context, in *NotificationRequest, opts ...grpc.CallOption) (*empty.Empty, error) LabelClients(ctx context.Context, in *LabelClientsRequest, opts ...grpc.CallOption) (*APIResponse, error) ListClients(ctx context.Context, in *SearchClientsRequest, opts ...grpc.CallOption) (*SearchClientsResponse, error) GetClient(ctx context.Context, in *GetClientRequest, opts ...grpc.CallOption) (*ApiClient, error) GetClientMetadata(ctx context.Context, in *GetClientRequest, opts ...grpc.CallOption) (*ClientMetadata, error) - SetClientMetadata(ctx context.Context, in *SetClientMetadataRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + SetClientMetadata(ctx context.Context, in *SetClientMetadataRequest, opts ...grpc.CallOption) (*empty.Empty, error) GetClientFlows(ctx context.Context, in *ApiFlowRequest, opts ...grpc.CallOption) (*ApiFlowResponse, error) // Users - GetUserUITraits(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*ApiUser, error) + GetUserUITraits(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*ApiUser, error) SetGUIOptions(ctx context.Context, in *SetGUIOptionsRequest, opts ...grpc.CallOption) (*SetGUIOptionsResponse, error) // List all the GUI users known on this server. - GetUsers(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*Users, error) + GetUsers(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*Users, error) // List all the GUI users in orgs in which we are a member - GetGlobalUsers(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*Users, error) + GetGlobalUsers(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*Users, error) GetUserRoles(ctx context.Context, in *UserRequest, opts ...grpc.CallOption) (*UserRoles, error) - SetUserRoles(ctx context.Context, in *UserRoles, opts ...grpc.CallOption) (*emptypb.Empty, error) + SetUserRoles(ctx context.Context, in *UserRoles, opts ...grpc.CallOption) (*empty.Empty, error) GetUser(ctx context.Context, in *UserRequest, opts ...grpc.CallOption) (*VelociraptorUser, error) - CreateUser(ctx context.Context, in *UpdateUserRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + CreateUser(ctx context.Context, in *UpdateUserRequest, opts ...grpc.CallOption) (*empty.Empty, error) GetUserFavorites(ctx context.Context, in *Favorite, opts ...grpc.CallOption) (*Favorites, error) - SetPassword(ctx context.Context, in *SetPasswordRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + SetPassword(ctx context.Context, in *SetPasswordRequest, opts ...grpc.CallOption) (*empty.Empty, error) // VFS VFSListDirectory(ctx context.Context, in *VFSListRequest, opts ...grpc.CallOption) (*VFSListResponse, error) VFSListDirectoryFiles(ctx context.Context, in *GetTableRequest, opts ...grpc.CallOption) (*GetTableResponse, error) @@ -66,7 +66,7 @@ type APIClient interface { GetFlowDetails(ctx context.Context, in *ApiFlowRequest, opts ...grpc.CallOption) (*FlowDetails, error) GetFlowRequests(ctx context.Context, in *ApiFlowRequest, opts ...grpc.CallOption) (*ApiFlowRequestDetails, error) // VQL assistance - GetKeywordCompletions(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*KeywordCompletions, error) + GetKeywordCompletions(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*KeywordCompletions, error) ReformatVQL(ctx context.Context, in *ReformatVQLMessage, opts ...grpc.CallOption) (*ReformatVQLMessage, error) // Artifacts GetArtifacts(ctx context.Context, in *GetArtifactsRequest, opts ...grpc.CallOption) (*proto1.ArtifactDescriptors, error) @@ -80,7 +80,7 @@ type APIClient interface { GetReport(ctx context.Context, in *GetReportRequest, opts ...grpc.CallOption) (*GetReportResponse, error) // Server Monitoring Artifacts - manage the Server Monitoring // Service.. - GetServerMonitoringState(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*proto.ArtifactCollectorArgs, error) + GetServerMonitoringState(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*proto.ArtifactCollectorArgs, error) // Server Monitoring Artifacts - manage the Server Monitoring // Service. SetServerMonitoringState(ctx context.Context, in *proto.ArtifactCollectorArgs, opts ...grpc.CallOption) (*proto.ArtifactCollectorArgs, error) @@ -89,7 +89,7 @@ type APIClient interface { GetClientMonitoringState(ctx context.Context, in *proto.GetClientMonitoringStateRequest, opts ...grpc.CallOption) (*proto.ClientEventTable, error) // Client Monitoring Artifacts - manage the Client Monitoring // Service. - SetClientMonitoringState(ctx context.Context, in *proto.ClientEventTable, opts ...grpc.CallOption) (*emptypb.Empty, error) + SetClientMonitoringState(ctx context.Context, in *proto.ClientEventTable, opts ...grpc.CallOption) (*empty.Empty, error) ListAvailableEventResults(ctx context.Context, in *ListAvailableEventResultsRequest, opts ...grpc.CallOption) (*ListAvailableEventResultsResponse, error) // Schedule downloads. CreateDownloadFile(ctx context.Context, in *CreateDownloadRequest, opts ...grpc.CallOption) (*CreateDownloadResponse, error) @@ -100,8 +100,8 @@ type APIClient interface { NewNotebookCell(ctx context.Context, in *NotebookCellRequest, opts ...grpc.CallOption) (*NotebookMetadata, error) GetNotebookCell(ctx context.Context, in *NotebookCellRequest, opts ...grpc.CallOption) (*NotebookCell, error) UpdateNotebookCell(ctx context.Context, in *NotebookCellRequest, opts ...grpc.CallOption) (*NotebookCell, error) - CancelNotebookCell(ctx context.Context, in *NotebookCellRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) - CreateNotebookDownloadFile(ctx context.Context, in *NotebookExportRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + CancelNotebookCell(ctx context.Context, in *NotebookCellRequest, opts ...grpc.CallOption) (*empty.Empty, error) + CreateNotebookDownloadFile(ctx context.Context, in *NotebookExportRequest, opts ...grpc.CallOption) (*empty.Empty, error) UploadNotebookAttachment(ctx context.Context, in *NotebookFileUploadRequest, opts ...grpc.CallOption) (*NotebookFileUploadResponse, error) // This can be used by API clients to fetch file content. VFSGetBuffer(ctx context.Context, in *VFSFileBuffer, opts ...grpc.CallOption) (*VFSFileBuffer, error) @@ -110,13 +110,13 @@ type APIClient interface { // Watch for events from the master. WatchEvent(ctx context.Context, in *EventRequest, opts ...grpc.CallOption) (API_WatchEventClient, error) // Push the events to the master - PushEvents(ctx context.Context, in *PushEventRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + PushEvents(ctx context.Context, in *PushEventRequest, opts ...grpc.CallOption) (*empty.Empty, error) // Push monitoring event to the server. - WriteEvent(ctx context.Context, in *proto2.VQLResponse, opts ...grpc.CallOption) (*emptypb.Empty, error) + WriteEvent(ctx context.Context, in *proto2.VQLResponse, opts ...grpc.CallOption) (*empty.Empty, error) // Remote data store access. GetSubject(ctx context.Context, in *DataRequest, opts ...grpc.CallOption) (*DataResponse, error) SetSubject(ctx context.Context, in *DataRequest, opts ...grpc.CallOption) (*DataResponse, error) - DeleteSubject(ctx context.Context, in *DataRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + DeleteSubject(ctx context.Context, in *DataRequest, opts ...grpc.CallOption) (*empty.Empty, error) ListChildren(ctx context.Context, in *DataRequest, opts ...grpc.CallOption) (*ListChildrenResponse, error) // Health check protocol as in https://github.com/grpc/grpc/blob/master/doc/health-checking.md Check(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (*HealthCheckResponse, error) @@ -166,8 +166,8 @@ func (c *aPIClient) GetHunt(ctx context.Context, in *GetHuntRequest, opts ...grp return out, nil } -func (c *aPIClient) ModifyHunt(ctx context.Context, in *Hunt, opts ...grpc.CallOption) (*emptypb.Empty, error) { - out := new(emptypb.Empty) +func (c *aPIClient) ModifyHunt(ctx context.Context, in *Hunt, opts ...grpc.CallOption) (*empty.Empty, error) { + out := new(empty.Empty) err := c.cc.Invoke(ctx, "/proto.API/ModifyHunt", in, out, opts...) if err != nil { return nil, err @@ -193,8 +193,8 @@ func (c *aPIClient) GetHuntResults(ctx context.Context, in *GetHuntResultsReques return out, nil } -func (c *aPIClient) NotifyClients(ctx context.Context, in *NotificationRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { - out := new(emptypb.Empty) +func (c *aPIClient) NotifyClients(ctx context.Context, in *NotificationRequest, opts ...grpc.CallOption) (*empty.Empty, error) { + out := new(empty.Empty) err := c.cc.Invoke(ctx, "/proto.API/NotifyClients", in, out, opts...) if err != nil { return nil, err @@ -238,8 +238,8 @@ func (c *aPIClient) GetClientMetadata(ctx context.Context, in *GetClientRequest, return out, nil } -func (c *aPIClient) SetClientMetadata(ctx context.Context, in *SetClientMetadataRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { - out := new(emptypb.Empty) +func (c *aPIClient) SetClientMetadata(ctx context.Context, in *SetClientMetadataRequest, opts ...grpc.CallOption) (*empty.Empty, error) { + out := new(empty.Empty) err := c.cc.Invoke(ctx, "/proto.API/SetClientMetadata", in, out, opts...) if err != nil { return nil, err @@ -256,7 +256,7 @@ func (c *aPIClient) GetClientFlows(ctx context.Context, in *ApiFlowRequest, opts return out, nil } -func (c *aPIClient) GetUserUITraits(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*ApiUser, error) { +func (c *aPIClient) GetUserUITraits(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*ApiUser, error) { out := new(ApiUser) err := c.cc.Invoke(ctx, "/proto.API/GetUserUITraits", in, out, opts...) if err != nil { @@ -274,7 +274,7 @@ func (c *aPIClient) SetGUIOptions(ctx context.Context, in *SetGUIOptionsRequest, return out, nil } -func (c *aPIClient) GetUsers(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*Users, error) { +func (c *aPIClient) GetUsers(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*Users, error) { out := new(Users) err := c.cc.Invoke(ctx, "/proto.API/GetUsers", in, out, opts...) if err != nil { @@ -283,7 +283,7 @@ func (c *aPIClient) GetUsers(ctx context.Context, in *emptypb.Empty, opts ...grp return out, nil } -func (c *aPIClient) GetGlobalUsers(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*Users, error) { +func (c *aPIClient) GetGlobalUsers(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*Users, error) { out := new(Users) err := c.cc.Invoke(ctx, "/proto.API/GetGlobalUsers", in, out, opts...) if err != nil { @@ -301,8 +301,8 @@ func (c *aPIClient) GetUserRoles(ctx context.Context, in *UserRequest, opts ...g return out, nil } -func (c *aPIClient) SetUserRoles(ctx context.Context, in *UserRoles, opts ...grpc.CallOption) (*emptypb.Empty, error) { - out := new(emptypb.Empty) +func (c *aPIClient) SetUserRoles(ctx context.Context, in *UserRoles, opts ...grpc.CallOption) (*empty.Empty, error) { + out := new(empty.Empty) err := c.cc.Invoke(ctx, "/proto.API/SetUserRoles", in, out, opts...) if err != nil { return nil, err @@ -319,8 +319,8 @@ func (c *aPIClient) GetUser(ctx context.Context, in *UserRequest, opts ...grpc.C return out, nil } -func (c *aPIClient) CreateUser(ctx context.Context, in *UpdateUserRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { - out := new(emptypb.Empty) +func (c *aPIClient) CreateUser(ctx context.Context, in *UpdateUserRequest, opts ...grpc.CallOption) (*empty.Empty, error) { + out := new(empty.Empty) err := c.cc.Invoke(ctx, "/proto.API/CreateUser", in, out, opts...) if err != nil { return nil, err @@ -337,8 +337,8 @@ func (c *aPIClient) GetUserFavorites(ctx context.Context, in *Favorite, opts ... return out, nil } -func (c *aPIClient) SetPassword(ctx context.Context, in *SetPasswordRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { - out := new(emptypb.Empty) +func (c *aPIClient) SetPassword(ctx context.Context, in *SetPasswordRequest, opts ...grpc.CallOption) (*empty.Empty, error) { + out := new(empty.Empty) err := c.cc.Invoke(ctx, "/proto.API/SetPassword", in, out, opts...) if err != nil { return nil, err @@ -436,7 +436,7 @@ func (c *aPIClient) GetFlowRequests(ctx context.Context, in *ApiFlowRequest, opt return out, nil } -func (c *aPIClient) GetKeywordCompletions(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*KeywordCompletions, error) { +func (c *aPIClient) GetKeywordCompletions(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*KeywordCompletions, error) { out := new(KeywordCompletions) err := c.cc.Invoke(ctx, "/proto.API/GetKeywordCompletions", in, out, opts...) if err != nil { @@ -517,7 +517,7 @@ func (c *aPIClient) GetReport(ctx context.Context, in *GetReportRequest, opts .. return out, nil } -func (c *aPIClient) GetServerMonitoringState(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*proto.ArtifactCollectorArgs, error) { +func (c *aPIClient) GetServerMonitoringState(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*proto.ArtifactCollectorArgs, error) { out := new(proto.ArtifactCollectorArgs) err := c.cc.Invoke(ctx, "/proto.API/GetServerMonitoringState", in, out, opts...) if err != nil { @@ -544,8 +544,8 @@ func (c *aPIClient) GetClientMonitoringState(ctx context.Context, in *proto.GetC return out, nil } -func (c *aPIClient) SetClientMonitoringState(ctx context.Context, in *proto.ClientEventTable, opts ...grpc.CallOption) (*emptypb.Empty, error) { - out := new(emptypb.Empty) +func (c *aPIClient) SetClientMonitoringState(ctx context.Context, in *proto.ClientEventTable, opts ...grpc.CallOption) (*empty.Empty, error) { + out := new(empty.Empty) err := c.cc.Invoke(ctx, "/proto.API/SetClientMonitoringState", in, out, opts...) if err != nil { return nil, err @@ -625,8 +625,8 @@ func (c *aPIClient) UpdateNotebookCell(ctx context.Context, in *NotebookCellRequ return out, nil } -func (c *aPIClient) CancelNotebookCell(ctx context.Context, in *NotebookCellRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { - out := new(emptypb.Empty) +func (c *aPIClient) CancelNotebookCell(ctx context.Context, in *NotebookCellRequest, opts ...grpc.CallOption) (*empty.Empty, error) { + out := new(empty.Empty) err := c.cc.Invoke(ctx, "/proto.API/CancelNotebookCell", in, out, opts...) if err != nil { return nil, err @@ -634,8 +634,8 @@ func (c *aPIClient) CancelNotebookCell(ctx context.Context, in *NotebookCellRequ return out, nil } -func (c *aPIClient) CreateNotebookDownloadFile(ctx context.Context, in *NotebookExportRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { - out := new(emptypb.Empty) +func (c *aPIClient) CreateNotebookDownloadFile(ctx context.Context, in *NotebookExportRequest, opts ...grpc.CallOption) (*empty.Empty, error) { + out := new(empty.Empty) err := c.cc.Invoke(ctx, "/proto.API/CreateNotebookDownloadFile", in, out, opts...) if err != nil { return nil, err @@ -725,8 +725,8 @@ func (x *aPIWatchEventClient) Recv() (*EventResponse, error) { return m, nil } -func (c *aPIClient) PushEvents(ctx context.Context, in *PushEventRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { - out := new(emptypb.Empty) +func (c *aPIClient) PushEvents(ctx context.Context, in *PushEventRequest, opts ...grpc.CallOption) (*empty.Empty, error) { + out := new(empty.Empty) err := c.cc.Invoke(ctx, "/proto.API/PushEvents", in, out, opts...) if err != nil { return nil, err @@ -734,8 +734,8 @@ func (c *aPIClient) PushEvents(ctx context.Context, in *PushEventRequest, opts . return out, nil } -func (c *aPIClient) WriteEvent(ctx context.Context, in *proto2.VQLResponse, opts ...grpc.CallOption) (*emptypb.Empty, error) { - out := new(emptypb.Empty) +func (c *aPIClient) WriteEvent(ctx context.Context, in *proto2.VQLResponse, opts ...grpc.CallOption) (*empty.Empty, error) { + out := new(empty.Empty) err := c.cc.Invoke(ctx, "/proto.API/WriteEvent", in, out, opts...) if err != nil { return nil, err @@ -761,8 +761,8 @@ func (c *aPIClient) SetSubject(ctx context.Context, in *DataRequest, opts ...grp return out, nil } -func (c *aPIClient) DeleteSubject(ctx context.Context, in *DataRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { - out := new(emptypb.Empty) +func (c *aPIClient) DeleteSubject(ctx context.Context, in *DataRequest, opts ...grpc.CallOption) (*empty.Empty, error) { + out := new(empty.Empty) err := c.cc.Invoke(ctx, "/proto.API/DeleteSubject", in, out, opts...) if err != nil { return nil, err @@ -799,30 +799,30 @@ type APIServer interface { EstimateHunt(context.Context, *HuntEstimateRequest) (*HuntStats, error) ListHunts(context.Context, *ListHuntsRequest) (*ListHuntsResponse, error) GetHunt(context.Context, *GetHuntRequest) (*Hunt, error) - ModifyHunt(context.Context, *Hunt) (*emptypb.Empty, error) + ModifyHunt(context.Context, *Hunt) (*empty.Empty, error) GetHuntFlows(context.Context, *GetTableRequest) (*GetTableResponse, error) GetHuntResults(context.Context, *GetHuntResultsRequest) (*GetTableResponse, error) // Clients. - NotifyClients(context.Context, *NotificationRequest) (*emptypb.Empty, error) + NotifyClients(context.Context, *NotificationRequest) (*empty.Empty, error) LabelClients(context.Context, *LabelClientsRequest) (*APIResponse, error) ListClients(context.Context, *SearchClientsRequest) (*SearchClientsResponse, error) GetClient(context.Context, *GetClientRequest) (*ApiClient, error) GetClientMetadata(context.Context, *GetClientRequest) (*ClientMetadata, error) - SetClientMetadata(context.Context, *SetClientMetadataRequest) (*emptypb.Empty, error) + SetClientMetadata(context.Context, *SetClientMetadataRequest) (*empty.Empty, error) GetClientFlows(context.Context, *ApiFlowRequest) (*ApiFlowResponse, error) // Users - GetUserUITraits(context.Context, *emptypb.Empty) (*ApiUser, error) + GetUserUITraits(context.Context, *empty.Empty) (*ApiUser, error) SetGUIOptions(context.Context, *SetGUIOptionsRequest) (*SetGUIOptionsResponse, error) // List all the GUI users known on this server. - GetUsers(context.Context, *emptypb.Empty) (*Users, error) + GetUsers(context.Context, *empty.Empty) (*Users, error) // List all the GUI users in orgs in which we are a member - GetGlobalUsers(context.Context, *emptypb.Empty) (*Users, error) + GetGlobalUsers(context.Context, *empty.Empty) (*Users, error) GetUserRoles(context.Context, *UserRequest) (*UserRoles, error) - SetUserRoles(context.Context, *UserRoles) (*emptypb.Empty, error) + SetUserRoles(context.Context, *UserRoles) (*empty.Empty, error) GetUser(context.Context, *UserRequest) (*VelociraptorUser, error) - CreateUser(context.Context, *UpdateUserRequest) (*emptypb.Empty, error) + CreateUser(context.Context, *UpdateUserRequest) (*empty.Empty, error) GetUserFavorites(context.Context, *Favorite) (*Favorites, error) - SetPassword(context.Context, *SetPasswordRequest) (*emptypb.Empty, error) + SetPassword(context.Context, *SetPasswordRequest) (*empty.Empty, error) // VFS VFSListDirectory(context.Context, *VFSListRequest) (*VFSListResponse, error) VFSListDirectoryFiles(context.Context, *GetTableRequest) (*GetTableResponse, error) @@ -836,7 +836,7 @@ type APIServer interface { GetFlowDetails(context.Context, *ApiFlowRequest) (*FlowDetails, error) GetFlowRequests(context.Context, *ApiFlowRequest) (*ApiFlowRequestDetails, error) // VQL assistance - GetKeywordCompletions(context.Context, *emptypb.Empty) (*KeywordCompletions, error) + GetKeywordCompletions(context.Context, *empty.Empty) (*KeywordCompletions, error) ReformatVQL(context.Context, *ReformatVQLMessage) (*ReformatVQLMessage, error) // Artifacts GetArtifacts(context.Context, *GetArtifactsRequest) (*proto1.ArtifactDescriptors, error) @@ -850,7 +850,7 @@ type APIServer interface { GetReport(context.Context, *GetReportRequest) (*GetReportResponse, error) // Server Monitoring Artifacts - manage the Server Monitoring // Service.. - GetServerMonitoringState(context.Context, *emptypb.Empty) (*proto.ArtifactCollectorArgs, error) + GetServerMonitoringState(context.Context, *empty.Empty) (*proto.ArtifactCollectorArgs, error) // Server Monitoring Artifacts - manage the Server Monitoring // Service. SetServerMonitoringState(context.Context, *proto.ArtifactCollectorArgs) (*proto.ArtifactCollectorArgs, error) @@ -859,7 +859,7 @@ type APIServer interface { GetClientMonitoringState(context.Context, *proto.GetClientMonitoringStateRequest) (*proto.ClientEventTable, error) // Client Monitoring Artifacts - manage the Client Monitoring // Service. - SetClientMonitoringState(context.Context, *proto.ClientEventTable) (*emptypb.Empty, error) + SetClientMonitoringState(context.Context, *proto.ClientEventTable) (*empty.Empty, error) ListAvailableEventResults(context.Context, *ListAvailableEventResultsRequest) (*ListAvailableEventResultsResponse, error) // Schedule downloads. CreateDownloadFile(context.Context, *CreateDownloadRequest) (*CreateDownloadResponse, error) @@ -870,8 +870,8 @@ type APIServer interface { NewNotebookCell(context.Context, *NotebookCellRequest) (*NotebookMetadata, error) GetNotebookCell(context.Context, *NotebookCellRequest) (*NotebookCell, error) UpdateNotebookCell(context.Context, *NotebookCellRequest) (*NotebookCell, error) - CancelNotebookCell(context.Context, *NotebookCellRequest) (*emptypb.Empty, error) - CreateNotebookDownloadFile(context.Context, *NotebookExportRequest) (*emptypb.Empty, error) + CancelNotebookCell(context.Context, *NotebookCellRequest) (*empty.Empty, error) + CreateNotebookDownloadFile(context.Context, *NotebookExportRequest) (*empty.Empty, error) UploadNotebookAttachment(context.Context, *NotebookFileUploadRequest) (*NotebookFileUploadResponse, error) // This can be used by API clients to fetch file content. VFSGetBuffer(context.Context, *VFSFileBuffer) (*VFSFileBuffer, error) @@ -880,13 +880,13 @@ type APIServer interface { // Watch for events from the master. WatchEvent(*EventRequest, API_WatchEventServer) error // Push the events to the master - PushEvents(context.Context, *PushEventRequest) (*emptypb.Empty, error) + PushEvents(context.Context, *PushEventRequest) (*empty.Empty, error) // Push monitoring event to the server. - WriteEvent(context.Context, *proto2.VQLResponse) (*emptypb.Empty, error) + WriteEvent(context.Context, *proto2.VQLResponse) (*empty.Empty, error) // Remote data store access. GetSubject(context.Context, *DataRequest) (*DataResponse, error) SetSubject(context.Context, *DataRequest) (*DataResponse, error) - DeleteSubject(context.Context, *DataRequest) (*emptypb.Empty, error) + DeleteSubject(context.Context, *DataRequest) (*empty.Empty, error) ListChildren(context.Context, *DataRequest) (*ListChildrenResponse, error) // Health check protocol as in https://github.com/grpc/grpc/blob/master/doc/health-checking.md Check(context.Context, *HealthCheckRequest) (*HealthCheckResponse, error) @@ -909,7 +909,7 @@ func (UnimplementedAPIServer) ListHunts(context.Context, *ListHuntsRequest) (*Li func (UnimplementedAPIServer) GetHunt(context.Context, *GetHuntRequest) (*Hunt, error) { return nil, status.Errorf(codes.Unimplemented, "method GetHunt not implemented") } -func (UnimplementedAPIServer) ModifyHunt(context.Context, *Hunt) (*emptypb.Empty, error) { +func (UnimplementedAPIServer) ModifyHunt(context.Context, *Hunt) (*empty.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method ModifyHunt not implemented") } func (UnimplementedAPIServer) GetHuntFlows(context.Context, *GetTableRequest) (*GetTableResponse, error) { @@ -918,7 +918,7 @@ func (UnimplementedAPIServer) GetHuntFlows(context.Context, *GetTableRequest) (* func (UnimplementedAPIServer) GetHuntResults(context.Context, *GetHuntResultsRequest) (*GetTableResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetHuntResults not implemented") } -func (UnimplementedAPIServer) NotifyClients(context.Context, *NotificationRequest) (*emptypb.Empty, error) { +func (UnimplementedAPIServer) NotifyClients(context.Context, *NotificationRequest) (*empty.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method NotifyClients not implemented") } func (UnimplementedAPIServer) LabelClients(context.Context, *LabelClientsRequest) (*APIResponse, error) { @@ -933,40 +933,40 @@ func (UnimplementedAPIServer) GetClient(context.Context, *GetClientRequest) (*Ap func (UnimplementedAPIServer) GetClientMetadata(context.Context, *GetClientRequest) (*ClientMetadata, error) { return nil, status.Errorf(codes.Unimplemented, "method GetClientMetadata not implemented") } -func (UnimplementedAPIServer) SetClientMetadata(context.Context, *SetClientMetadataRequest) (*emptypb.Empty, error) { +func (UnimplementedAPIServer) SetClientMetadata(context.Context, *SetClientMetadataRequest) (*empty.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method SetClientMetadata not implemented") } func (UnimplementedAPIServer) GetClientFlows(context.Context, *ApiFlowRequest) (*ApiFlowResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetClientFlows not implemented") } -func (UnimplementedAPIServer) GetUserUITraits(context.Context, *emptypb.Empty) (*ApiUser, error) { +func (UnimplementedAPIServer) GetUserUITraits(context.Context, *empty.Empty) (*ApiUser, error) { return nil, status.Errorf(codes.Unimplemented, "method GetUserUITraits not implemented") } func (UnimplementedAPIServer) SetGUIOptions(context.Context, *SetGUIOptionsRequest) (*SetGUIOptionsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method SetGUIOptions not implemented") } -func (UnimplementedAPIServer) GetUsers(context.Context, *emptypb.Empty) (*Users, error) { +func (UnimplementedAPIServer) GetUsers(context.Context, *empty.Empty) (*Users, error) { return nil, status.Errorf(codes.Unimplemented, "method GetUsers not implemented") } -func (UnimplementedAPIServer) GetGlobalUsers(context.Context, *emptypb.Empty) (*Users, error) { +func (UnimplementedAPIServer) GetGlobalUsers(context.Context, *empty.Empty) (*Users, error) { return nil, status.Errorf(codes.Unimplemented, "method GetGlobalUsers not implemented") } func (UnimplementedAPIServer) GetUserRoles(context.Context, *UserRequest) (*UserRoles, error) { return nil, status.Errorf(codes.Unimplemented, "method GetUserRoles not implemented") } -func (UnimplementedAPIServer) SetUserRoles(context.Context, *UserRoles) (*emptypb.Empty, error) { +func (UnimplementedAPIServer) SetUserRoles(context.Context, *UserRoles) (*empty.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method SetUserRoles not implemented") } func (UnimplementedAPIServer) GetUser(context.Context, *UserRequest) (*VelociraptorUser, error) { return nil, status.Errorf(codes.Unimplemented, "method GetUser not implemented") } -func (UnimplementedAPIServer) CreateUser(context.Context, *UpdateUserRequest) (*emptypb.Empty, error) { +func (UnimplementedAPIServer) CreateUser(context.Context, *UpdateUserRequest) (*empty.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method CreateUser not implemented") } func (UnimplementedAPIServer) GetUserFavorites(context.Context, *Favorite) (*Favorites, error) { return nil, status.Errorf(codes.Unimplemented, "method GetUserFavorites not implemented") } -func (UnimplementedAPIServer) SetPassword(context.Context, *SetPasswordRequest) (*emptypb.Empty, error) { +func (UnimplementedAPIServer) SetPassword(context.Context, *SetPasswordRequest) (*empty.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method SetPassword not implemented") } func (UnimplementedAPIServer) VFSListDirectory(context.Context, *VFSListRequest) (*VFSListResponse, error) { @@ -999,7 +999,7 @@ func (UnimplementedAPIServer) GetFlowDetails(context.Context, *ApiFlowRequest) ( func (UnimplementedAPIServer) GetFlowRequests(context.Context, *ApiFlowRequest) (*ApiFlowRequestDetails, error) { return nil, status.Errorf(codes.Unimplemented, "method GetFlowRequests not implemented") } -func (UnimplementedAPIServer) GetKeywordCompletions(context.Context, *emptypb.Empty) (*KeywordCompletions, error) { +func (UnimplementedAPIServer) GetKeywordCompletions(context.Context, *empty.Empty) (*KeywordCompletions, error) { return nil, status.Errorf(codes.Unimplemented, "method GetKeywordCompletions not implemented") } func (UnimplementedAPIServer) ReformatVQL(context.Context, *ReformatVQLMessage) (*ReformatVQLMessage, error) { @@ -1026,7 +1026,7 @@ func (UnimplementedAPIServer) SetToolInfo(context.Context, *proto1.Tool) (*proto func (UnimplementedAPIServer) GetReport(context.Context, *GetReportRequest) (*GetReportResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetReport not implemented") } -func (UnimplementedAPIServer) GetServerMonitoringState(context.Context, *emptypb.Empty) (*proto.ArtifactCollectorArgs, error) { +func (UnimplementedAPIServer) GetServerMonitoringState(context.Context, *empty.Empty) (*proto.ArtifactCollectorArgs, error) { return nil, status.Errorf(codes.Unimplemented, "method GetServerMonitoringState not implemented") } func (UnimplementedAPIServer) SetServerMonitoringState(context.Context, *proto.ArtifactCollectorArgs) (*proto.ArtifactCollectorArgs, error) { @@ -1035,7 +1035,7 @@ func (UnimplementedAPIServer) SetServerMonitoringState(context.Context, *proto.A func (UnimplementedAPIServer) GetClientMonitoringState(context.Context, *proto.GetClientMonitoringStateRequest) (*proto.ClientEventTable, error) { return nil, status.Errorf(codes.Unimplemented, "method GetClientMonitoringState not implemented") } -func (UnimplementedAPIServer) SetClientMonitoringState(context.Context, *proto.ClientEventTable) (*emptypb.Empty, error) { +func (UnimplementedAPIServer) SetClientMonitoringState(context.Context, *proto.ClientEventTable) (*empty.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method SetClientMonitoringState not implemented") } func (UnimplementedAPIServer) ListAvailableEventResults(context.Context, *ListAvailableEventResultsRequest) (*ListAvailableEventResultsResponse, error) { @@ -1062,10 +1062,10 @@ func (UnimplementedAPIServer) GetNotebookCell(context.Context, *NotebookCellRequ func (UnimplementedAPIServer) UpdateNotebookCell(context.Context, *NotebookCellRequest) (*NotebookCell, error) { return nil, status.Errorf(codes.Unimplemented, "method UpdateNotebookCell not implemented") } -func (UnimplementedAPIServer) CancelNotebookCell(context.Context, *NotebookCellRequest) (*emptypb.Empty, error) { +func (UnimplementedAPIServer) CancelNotebookCell(context.Context, *NotebookCellRequest) (*empty.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method CancelNotebookCell not implemented") } -func (UnimplementedAPIServer) CreateNotebookDownloadFile(context.Context, *NotebookExportRequest) (*emptypb.Empty, error) { +func (UnimplementedAPIServer) CreateNotebookDownloadFile(context.Context, *NotebookExportRequest) (*empty.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method CreateNotebookDownloadFile not implemented") } func (UnimplementedAPIServer) UploadNotebookAttachment(context.Context, *NotebookFileUploadRequest) (*NotebookFileUploadResponse, error) { @@ -1080,10 +1080,10 @@ func (UnimplementedAPIServer) Query(*proto2.VQLCollectorArgs, API_QueryServer) e func (UnimplementedAPIServer) WatchEvent(*EventRequest, API_WatchEventServer) error { return status.Errorf(codes.Unimplemented, "method WatchEvent not implemented") } -func (UnimplementedAPIServer) PushEvents(context.Context, *PushEventRequest) (*emptypb.Empty, error) { +func (UnimplementedAPIServer) PushEvents(context.Context, *PushEventRequest) (*empty.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method PushEvents not implemented") } -func (UnimplementedAPIServer) WriteEvent(context.Context, *proto2.VQLResponse) (*emptypb.Empty, error) { +func (UnimplementedAPIServer) WriteEvent(context.Context, *proto2.VQLResponse) (*empty.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method WriteEvent not implemented") } func (UnimplementedAPIServer) GetSubject(context.Context, *DataRequest) (*DataResponse, error) { @@ -1092,7 +1092,7 @@ func (UnimplementedAPIServer) GetSubject(context.Context, *DataRequest) (*DataRe func (UnimplementedAPIServer) SetSubject(context.Context, *DataRequest) (*DataResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method SetSubject not implemented") } -func (UnimplementedAPIServer) DeleteSubject(context.Context, *DataRequest) (*emptypb.Empty, error) { +func (UnimplementedAPIServer) DeleteSubject(context.Context, *DataRequest) (*empty.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method DeleteSubject not implemented") } func (UnimplementedAPIServer) ListChildren(context.Context, *DataRequest) (*ListChildrenResponse, error) { @@ -1367,7 +1367,7 @@ func _API_GetClientFlows_Handler(srv interface{}, ctx context.Context, dec func( } func _API_GetUserUITraits_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(emptypb.Empty) + in := new(empty.Empty) if err := dec(in); err != nil { return nil, err } @@ -1379,7 +1379,7 @@ func _API_GetUserUITraits_Handler(srv interface{}, ctx context.Context, dec func FullMethod: "/proto.API/GetUserUITraits", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(APIServer).GetUserUITraits(ctx, req.(*emptypb.Empty)) + return srv.(APIServer).GetUserUITraits(ctx, req.(*empty.Empty)) } return interceptor(ctx, in, info, handler) } @@ -1403,7 +1403,7 @@ func _API_SetGUIOptions_Handler(srv interface{}, ctx context.Context, dec func(i } func _API_GetUsers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(emptypb.Empty) + in := new(empty.Empty) if err := dec(in); err != nil { return nil, err } @@ -1415,13 +1415,13 @@ func _API_GetUsers_Handler(srv interface{}, ctx context.Context, dec func(interf FullMethod: "/proto.API/GetUsers", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(APIServer).GetUsers(ctx, req.(*emptypb.Empty)) + return srv.(APIServer).GetUsers(ctx, req.(*empty.Empty)) } return interceptor(ctx, in, info, handler) } func _API_GetGlobalUsers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(emptypb.Empty) + in := new(empty.Empty) if err := dec(in); err != nil { return nil, err } @@ -1433,7 +1433,7 @@ func _API_GetGlobalUsers_Handler(srv interface{}, ctx context.Context, dec func( FullMethod: "/proto.API/GetGlobalUsers", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(APIServer).GetGlobalUsers(ctx, req.(*emptypb.Empty)) + return srv.(APIServer).GetGlobalUsers(ctx, req.(*empty.Empty)) } return interceptor(ctx, in, info, handler) } @@ -1727,7 +1727,7 @@ func _API_GetFlowRequests_Handler(srv interface{}, ctx context.Context, dec func } func _API_GetKeywordCompletions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(emptypb.Empty) + in := new(empty.Empty) if err := dec(in); err != nil { return nil, err } @@ -1739,7 +1739,7 @@ func _API_GetKeywordCompletions_Handler(srv interface{}, ctx context.Context, de FullMethod: "/proto.API/GetKeywordCompletions", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(APIServer).GetKeywordCompletions(ctx, req.(*emptypb.Empty)) + return srv.(APIServer).GetKeywordCompletions(ctx, req.(*empty.Empty)) } return interceptor(ctx, in, info, handler) } @@ -1889,7 +1889,7 @@ func _API_GetReport_Handler(srv interface{}, ctx context.Context, dec func(inter } func _API_GetServerMonitoringState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(emptypb.Empty) + in := new(empty.Empty) if err := dec(in); err != nil { return nil, err } @@ -1901,7 +1901,7 @@ func _API_GetServerMonitoringState_Handler(srv interface{}, ctx context.Context, FullMethod: "/proto.API/GetServerMonitoringState", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(APIServer).GetServerMonitoringState(ctx, req.(*emptypb.Empty)) + return srv.(APIServer).GetServerMonitoringState(ctx, req.(*empty.Empty)) } return interceptor(ctx, in, info, handler) } diff --git a/api/reformat.go b/api/reformat.go index 85a2dd69a27..dc54b441afd 100644 --- a/api/reformat.go +++ b/api/reformat.go @@ -2,8 +2,6 @@ package api import ( context "golang.org/x/net/context" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" "www.velocidex.com/golang/velociraptor/acls" api_proto "www.velocidex.com/golang/velociraptor/api/proto" "www.velocidex.com/golang/velociraptor/services" @@ -23,7 +21,7 @@ func (self *ApiServer) ReformatVQL( permissions := acls.READ_RESULTS perm, err := services.CheckAccess(org_config_obj, user_record.Name, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to read notebooks.") } diff --git a/api/status.go b/api/status.go index 779cce3386e..0208ba4bab8 100644 --- a/api/status.go +++ b/api/status.go @@ -1,6 +1,7 @@ package api import ( + "fmt" "os" errors "github.com/go-errors/errors" @@ -40,3 +41,11 @@ func Status(verbose bool, err error) error { func InvalidStatus(msg string) error { return status.Error(codes.InvalidArgument, msg) } + +func PermissionDenied(err error, message string) error { + if err != nil { + return status.Error(codes.PermissionDenied, + fmt.Sprintf("%v: %v", err, message)) + } + return status.Error(codes.PermissionDenied, message) +} diff --git a/api/tools.go b/api/tools.go index 4bc598f9fb5..bcc3a912b0e 100644 --- a/api/tools.go +++ b/api/tools.go @@ -2,8 +2,6 @@ package api import ( context "golang.org/x/net/context" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" "www.velocidex.com/golang/velociraptor/acls" artifacts_proto "www.velocidex.com/golang/velociraptor/artifacts/proto" @@ -22,7 +20,7 @@ func (self *ApiServer) GetToolInfo(ctx context.Context, permissions := acls.READ_RESULTS perm, err := services.CheckAccess(org_config_obj, user_record.Name, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to view tools.") } @@ -52,7 +50,7 @@ func (self *ApiServer) SetToolInfo(ctx context.Context, permissions := acls.ARTIFACT_WRITER perm, err := services.CheckAccess(org_config_obj, user_record.Name, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to update tool definitions.") } diff --git a/api/vfs.go b/api/vfs.go index 100cbdd8407..6d12364fe62 100644 --- a/api/vfs.go +++ b/api/vfs.go @@ -66,8 +66,6 @@ import ( "strings" context "golang.org/x/net/context" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" "www.velocidex.com/golang/velociraptor/acls" api_proto "www.velocidex.com/golang/velociraptor/api/proto" flows_proto "www.velocidex.com/golang/velociraptor/flows/proto" @@ -149,7 +147,7 @@ func (self *ApiServer) VFSListDirectoryFiles( permissions := acls.READ_RESULTS perm, err := services.CheckAccess(org_config_obj, principal, permissions) if !perm || err != nil { - return nil, status.Error(codes.PermissionDenied, + return nil, PermissionDenied(err, "User is not allowed to view the VFS.") } diff --git a/config/proto/config.pb.go b/config/proto/config.pb.go index d75a442c9e3..bb4d4b625ed 100644 --- a/config/proto/config.pb.go +++ b/config/proto/config.pb.go @@ -3208,6 +3208,17 @@ type Defaults struct { // POST messages. If not set we use client defaults. MaxRows uint64 `protobuf:"varint,30,opt,name=max_rows,json=maxRows,proto3" json:"max_rows,omitempty"` MaxRowBufferSize uint64 `protobuf:"varint,31,opt,name=max_row_buffer_size,json=maxRowBufferSize,proto3" json:"max_row_buffer_size,omitempty"` + // When the server is in lockdown mode the following permissions + // will be denied (Even for administrators). + // The default list is: + // - ARTIFACT_WRITER + // - SERVER_ARTIFACT_WRITER + // - EXECVE + // - SERVER_ADMIN + // - FILESYSTEM_WRITE + // - FILESYSTEM_READ + // - MACHINE_STATE + LockdownDeniedPermissions []string `protobuf:"bytes,32,rep,name=lockdown_denied_permissions,json=lockdownDeniedPermissions,proto3" json:"lockdown_denied_permissions,omitempty"` } func (x *Defaults) Reset() { @@ -3389,6 +3400,13 @@ func (x *Defaults) GetMaxRowBufferSize() uint64 { return 0 } +func (x *Defaults) GetLockdownDeniedPermissions() []string { + if x != nil { + return x.LockdownDeniedPermissions + } + return nil +} + // Configures crypto preferences type CryptoConfig struct { state protoimpl.MessageState @@ -3726,6 +3744,13 @@ type Config struct { // set in the config file by the user but is propagated from the // startup code. Services *ServerServicesConfig `protobuf:"bytes,38,opt,name=services,proto3" json:"services,omitempty"` + // The Velociraptor server may be placed into "lockdown" + // mode. While in lockdown mode certain permissions are denied - + // even for administrators. This additional protection mode helps + // to mitigate the case when a Velociraptor administrator's + // account is compromised. The server can be taken out of lockdown + // mode by setting lockdown to false and restarting the server. + Lockdown bool `protobuf:"varint,39,opt,name=lockdown,proto3" json:"lockdown,omitempty"` } func (x *Config) Reset() { @@ -3937,6 +3962,13 @@ func (x *Config) GetServices() *ServerServicesConfig { return nil } +func (x *Config) GetLockdown() bool { + if x != nil { + return x.Lockdown + } + return false +} + var File_config_proto protoreflect.FileDescriptor var file_config_proto_rawDesc = []byte{ @@ -5029,7 +5061,7 @@ var file_config_proto_rawDesc = []byte{ 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x2c, 0x0a, 0x12, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x22, 0xab, 0x08, 0x0a, 0x08, 0x44, 0x65, 0x66, 0x61, + 0x6e, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x22, 0xeb, 0x08, 0x0a, 0x08, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x68, 0x75, 0x6e, 0x74, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x5f, 0x68, 0x6f, 0x75, 0x72, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x68, 0x75, 0x6e, 0x74, 0x45, 0x78, 0x70, 0x69, 0x72, 0x79, 0x48, 0x6f, 0x75, 0x72, 0x73, @@ -5096,7 +5128,11 @@ var file_config_proto_rawDesc = []byte{ 0x61, 0x78, 0x52, 0x6f, 0x77, 0x73, 0x12, 0x2d, 0x0a, 0x13, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x6f, 0x77, 0x5f, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x6d, 0x61, 0x78, 0x52, 0x6f, 0x77, 0x42, 0x75, 0x66, 0x66, 0x65, - 0x72, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x86, 0x03, 0x0a, 0x0c, 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, + 0x72, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x3e, 0x0a, 0x1b, 0x6c, 0x6f, 0x63, 0x6b, 0x64, 0x6f, 0x77, + 0x6e, 0x5f, 0x64, 0x65, 0x6e, 0x69, 0x65, 0x64, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x20, 0x20, 0x03, 0x28, 0x09, 0x52, 0x19, 0x6c, 0x6f, 0x63, 0x6b, + 0x64, 0x6f, 0x77, 0x6e, 0x44, 0x65, 0x6e, 0x69, 0x65, 0x64, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x86, 0x03, 0x0a, 0x0c, 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x6f, 0x6f, 0x74, 0x43, 0x65, 0x72, 0x74, 0x73, 0x12, 0x7f, 0x0a, 0x17, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, @@ -5148,7 +5184,7 @@ var file_config_proto_rawDesc = []byte{ 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x64, 0x69, 0x73, 0x61, 0x62, - 0x6c, 0x65, 0x64, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x22, 0xae, 0x0c, 0x0a, 0x06, 0x43, + 0x6c, 0x65, 0x64, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x22, 0xca, 0x0c, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2b, 0x0a, 0x0f, 0x61, 0x75, 0x74, 0x6f, 0x63, 0x65, 0x72, 0x74, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0e, 0x61, 0x75, 0x74, 0x6f, 0x63, 0x65, 0x72, 0x74, 0x44, 0x6f, 0x6d, 0x61, @@ -5247,11 +5283,13 @@ var file_config_proto_rawDesc = []byte{ 0x6d, 0x65, 0x12, 0x37, 0x0a, 0x08, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x26, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x52, 0x08, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x42, 0x34, 0x5a, 0x32, 0x77, - 0x77, 0x77, 0x2e, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x64, 0x65, 0x78, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x72, 0x61, - 0x70, 0x74, 0x6f, 0x72, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x67, 0x52, 0x08, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x6c, + 0x6f, 0x63, 0x6b, 0x64, 0x6f, 0x77, 0x6e, 0x18, 0x27, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6c, + 0x6f, 0x63, 0x6b, 0x64, 0x6f, 0x77, 0x6e, 0x42, 0x34, 0x5a, 0x32, 0x77, 0x77, 0x77, 0x2e, 0x76, + 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x64, 0x65, 0x78, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, + 0x61, 0x6e, 0x67, 0x2f, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x72, 0x61, 0x70, 0x74, 0x6f, 0x72, + 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/config/proto/config.proto b/config/proto/config.proto index 30fb18da1cd..f7dce819062 100644 --- a/config/proto/config.proto +++ b/config/proto/config.proto @@ -972,6 +972,18 @@ message Defaults { // POST messages. If not set we use client defaults. uint64 max_rows = 30; uint64 max_row_buffer_size = 31; + + // When the server is in lockdown mode the following permissions + // will be denied (Even for administrators). + // The default list is: + // - ARTIFACT_WRITER + // - SERVER_ARTIFACT_WRITER + // - EXECVE + // - SERVER_ADMIN + // - FILESYSTEM_WRITE + // - FILESYSTEM_READ + // - MACHINE_STATE + repeated string lockdown_denied_permissions = 32; } // Configures crypto preferences @@ -1138,4 +1150,12 @@ message Config { // set in the config file by the user but is propagated from the // startup code. ServerServicesConfig services = 38; + + // The Velociraptor server may be placed into "lockdown" + // mode. While in lockdown mode certain permissions are denied - + // even for administrators. This additional protection mode helps + // to mitigate the case when a Velociraptor administrator's + // account is compromised. The server can be taken out of lockdown + // mode by setting lockdown to false and restarting the server. + bool lockdown = 39; } diff --git a/docs/references/server.config.yaml b/docs/references/server.config.yaml index 127cde87fdb..dcc40cc1d6f 100644 --- a/docs/references/server.config.yaml +++ b/docs/references/server.config.yaml @@ -29,6 +29,9 @@ version: # The version of the Go compiler that built this binary compiler: go1.19.2 + # The time the client was installed (as written in the writeback file). + install_time: 1680267359 + ## The Client block will be copied into the client.config.yaml and it ## is expected to be used by clients. It contains no secrets and can ## be embedded into clients. The server must also have this block as @@ -451,7 +454,7 @@ Frontend: # tools. This setting will force it to go out over this proxy. NOTE- # If you dont want to allow outbound connections, just set this to # an non existent setting (e.g. http://127.0.0.1:3128). - proxy: "" + proxy: "http://127.0.0.1:3128" ## Velociraptor can attempt to obfuscate artifact names when ## compiling them into raw VQL. If this is set this obfuscation is diff --git a/gui/velociraptor/src/components/i8n/en.jsx b/gui/velociraptor/src/components/i8n/en.jsx index e77518c5b20..f5320cd6df0 100644 --- a/gui/velociraptor/src/components/i8n/en.jsx +++ b/gui/velociraptor/src/components/i8n/en.jsx @@ -179,7 +179,7 @@ const English = { "Role_analyst" : "Analyst", "Role_investigator" : "Investigator", "Role_artifact_writer" : "Artifact Writer", - "Role_api" : "Read-Only API Client", + "Role_api" : "API Client", "ToolRole_administrator" : <> Like any system, Velociraptor needs an administrator which is all powerful. This account can run arbitrary VQL on the server, reconfigure the server, etc. The ability to add/create/edit/remove users is dependent on the organizations to which this account belongs. @@ -206,7 +206,7 @@ const English = { , "ToolRole_api" : <> - This role provides the ability to read previously collected results but does not allow the user to actually make any changes. + This role is required to provide the ability for the user to connect over the API port. , "Perm_ALL_QUERY" : "All Query", diff --git a/proto/flow_metadata.pb.go b/proto/flow_metadata.pb.go index da32b7456cd..00033dfbf6e 100644 --- a/proto/flow_metadata.pb.go +++ b/proto/flow_metadata.pb.go @@ -4,9 +4,9 @@ package proto import ( + descriptor "github.com/golang/protobuf/protoc-gen-go/descriptor" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - descriptorpb "google.golang.org/protobuf/types/descriptorpb" reflect "reflect" sync "sync" ) @@ -67,7 +67,7 @@ func (x *FlowMetaData) GetCategory() string { var file_flow_metadata_proto_extTypes = []protoimpl.ExtensionInfo{ { - ExtendedType: (*descriptorpb.MessageOptions)(nil), + ExtendedType: (*descriptor.MessageOptions)(nil), ExtensionType: (*FlowMetaData)(nil), Field: 65661, Name: "proto.flow_metadata", @@ -76,7 +76,7 @@ var file_flow_metadata_proto_extTypes = []protoimpl.ExtensionInfo{ }, } -// Extension fields to descriptorpb.MessageOptions. +// Extension fields to descriptor.MessageOptions. var ( // optional proto.FlowMetaData flow_metadata = 65661; E_FlowMetadata = &file_flow_metadata_proto_extTypes[0] @@ -117,8 +117,8 @@ func file_flow_metadata_proto_rawDescGZIP() []byte { var file_flow_metadata_proto_msgTypes = make([]protoimpl.MessageInfo, 1) var file_flow_metadata_proto_goTypes = []interface{}{ - (*FlowMetaData)(nil), // 0: proto.FlowMetaData - (*descriptorpb.MessageOptions)(nil), // 1: google.protobuf.MessageOptions + (*FlowMetaData)(nil), // 0: proto.FlowMetaData + (*descriptor.MessageOptions)(nil), // 1: google.protobuf.MessageOptions } var file_flow_metadata_proto_depIdxs = []int32{ 1, // 0: proto.flow_metadata:extendee -> google.protobuf.MessageOptions diff --git a/proto/semantic.pb.go b/proto/semantic.pb.go index eb78699170e..c0ccd6e4ddd 100644 --- a/proto/semantic.pb.go +++ b/proto/semantic.pb.go @@ -4,9 +4,9 @@ package proto import ( + descriptor "github.com/golang/protobuf/protoc-gen-go/descriptor" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - descriptorpb "google.golang.org/protobuf/types/descriptorpb" reflect "reflect" sync "sync" ) @@ -220,7 +220,7 @@ func (x *SemanticMessageDescriptor) GetFriendlyName() string { var file_semantic_proto_extTypes = []protoimpl.ExtensionInfo{ { - ExtendedType: (*descriptorpb.FieldOptions)(nil), + ExtendedType: (*descriptor.FieldOptions)(nil), ExtensionType: (*SemanticDescriptor)(nil), Field: 51584972, Name: "proto.sem_type", @@ -228,7 +228,7 @@ var file_semantic_proto_extTypes = []protoimpl.ExtensionInfo{ Filename: "semantic.proto", }, { - ExtendedType: (*descriptorpb.MessageOptions)(nil), + ExtendedType: (*descriptor.MessageOptions)(nil), ExtensionType: (*SemanticMessageDescriptor)(nil), Field: 51584971, Name: "proto.semantic", @@ -236,7 +236,7 @@ var file_semantic_proto_extTypes = []protoimpl.ExtensionInfo{ Filename: "semantic.proto", }, { - ExtendedType: (*descriptorpb.EnumValueOptions)(nil), + ExtendedType: (*descriptor.EnumValueOptions)(nil), ExtensionType: (*string)(nil), Field: 48651165, Name: "proto.description", @@ -244,7 +244,7 @@ var file_semantic_proto_extTypes = []protoimpl.ExtensionInfo{ Filename: "semantic.proto", }, { - ExtendedType: (*descriptorpb.EnumValueOptions)(nil), + ExtendedType: (*descriptor.EnumValueOptions)(nil), ExtensionType: (*SemanticDescriptor_Labels)(nil), Field: 48651166, Name: "proto.label", @@ -253,19 +253,19 @@ var file_semantic_proto_extTypes = []protoimpl.ExtensionInfo{ }, } -// Extension fields to descriptorpb.FieldOptions. +// Extension fields to descriptor.FieldOptions. var ( // optional proto.SemanticDescriptor sem_type = 51584972; E_SemType = &file_semantic_proto_extTypes[0] ) -// Extension fields to descriptorpb.MessageOptions. +// Extension fields to descriptor.MessageOptions. var ( // optional proto.SemanticMessageDescriptor semantic = 51584971; E_Semantic = &file_semantic_proto_extTypes[1] ) -// Extension fields to descriptorpb.EnumValueOptions. +// Extension fields to descriptor.EnumValueOptions. var ( // optional string description = 48651165; E_Description = &file_semantic_proto_extTypes[2] @@ -346,12 +346,12 @@ func file_semantic_proto_rawDescGZIP() []byte { var file_semantic_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_semantic_proto_msgTypes = make([]protoimpl.MessageInfo, 2) var file_semantic_proto_goTypes = []interface{}{ - (SemanticDescriptor_Labels)(0), // 0: proto.SemanticDescriptor.Labels - (*SemanticDescriptor)(nil), // 1: proto.SemanticDescriptor - (*SemanticMessageDescriptor)(nil), // 2: proto.SemanticMessageDescriptor - (*descriptorpb.FieldOptions)(nil), // 3: google.protobuf.FieldOptions - (*descriptorpb.MessageOptions)(nil), // 4: google.protobuf.MessageOptions - (*descriptorpb.EnumValueOptions)(nil), // 5: google.protobuf.EnumValueOptions + (SemanticDescriptor_Labels)(0), // 0: proto.SemanticDescriptor.Labels + (*SemanticDescriptor)(nil), // 1: proto.SemanticDescriptor + (*SemanticMessageDescriptor)(nil), // 2: proto.SemanticMessageDescriptor + (*descriptor.FieldOptions)(nil), // 3: google.protobuf.FieldOptions + (*descriptor.MessageOptions)(nil), // 4: google.protobuf.MessageOptions + (*descriptor.EnumValueOptions)(nil), // 5: google.protobuf.EnumValueOptions } var file_semantic_proto_depIdxs = []int32{ 0, // 0: proto.SemanticDescriptor.label:type_name -> proto.SemanticDescriptor.Labels diff --git a/services/acl_manager/acl_manager.go b/services/acl_manager/acl_manager.go index 8cbb6b9d535..fbd3823bdf4 100644 --- a/services/acl_manager/acl_manager.go +++ b/services/acl_manager/acl_manager.go @@ -18,6 +18,10 @@ import ( "www.velocidex.com/golang/velociraptor/utils" ) +var ( + notLockedDownError = errors.New("PERMISSION_DENIED: Server locked down") +) + type ACLManager struct { // Cache the effective policy for each principal for 60 sec. lru *ttlcache.Cache @@ -124,11 +128,32 @@ func (self ACLManager) SetPolicy( return db.SetSubject(config_obj, user_path_manager.ACL(), acl_obj) } +func (self ACLManager) handleLockdown( + permissions []acls.ACL_PERMISSION) (bool, error) { + if acls.LockdownToken() == nil { + return false, nil + } + + for _, perm := range permissions { + ok, err := services.CheckAccessWithToken(acls.LockdownToken(), perm) + if err == nil && ok { + return false, notLockedDownError + } + } + return false, nil +} + func (self ACLManager) CheckAccess( config_obj *config_proto.Config, principal string, permissions ...acls.ACL_PERMISSION) (bool, error) { + // If we are in lockdown, immediately reject permission + ok, err := self.handleLockdown(permissions) + if err != nil { + return ok, err + } + // Internal calls from the server are allowed to do anything. if config_obj.Client != nil && principal == config_obj.Client.PinnedServerName { return true, nil diff --git a/services/launcher/acls.go b/services/launcher/acls.go index 47b8ab97150..0e60a28fc19 100644 --- a/services/launcher/acls.go +++ b/services/launcher/acls.go @@ -3,7 +3,6 @@ package launcher import ( "fmt" - "github.com/go-errors/errors" "www.velocidex.com/golang/velociraptor/acls" artifacts_proto "www.velocidex.com/golang/velociraptor/artifacts/proto" config_proto "www.velocidex.com/golang/velociraptor/config/proto" @@ -23,10 +22,15 @@ func CheckAccess( for _, perm := range artifact.RequiredPermissions { permission := acls.GetPermission(perm) perm, err := acl_manager.CheckAccess(permission) - if !perm || err != nil { - return errors.New(fmt.Sprintf( + if !perm { + if err != nil { + return fmt.Errorf( + "While collecting artifact (%s) permission denied %v: %v", + artifact.Name, permission, err) + } + return fmt.Errorf( "While collecting artifact (%s) permission denied %v", - artifact.Name, permission)) + artifact.Name, permission) } } diff --git a/services/sanity/lockdown.go b/services/sanity/lockdown.go new file mode 100644 index 00000000000..95f4d2d4dde --- /dev/null +++ b/services/sanity/lockdown.go @@ -0,0 +1,47 @@ +package sanity + +import ( + "context" + "fmt" + + "www.velocidex.com/golang/velociraptor/acls" + acl_proto "www.velocidex.com/golang/velociraptor/acls/proto" + config_proto "www.velocidex.com/golang/velociraptor/config/proto" + "www.velocidex.com/golang/velociraptor/logging" +) + +func (self SanityChecks) CheckForLockdown( + ctx context.Context, config_obj *config_proto.Config) error { + if !config_obj.Lockdown { + return nil + } + + lockdown_token := &acl_proto.ApiClientACL{ + ArtifactWriter: true, + ServerArtifactWriter: true, + Execve: true, + ServerAdmin: true, + FilesystemWrite: true, + FilesystemRead: true, + MachineState: true, + } + + if config_obj.Defaults != nil && + len(config_obj.Defaults.LockdownDeniedPermissions) > 0 { + lockdown_token = &acl_proto.ApiClientACL{} + for _, perm_name := range config_obj.Defaults.LockdownDeniedPermissions { + err := acls.SetTokenPermission(lockdown_token, perm_name) + if err != nil { + return fmt.Errorf("Invalid permission %v while parsing lockdown_denied_permissions", + perm_name) + } + } + } + + logger := logging.GetLogger(config_obj, &logging.FrontendComponent) + logger.Info("Server is in lockdown! The following permissions are denied: %v", + acls.DescribePermissions(lockdown_token)) + + acls.SetLockdownToken(lockdown_token) + return nil +} diff --git a/services/sanity/sanity.go b/services/sanity/sanity.go index 15994b7ecbd..1c12e39efaa 100644 --- a/services/sanity/sanity.go +++ b/services/sanity/sanity.go @@ -63,6 +63,11 @@ func (self *SanityChecks) CheckRootOrg( } } + err := self.CheckForLockdown(ctx, config_obj) + if err != nil { + return err + } + // Make sure our internal VelociraptorServer service account is // properly created. if config_obj.Client != nil && config_obj.Client.PinnedServerName != "" { diff --git a/vql/acl_managers/server.go b/vql/acl_managers/server.go index d57ec67d125..8d119b66f89 100644 --- a/vql/acl_managers/server.go +++ b/vql/acl_managers/server.go @@ -1,6 +1,7 @@ package acl_managers import ( + "errors" "sync" "www.velocidex.com/golang/velociraptor/acls" @@ -10,6 +11,10 @@ import ( vql_subsystem "www.velocidex.com/golang/velociraptor/vql" ) +var ( + notLockedDownError = errors.New("PERMISSION_DENIED: Server locked down") +) + // ServerACLManager is used when running server side VQL to control // ACLs on various VQL plugins. type ServerACLManager struct { @@ -25,10 +30,31 @@ func (self *ServerACLManager) GetPrincipal() string { return self.principal } +func (self *ServerACLManager) handleLockdown( + permissions []acls.ACL_PERMISSION) (bool, error) { + if acls.LockdownToken() == nil { + return false, nil + } + + for _, perm := range permissions { + ok, err := services.CheckAccessWithToken(acls.LockdownToken(), perm) + if err == nil && ok { + return false, notLockedDownError + } + } + return false, nil +} + // Token must have *ALL* the specified permissions. func (self *ServerACLManager) CheckAccess( permissions ...acls.ACL_PERMISSION) (bool, error) { + // If we are in lockdown, immediately reject permission + ok, err := self.handleLockdown(permissions) + if err != nil { + return ok, err + } + policy, err := self.getPolicyInOrg(self.config_obj.OrgId) if err != nil { return false, err diff --git a/vql/acls.go b/vql/acls.go index f684bd605f0..2aeab1fcc2e 100644 --- a/vql/acls.go +++ b/vql/acls.go @@ -45,8 +45,11 @@ func CheckAccess(scope vfilter.Scope, permissions ...acls.ACL_PERMISSION) error } perm, err := manager.CheckAccess(permissions...) - if !perm || err != nil { - return fmt.Errorf("Permission denied: %v", permissions) + if !perm { + if err == nil { + return fmt.Errorf("Permission denied: %v", permissions) + } + return fmt.Errorf("%v: %v", err, permissions) } return nil @@ -69,7 +72,10 @@ func CheckAccessInOrg(scope vfilter.Scope, org_id string, permissions ...acls.AC } perm, err := manager.CheckAccessInOrg(org_id, permissions...) - if !perm || err != nil { + if !perm { + if err != nil { + return fmt.Errorf("%v: %v", err, permissions) + } return fmt.Errorf("Permission denied: %v", permissions) } @@ -89,7 +95,10 @@ func CheckAccessWithArgs(scope vfilter.Scope, permissions acls.ACL_PERMISSION, } perm, err := manager.CheckAccessWithArgs(permissions, args...) - if !perm || err != nil { + if !perm { + if err != nil { + return fmt.Errorf("%v: %v", err, permissions) + } return fmt.Errorf("Permission denied: %v", permissions) }