diff --git a/accessors/vfs/vfs_test.go b/accessors/vfs/vfs_test.go
index 6e7ea5d90cf..c05f0b717b0 100644
--- a/accessors/vfs/vfs_test.go
+++ b/accessors/vfs/vfs_test.go
@@ -120,6 +120,7 @@ func (self *TestSuite) TestVFSAccessor() {
flow_id, err := launcher.ScheduleArtifactCollection(self.Ctx, self.ConfigObj,
acl_manager, repository, &flows_proto.ArtifactCollectorArgs{
Artifacts: []string{"System.VFS.ListDirectory", "System.VFS.DownloadFile"},
+ Creator: utils.GetSuperuserName(self.ConfigObj),
Specs: []*flows_proto.ArtifactSpec{
{
Artifact: "System.VFS.DownloadFile",
@@ -167,6 +168,7 @@ func (self *TestSuite) TestVFSAccessor() {
vtesting.WaitUntil(time.Second*5, self.T(), func() bool {
flow, err := launcher.GetFlowDetails(self.Ctx, self.ConfigObj, "server", flow_id)
assert.NoError(self.T(), err)
+
return flow.Context.State == flows_proto.ArtifactCollectorContext_FINISHED
})
diff --git a/api/api.go b/api/api.go
index ec6ad8a8e3e..5355151b02b 100644
--- a/api/api.go
+++ b/api/api.go
@@ -162,15 +162,12 @@ func (self *ApiServer) CollectArtifact(
if err != nil {
return nil, Status(self.verbose, err)
}
- principal := user_record.Name
- // Internal calls from the frontend can set the creator.
- if principal != org_config_obj.Client.PinnedServerName {
- in.Creator = principal
- }
+ // Ensure the request is marked with the real caller.
+ in.Creator = user_record.Name
acl_manager := acl_managers.NewServerACLManager(
- org_config_obj, principal)
+ org_config_obj, in.Creator)
manager, err := services.GetRepositoryManager(org_config_obj)
if err != nil {
@@ -198,7 +195,7 @@ func (self *ApiServer) CollectArtifact(
// Log this event as an Audit event.
services.LogAudit(ctx,
- org_config_obj, principal, "ScheduleFlow",
+ org_config_obj, in.Creator, "ScheduleFlow",
ordereddict.NewDict().
Set("client", in.ClientId).
Set("flow_id", flow_id).
diff --git a/api/authenticators/certs.go b/api/authenticators/certs.go
index cc442ce1e80..64aa4ba18de 100644
--- a/api/authenticators/certs.go
+++ b/api/authenticators/certs.go
@@ -84,11 +84,12 @@ import (
"github.com/gorilla/csrf"
acl_proto "www.velocidex.com/golang/velociraptor/acls/proto"
api_proto "www.velocidex.com/golang/velociraptor/api/proto"
- utils "www.velocidex.com/golang/velociraptor/api/utils"
+ api_utils "www.velocidex.com/golang/velociraptor/api/utils"
config_proto "www.velocidex.com/golang/velociraptor/config/proto"
"www.velocidex.com/golang/velociraptor/constants"
"www.velocidex.com/golang/velociraptor/json"
"www.velocidex.com/golang/velociraptor/services"
+ "www.velocidex.com/golang/velociraptor/utils"
)
var (
@@ -111,7 +112,7 @@ func (self *CertAuthenticator) AddHandlers(mux *http.ServeMux) error {
// It is not really possible to log off when using client certs
func (self *CertAuthenticator) AddLogoff(mux *http.ServeMux) error {
- mux.Handle(utils.Join(self.base, "/app/logoff.html"),
+ mux.Handle(api_utils.Join(self.base, "/app/logoff.html"),
IpFilter(self.config_obj,
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
@@ -187,7 +188,7 @@ func (self *CertAuthenticator) AuthenticateUserHandler(
// Use the super user principal to actually add the
// username so we have enough permissions.
err = users_manager.AddUserToOrg(r.Context(), services.AddNewUser,
- constants.PinnedServerName, username,
+ utils.GetSuperuserName(self.config_obj), username,
[]string{"root"}, policy)
if err != nil {
http.Error(w,
diff --git a/api/proxy.go b/api/proxy.go
index e9b0667da43..7dabc5ca46e 100644
--- a/api/proxy.go
+++ b/api/proxy.go
@@ -1,19 +1,19 @@
/*
- Velociraptor - Dig Deeper
- Copyright (C) 2019-2024 Rapid7 Inc.
+Velociraptor - Dig Deeper
+Copyright (C) 2019-2024 Rapid7 Inc.
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published
+by the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see .
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
*/
package api
@@ -34,13 +34,14 @@ import (
"google.golang.org/protobuf/encoding/protojson"
"www.velocidex.com/golang/velociraptor/api/authenticators"
api_proto "www.velocidex.com/golang/velociraptor/api/proto"
- utils "www.velocidex.com/golang/velociraptor/api/utils"
+ api_utils "www.velocidex.com/golang/velociraptor/api/utils"
config_proto "www.velocidex.com/golang/velociraptor/config/proto"
"www.velocidex.com/golang/velociraptor/constants"
crypto_utils "www.velocidex.com/golang/velociraptor/crypto/utils"
"www.velocidex.com/golang/velociraptor/grpc_client"
"www.velocidex.com/golang/velociraptor/logging"
"www.velocidex.com/golang/velociraptor/server"
+ "www.velocidex.com/golang/velociraptor/utils"
)
// A Mux for the reverse proxy feature.
@@ -140,50 +141,50 @@ func PrepareGUIMux(
return nil, err
}
- base := utils.GetBasePath(config_obj)
- mux.Handle(utils.Join(base, "/api/"), ipFilter(config_obj,
+ base := api_utils.GetBasePath(config_obj)
+ mux.Handle(api_utils.Join(base, "/api/"), ipFilter(config_obj,
csrfProtect(config_obj,
auther.AuthenticateUserHandler(h))))
- mux.Handle(utils.Join(base, "/api/v1/DownloadTable"),
+ mux.Handle(api_utils.Join(base, "/api/v1/DownloadTable"),
ipFilter(config_obj, csrfProtect(config_obj,
auther.AuthenticateUserHandler(downloadTable()))))
- mux.Handle(utils.Join(base, "/api/v1/DownloadVFSFile"),
+ mux.Handle(api_utils.Join(base, "/api/v1/DownloadVFSFile"),
ipFilter(config_obj, csrfProtect(config_obj,
auther.AuthenticateUserHandler(vfsFileDownloadHandler()))))
- mux.Handle(utils.Join(base, "/api/v1/UploadTool"),
+ mux.Handle(api_utils.Join(base, "/api/v1/UploadTool"),
ipFilter(config_obj, csrfProtect(config_obj,
auther.AuthenticateUserHandler(toolUploadHandler()))))
- mux.Handle(utils.Join(base, "/api/v1/UploadFormFile"),
+ mux.Handle(api_utils.Join(base, "/api/v1/UploadFormFile"),
ipFilter(config_obj, csrfProtect(config_obj,
auther.AuthenticateUserHandler(formUploadHandler()))))
// Serve prepared zip files.
- mux.Handle(utils.Join(base, "/downloads/"),
+ mux.Handle(api_utils.Join(base, "/downloads/"),
ipFilter(config_obj, csrfProtect(config_obj,
auther.AuthenticateUserHandler(
http.StripPrefix(base,
downloadFileStore([]string{"downloads"}))))))
// Serve notebook items
- mux.Handle(utils.Join(base, "/notebooks/"),
+ mux.Handle(api_utils.Join(base, "/notebooks/"),
ipFilter(config_obj, csrfProtect(config_obj,
auther.AuthenticateUserHandler(
http.StripPrefix(base,
downloadFileStore([]string{"notebooks"}))))))
// Serve files from hunt notebooks
- mux.Handle(utils.Join(base, "/hunts/"),
+ mux.Handle(api_utils.Join(base, "/hunts/"),
ipFilter(config_obj, csrfProtect(config_obj,
auther.AuthenticateUserHandler(
http.StripPrefix(base,
downloadFileStore([]string{"hunts"}))))))
// Serve files from client notebooks
- mux.Handle(utils.Join(base, "/clients/"),
+ mux.Handle(api_utils.Join(base, "/clients/"),
ipFilter(config_obj, csrfProtect(config_obj,
auther.AuthenticateUserHandler(
http.StripPrefix(base,
@@ -202,14 +203,14 @@ func PrepareGUIMux(
if err != nil {
return nil, err
}
- mux.Handle(utils.Join(base, "/app/index.html"),
+ mux.Handle(api_utils.Join(base, "/app/index.html"),
ipFilter(config_obj,
csrfProtect(config_obj, auther.AuthenticateUserHandler(h))))
// Redirect everything else to the app
- mux.Handle(utils.GetBaseDirectory(config_obj),
+ mux.Handle(api_utils.GetBaseDirectory(config_obj),
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- http.Redirect(w, r, utils.Join(base, "/app/index.html"), 302)
+ http.Redirect(w, r, api_utils.Join(base, "/app/index.html"), 302)
}))
return mux, nil
@@ -287,7 +288,7 @@ func GetAPIHandler(
creds := credentials.NewTLS(&tls.Config{
Certificates: []tls.Certificate{cert},
RootCAs: CA_Pool,
- ServerName: config_obj.Client.PinnedServerName,
+ ServerName: utils.GetSuperuserName(config_obj),
})
opts := []grpc.DialOption{
@@ -301,9 +302,9 @@ func GetAPIHandler(
return nil, err
}
- base := utils.GetBasePath(config_obj)
+ base := api_utils.GetBasePath(config_obj)
reverse_proxy_mux := http.NewServeMux()
- reverse_proxy_mux.Handle(utils.Join(base, "/api/v1/"),
+ reverse_proxy_mux.Handle(api_utils.Join(base, "/api/v1/"),
http.StripPrefix(base, grpc_proxy_mux))
return reverse_proxy_mux, nil
diff --git a/artifacts/testdata/windows/github_actions.config.yaml b/artifacts/testdata/windows/github_actions.config.yaml
index 3dc292b0399..8a9c2c6c009 100644
--- a/artifacts/testdata/windows/github_actions.config.yaml
+++ b/artifacts/testdata/windows/github_actions.config.yaml
@@ -140,6 +140,8 @@ Datastore:
implementation: FileBaseDataStore
filestore_directory: x:\artifacts\testdata\server
+defaults:
+ backup_period_seconds: -1
Writeback:
private_key: |
diff --git a/artifacts/testdata/windows/test.config.yaml b/artifacts/testdata/windows/test.config.yaml
index f498df0d77f..4ac69a43edc 100644
--- a/artifacts/testdata/windows/test.config.yaml
+++ b/artifacts/testdata/windows/test.config.yaml
@@ -141,6 +141,9 @@ Datastore:
filestore_directory: ./artifacts/testdata/server/
location: ./artifacts/testdata/server/
+defaults:
+ backup_period_seconds: -1
+
Writeback:
private_key: |
-----BEGIN RSA PRIVATE KEY-----
diff --git a/bin/config.go b/bin/config.go
index 257af97e160..fab5256861a 100644
--- a/bin/config.go
+++ b/bin/config.go
@@ -1,19 +1,19 @@
/*
- Velociraptor - Dig Deeper
- Copyright (C) 2019-2024 Rapid7 Inc.
+Velociraptor - Dig Deeper
+Copyright (C) 2019-2024 Rapid7 Inc.
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published
+by the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see .
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
*/
package main
@@ -34,13 +34,13 @@ import (
api_proto "www.velocidex.com/golang/velociraptor/api/proto"
"www.velocidex.com/golang/velociraptor/config"
config_proto "www.velocidex.com/golang/velociraptor/config/proto"
- "www.velocidex.com/golang/velociraptor/constants"
"www.velocidex.com/golang/velociraptor/crypto"
- "www.velocidex.com/golang/velociraptor/crypto/utils"
+ crypto_utils "www.velocidex.com/golang/velociraptor/crypto/utils"
"www.velocidex.com/golang/velociraptor/json"
"www.velocidex.com/golang/velociraptor/logging"
"www.velocidex.com/golang/velociraptor/services"
"www.velocidex.com/golang/velociraptor/startup"
+ "www.velocidex.com/golang/velociraptor/utils"
)
var (
@@ -221,7 +221,7 @@ func generateNewKeys(config_obj *config_proto.Config) error {
// have a constant common name - clients will refuse to talk
// with another common name.
frontend_cert, err := crypto.GenerateServerCert(
- config_obj, config_obj.Client.PinnedServerName)
+ config_obj, utils.GetSuperuserName(config_obj))
if err != nil {
return fmt.Errorf("Unable to create Frontend cert: %w", err)
}
@@ -292,7 +292,7 @@ func doRotateKeyConfig() error {
// Frontends must have a well known common name.
frontend_cert, err := crypto.GenerateServerCert(
- config_obj, config_obj.Client.PinnedServerName)
+ config_obj, utils.GetSuperuserName(config_obj))
if err != nil {
return fmt.Errorf("Unable to create Frontend cert: %w", err)
}
@@ -423,7 +423,7 @@ func doDumpApiClientConfig() error {
return err
}
- if *config_api_client_common_name == config_obj.Client.PinnedServerName {
+ if *config_api_client_common_name == utils.GetSuperuserName(config_obj) {
return errors.New("Name reserved! You may not name your " +
"api keys with this name.")
}
@@ -476,7 +476,7 @@ func doDumpApiClientConfig() error {
// Possibly dump out the pkcs12 key
if *config_api_client_pkcs12_output != "" {
- ca_cert, err := utils.ParseX509CertFromPemStr([]byte(
+ ca_cert, err := crypto_utils.ParseX509CertFromPemStr([]byte(
config_obj.Client.CaCertificate))
if err != nil {
return err
@@ -551,8 +551,8 @@ func doDumpApiClientConfig() error {
// Make sure the user actually exists.
user_manager := services.GetUserManager()
- _, err = user_manager.GetUser(ctx, constants.PinnedServerName,
- *config_api_client_common_name)
+ _, err = user_manager.GetUser(ctx,
+ utils.GetSuperuserName(config_obj), *config_api_client_common_name)
if err != nil {
// Need to ensure we have a user
err := user_manager.SetUser(ctx, &api_proto.VelociraptorUser{
diff --git a/bin/grant.go b/bin/grant.go
index debdec11e51..3f0c88a2532 100644
--- a/bin/grant.go
+++ b/bin/grant.go
@@ -8,7 +8,6 @@ import (
jsonpatch "github.com/evanphx/json-patch/v5"
"www.velocidex.com/golang/velociraptor/acls"
acl_proto "www.velocidex.com/golang/velociraptor/acls/proto"
- "www.velocidex.com/golang/velociraptor/constants"
"www.velocidex.com/golang/velociraptor/json"
logging "www.velocidex.com/golang/velociraptor/logging"
"www.velocidex.com/golang/velociraptor/services"
@@ -79,7 +78,8 @@ func doGrant() error {
// Check the user actually exists first
user_manager := services.GetUserManager()
- _, err = user_manager.GetUser(ctx, constants.PinnedServerName, principal)
+ _, err = user_manager.GetUser(ctx,
+ utils.GetSuperuserName(config_obj), principal)
if err != nil {
return err
}
diff --git a/bin/orgs.go b/bin/orgs.go
index 4fc53ccc7f5..0636927818b 100644
--- a/bin/orgs.go
+++ b/bin/orgs.go
@@ -4,11 +4,11 @@ import (
"fmt"
api_proto "www.velocidex.com/golang/velociraptor/api/proto"
- "www.velocidex.com/golang/velociraptor/constants"
"www.velocidex.com/golang/velociraptor/json"
logging "www.velocidex.com/golang/velociraptor/logging"
"www.velocidex.com/golang/velociraptor/services"
"www.velocidex.com/golang/velociraptor/startup"
+ "www.velocidex.com/golang/velociraptor/utils"
)
var (
@@ -88,7 +88,7 @@ func doOrgUserAdd() error {
user_manager := services.GetUserManager()
record, err := user_manager.GetUserWithHashes(
- ctx, constants.PinnedServerName, *orgs_user_add_user)
+ ctx, utils.GetSuperuserName(config_obj), *orgs_user_add_user)
if err != nil {
return err
}
@@ -181,7 +181,7 @@ func doOrgDelete() error {
logger.Info("Will remove org %v\n", *orgs_delete_org_id)
return org_manager.DeleteOrg(ctx,
- constants.PinnedServerName, *orgs_delete_org_id)
+ utils.GetSuperuserName(config_obj), *orgs_delete_org_id)
}
func init() {
diff --git a/bin/users.go b/bin/users.go
index 4a192c47f5c..4f8a1c8218f 100644
--- a/bin/users.go
+++ b/bin/users.go
@@ -1,19 +1,19 @@
/*
- Velociraptor - Dig Deeper
- Copyright (C) 2019-2024 Rapid7 Inc.
+Velociraptor - Dig Deeper
+Copyright (C) 2019-2024 Rapid7 Inc.
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published
+by the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see .
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
*/
package main
@@ -25,12 +25,12 @@ import (
"golang.org/x/crypto/ssh/terminal"
"www.velocidex.com/golang/velociraptor/api/authenticators"
- "www.velocidex.com/golang/velociraptor/constants"
"www.velocidex.com/golang/velociraptor/json"
logging "www.velocidex.com/golang/velociraptor/logging"
"www.velocidex.com/golang/velociraptor/services"
"www.velocidex.com/golang/velociraptor/services/users"
"www.velocidex.com/golang/velociraptor/startup"
+ "www.velocidex.com/golang/velociraptor/utils"
)
var (
@@ -153,15 +153,15 @@ func doShowUser() error {
defer sm.Close()
users_manager := services.GetUserManager()
- user_record, err := users_manager.GetUser(ctx, constants.PinnedServerName,
- *user_show_name)
+ user_record, err := users_manager.GetUser(ctx,
+ utils.GetSuperuserName(config_obj), *user_show_name)
if err != nil {
return err
}
if *user_show_hashes {
user_record, err := users_manager.GetUserWithHashes(ctx,
- constants.PinnedServerName, *user_show_name)
+ utils.GetSuperuserName(config_obj), *user_show_name)
if err != nil {
return err
}
@@ -200,8 +200,8 @@ func doLockUser() error {
defer sm.Close()
users_manager := services.GetUserManager()
- user_record, err := users_manager.GetUser(ctx, constants.PinnedServerName,
- *user_lock_name)
+ user_record, err := users_manager.GetUser(ctx,
+ utils.GetSuperuserName(config_obj), *user_lock_name)
if err != nil {
return fmt.Errorf("Unable to find user %s", *user_lock_name)
}
diff --git a/config/config.go b/config/config.go
index f5cae27066d..fd0a435ef82 100644
--- a/config/config.go
+++ b/config/config.go
@@ -1,19 +1,19 @@
/*
- Velociraptor - Dig Deeper
- Copyright (C) 2019-2024 Rapid7 Inc.
+Velociraptor - Dig Deeper
+Copyright (C) 2019-2024 Rapid7 Inc.
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published
+by the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see .
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
*/
package config
@@ -95,9 +95,8 @@ func GetDefaultConfig() *config_proto.Config {
// If set to true this will stop
// arbitrary code execution on the
// client.
- PreventExecve: false,
- MaxUploadSize: constants.MAX_MEMORY,
- PinnedServerName: "VelociraptorServer",
+ PreventExecve: false,
+ MaxUploadSize: constants.MAX_MEMORY,
},
API: &config_proto.APIConfig{
// Bind port for gRPC endpoint - this should not
diff --git a/config/validate.go b/config/validate.go
index 2a0b5ce5d23..6b299393dfb 100644
--- a/config/validate.go
+++ b/config/validate.go
@@ -48,10 +48,6 @@ func ValidateClientConfig(config_obj *config_proto.Config) error {
config_obj.Client.MaxPoll = 60 // One minute
}
- if config_obj.Client.PinnedServerName == "" {
- config_obj.Client.PinnedServerName = "VelociraptorServer"
- }
-
if config_obj.Client.MaxUploadSize == 0 {
config_obj.Client.MaxUploadSize = 5242880
}
diff --git a/crypto/crypto_test.go b/crypto/crypto_test.go
index ccc158652cd..67072059b32 100644
--- a/crypto/crypto_test.go
+++ b/crypto/crypto_test.go
@@ -1,19 +1,19 @@
/*
- Velociraptor - Dig Deeper
- Copyright (C) 2019-2024 Rapid7 Inc.
+Velociraptor - Dig Deeper
+Copyright (C) 2019-2024 Rapid7 Inc.
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published
+by the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see .
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
*/
package crypto_test
@@ -32,7 +32,6 @@ import (
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"google.golang.org/protobuf/proto"
- "www.velocidex.com/golang/velociraptor/config"
config_proto "www.velocidex.com/golang/velociraptor/config/proto"
"www.velocidex.com/golang/velociraptor/crypto/client"
crypto_client "www.velocidex.com/golang/velociraptor/crypto/client"
@@ -162,9 +161,8 @@ func (self *TestSuite) TestEncDecClientToServerWithSpoof() {
Source: "C.1234Spoof",
Name: "OMG it's a string"})
- ConfigObj := config.GetDefaultConfig()
cipher_text, err := self._EncryptMessageListWithSpoofedPackedMessage(
- message_list, ConfigObj.Client.PinnedServerName)
+ message_list, utils.GetSuperuserName(self.ConfigObj))
assert.NoError(t, err)
message_info, err := self.server_manager.Decrypt(cipher_text)
@@ -256,7 +254,7 @@ func (self *TestSuite) TestEncDecClientToServer() {
cipher_text, err := self.client_manager.EncryptMessageList(
message_list,
crypto_proto.PackedMessageList_ZCOMPRESSION,
- nonce, self.ConfigObj.Client.PinnedServerName)
+ nonce, utils.GetSuperuserName(self.ConfigObj))
assert.NoError(t, err)
initial_c := testutil.ToFloat64(crypto_client.RsaDecryptCounter)
@@ -296,7 +294,7 @@ func (self *TestSuite) TestEncryption() {
[][]byte{compressed},
crypto_proto.PackedMessageList_ZCOMPRESSION,
self.ConfigObj.Client.Nonce,
- self.ConfigObj.Client.PinnedServerName)
+ utils.GetSuperuserName(self.ConfigObj))
assert.NoError(t, err)
result, err := self.server_manager.Decrypt(cipher_text)
diff --git a/file_store/test_utils/server_config.go b/file_store/test_utils/server_config.go
index dc61af6952a..d254228d272 100644
--- a/file_store/test_utils/server_config.go
+++ b/file_store/test_utils/server_config.go
@@ -48,7 +48,6 @@ Client:
version: 0.6.4-rc4
commit: f3264824
build_time: "2022-04-14T02:23:05+10:00"
- pinned_server_name: VelociraptorServer
max_upload_size: 5242880
local_buffer:
memory_size: 52428800
@@ -254,6 +253,7 @@ obfuscation_nonce: RzlAlmdcUyw=
defaults:
hunt_expiry_hours: 168
notebook_cell_timeout_min: 10
+ backup_period_seconds: -1
services:
hunt_manager: false
diff --git a/flows/artifacts_test.go b/flows/artifacts_test.go
index 818e9e689e3..c2f8afa048b 100644
--- a/flows/artifacts_test.go
+++ b/flows/artifacts_test.go
@@ -90,11 +90,13 @@ func (self *TestSuite) TestGetFlow() {
request1 := &flows_proto.ArtifactCollectorArgs{
ClientId: self.client_id,
+ Creator: utils.GetSuperuserName(self.ConfigObj),
Artifacts: []string{"Generic.Client.Info"},
}
request2 := &flows_proto.ArtifactCollectorArgs{
ClientId: self.client_id,
+ Creator: utils.GetSuperuserName(self.ConfigObj),
Artifacts: []string{"Generic.Client.Profile"},
}
@@ -144,6 +146,7 @@ func (self *TestSuite) TestRetransmission() {
request := &flows_proto.ArtifactCollectorArgs{
ClientId: self.client_id,
+ Creator: utils.GetSuperuserName(self.ConfigObj),
Artifacts: []string{"Generic.Client.Info"},
}
@@ -202,6 +205,7 @@ func (self *TestSuite) TestResourceLimits() {
request := &flows_proto.ArtifactCollectorArgs{
ClientId: self.client_id,
+ Creator: utils.GetSuperuserName(self.ConfigObj),
Artifacts: []string{"Generic.Client.Info"},
// Only accept 5 rows.
diff --git a/grpc_client/grpc.go b/grpc_client/grpc.go
index c6f0771076c..2ce2e9b8377 100644
--- a/grpc_client/grpc.go
+++ b/grpc_client/grpc.go
@@ -34,7 +34,7 @@ import (
"google.golang.org/grpc/credentials"
api_proto "www.velocidex.com/golang/velociraptor/api/proto"
config_proto "www.velocidex.com/golang/velociraptor/config/proto"
- "www.velocidex.com/golang/velociraptor/constants"
+ "www.velocidex.com/golang/velociraptor/utils"
)
var (
@@ -71,17 +71,14 @@ func getCreds(config_obj *config_proto.Config) (credentials.TransportCredentials
certificate = config_obj.Frontend.Certificate
private_key = config_obj.Frontend.PrivateKey
ca_certificate = config_obj.Client.CaCertificate
- server_name = config_obj.Client.PinnedServerName
+ server_name = utils.GetSuperuserName(config_obj)
}
if config_obj.ApiConfig != nil &&
config_obj.ApiConfig.ClientCert != "" {
certificate = config_obj.ApiConfig.ClientCert
private_key = config_obj.ApiConfig.ClientPrivateKey
ca_certificate = config_obj.ApiConfig.CaCertificate
- server_name = config_obj.ApiConfig.PinnedServerName
- if server_name == "" {
- server_name = constants.PinnedServerName
- }
+ server_name = utils.GetSuperuserGWName(config_obj)
}
if certificate == "" {
diff --git a/http_comms/comms.go b/http_comms/comms.go
index 778b23e2c3e..30e8acd68f1 100644
--- a/http_comms/comms.go
+++ b/http_comms/comms.go
@@ -189,7 +189,7 @@ func NewHTTPConnector(
// server. This setting also allows the server to be accessed
// by e.g. localhost despite the certificate being issued to
// VelociraptorServer.
- transport.TLSClientConfig.ServerName = config_obj.Client.PinnedServerName
+ transport.TLSClientConfig.ServerName = utils.GetSuperuserName(config_obj)
} else {
// Not self signed - add the public roots for verifications.
crypto.AddPublicRoots(transport.TLSClientConfig.RootCAs)
@@ -533,7 +533,7 @@ func (self *HTTPConnector) rekeyNextServer(ctx context.Context) error {
// We must be talking to the server! The server certificate
// must have this common name.
- if server_name != self.config_obj.Client.PinnedServerName {
+ if server_name != utils.GetSuperuserName(self.config_obj) {
self.server_name = ""
self.logger.Info("Invalid server certificate common name %v!", server_name)
return errors.New("Invalid server certificate common name!")
diff --git a/http_comms/e2e_test.go b/http_comms/e2e_test.go
index a9e348ac21f..25f5d9e6b3b 100644
--- a/http_comms/e2e_test.go
+++ b/http_comms/e2e_test.go
@@ -230,6 +230,7 @@ func (self *TestSuite) testScheduleCollection() (closer func()) {
request := &flows_proto.ArtifactCollectorArgs{
ClientId: self.client_id,
Artifacts: []string{"TestArtifact"},
+ Creator: utils.GetSuperuserName(self.ConfigObj),
}
flow_id, err := launcher.ScheduleArtifactCollection(self.Ctx,
@@ -294,7 +295,7 @@ func (self *TestSuite) TestServerRotateKeyE2E() {
// Now rekey the server
frontend_cert, err := crypto.GenerateServerCert(
- self.ConfigObj, self.ConfigObj.Client.PinnedServerName)
+ self.ConfigObj, utils.GetSuperuserName(self.ConfigObj))
assert.NoError(self.T(), err)
self.ConfigObj.Frontend.Certificate = frontend_cert.Cert
diff --git a/http_comms/sender_test.go b/http_comms/sender_test.go
index 84c69d32828..ad55f8cc636 100644
--- a/http_comms/sender_test.go
+++ b/http_comms/sender_test.go
@@ -1,19 +1,19 @@
/*
- Velociraptor - Dig Deeper
- Copyright (C) 2019-2024 Rapid7 Inc.
+Velociraptor - Dig Deeper
+Copyright (C) 2019-2024 Rapid7 Inc.
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published
+by the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see .
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
*/
package http_comms
@@ -99,7 +99,7 @@ func (self *MockHTTPConnector) Post(ctx context.Context,
func (self *MockHTTPConnector) ReKeyNextServer(ctx context.Context) {}
func (self *MockHTTPConnector) ServerName() string {
- return "VelociraptorServer"
+ return utils.GetSuperuserName(self.config_obj)
}
// Try to send the message immediately.
diff --git a/http_comms/test_data/server.config.yaml b/http_comms/test_data/server.config.yaml
index be6dc795f01..55e152a631a 100644
--- a/http_comms/test_data/server.config.yaml
+++ b/http_comms/test_data/server.config.yaml
@@ -245,3 +245,4 @@ obfuscation_nonce: RzlAlmdcUyw=
defaults:
hunt_expiry_hours: 168
notebook_cell_timeout_min: 10
+ backup_period_seconds: -1
diff --git a/server/server_test.go b/server/server_test.go
index 41d55b1cd63..587b094b5dd 100644
--- a/server/server_test.go
+++ b/server/server_test.go
@@ -429,6 +429,7 @@ func (self *ServerTestSuite) TestScheduleCollection() {
t := self.T()
request := &flows_proto.ArtifactCollectorArgs{
ClientId: self.client_id,
+ Creator: utils.GetSuperuserName(self.ConfigObj),
Artifacts: []string{"Generic.Client.Info"},
}
@@ -490,6 +491,7 @@ func (self *ServerTestSuite) createArtifactCollection() (string, error) {
repository,
&flows_proto.ArtifactCollectorArgs{
ClientId: self.client_id,
+ Creator: utils.GetSuperuserName(self.ConfigObj),
Artifacts: []string{"Generic.Client.Info"},
}, nil)
diff --git a/services/acl_manager/acl_manager.go b/services/acl_manager/acl_manager.go
index fbd3823bdf4..035b80cd96a 100644
--- a/services/acl_manager/acl_manager.go
+++ b/services/acl_manager/acl_manager.go
@@ -45,6 +45,13 @@ func NewACLManager(
// ACLs do not typically change that quickly, cache for 60 sec.
result.lru.SetTTL(timeout)
+ backups, err := services.GetBackupService(config_obj)
+ if err == nil {
+ backups.Register(&ACLBackupProvider{
+ config_obj: config_obj,
+ })
+ }
+
return result, nil
}
@@ -89,8 +96,7 @@ func (self ACLManager) GetEffectivePolicy(
acl_obj := &acl_proto.ApiClientACL{}
// The server identity is special - it means the user is an admin.
- if config_obj != nil && config_obj.Client != nil &&
- config_obj.Client.PinnedServerName == principal {
+ if principal == utils.GetSuperuserName(config_obj) {
return &acl_proto.ApiClientACL{SuperUser: true}, nil
}
@@ -155,7 +161,7 @@ func (self ACLManager) CheckAccess(
}
// Internal calls from the server are allowed to do anything.
- if config_obj.Client != nil && principal == config_obj.Client.PinnedServerName {
+ if principal == utils.GetSuperuserName(config_obj) {
return true, nil
}
diff --git a/services/acl_manager/backup.go b/services/acl_manager/backup.go
new file mode 100644
index 00000000000..dee5625b085
--- /dev/null
+++ b/services/acl_manager/backup.go
@@ -0,0 +1,85 @@
+package acl_manager
+
+import (
+ "context"
+ "fmt"
+ "sync"
+
+ "github.com/Velocidex/ordereddict"
+ config_proto "www.velocidex.com/golang/velociraptor/config/proto"
+ "www.velocidex.com/golang/velociraptor/services"
+ "www.velocidex.com/golang/velociraptor/utils"
+ "www.velocidex.com/golang/vfilter"
+)
+
+type ACLBackupProvider struct {
+ config_obj *config_proto.Config
+ manager *ACLManager
+}
+
+func (self ACLBackupProvider) ProviderName() string {
+ return "ACLBackupProvider"
+}
+
+func (self ACLBackupProvider) Name() []string {
+ return []string{"acls.json"}
+}
+
+func (self ACLBackupProvider) BackupResults(
+ ctx context.Context, wg *sync.WaitGroup) (
+ <-chan vfilter.Row, error) {
+
+ users_manager := services.GetUserManager()
+ user_list, err := users_manager.ListUsers(ctx,
+ // Superuser privileges ....
+ utils.GetSuperuserName(self.config_obj),
+
+ // Only export current org.
+ []string{utils.GetOrgId(self.config_obj)})
+ if err != nil {
+ return nil, err
+ }
+
+ output := make(chan vfilter.Row)
+
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ defer close(output)
+
+ for _, user := range user_list {
+ policy, err := self.manager.GetPolicy(
+ self.config_obj, user.Name)
+ if err == nil {
+ select {
+ case <-ctx.Done():
+ return
+
+ case output <- ordereddict.NewDict().
+ Set("Principal", user).
+ Set("Policy", policy):
+ }
+ }
+ }
+ }()
+
+ return output, nil
+}
+
+// We do not want to automatically restore ACL permissions from backup
+// because this may represent a security compromise but we want to
+// allow users to see the ACL permissions that were backed up.
+func (self ACLBackupProvider) Restore(ctx context.Context,
+ in <-chan vfilter.Row) (stat services.BackupStat, err error) {
+
+ count := 0
+ defer func() {
+ stat.Message = fmt.Sprintf("ACL backups do not automatically restore. There are %v ACL records which may be restored manually.", count)
+ }()
+
+ for _ = range in {
+ count++
+ }
+
+ return stat, nil
+}
diff --git a/services/backup/backup.go b/services/backup/backup.go
index 5b6e276f2e8..a4e04184359 100644
--- a/services/backup/backup.go
+++ b/services/backup/backup.go
@@ -151,6 +151,8 @@ func (self *BackupService) RestoreBackup(
dest := strings.Join(provider.Name(), "/")
logger.Info("BackupService: Error restoring to %v: %v",
dest, err)
+ stat.Name = provider.ProviderName()
+ stat.Error = err
}
stats = append(stats, stat)
}
@@ -161,6 +163,7 @@ func (self *BackupService) RestoreBackup(
func (self *BackupService) feedProvider(
provider services.BackupProvider,
container *zip.Reader) (stat services.BackupStat, err error) {
+
dest := strings.Join(provider.Name(), "/")
member, err := container.Open(dest)
if err != nil {
@@ -175,6 +178,18 @@ func (self *BackupService) feedProvider(
wg := &sync.WaitGroup{}
defer wg.Wait()
+ // The provider will return a result when done.
+ results := make(chan services.BackupStat)
+ defer func() {
+ // Wait here until the provider is done.
+ stat = <-results
+ stat.Name = provider.ProviderName()
+ if stat.Error != nil {
+ err = stat.Error
+ }
+ }()
+
+ // Feed rows into this channel so provider can restore backups.
output := make(chan vfilter.Row)
defer close(output)
@@ -184,14 +199,19 @@ func (self *BackupService) feedProvider(
wg.Add(1)
go func() {
defer wg.Done()
- defer cancel()
+ defer close(results)
// Preserve the provider error as our return
- stat, err = provider.Restore(sub_ctx, output)
- stat.Name = provider.ProviderName()
+ stat, err := provider.Restore(sub_ctx, output)
if err != nil {
stat.Error = err
}
+
+ // Stop new rows to be written - we dont care any more.
+ cancel()
+
+ // Pass the result to the main routine.
+ results <- stat
}()
// Now dump the rows into the provider.
@@ -213,6 +233,7 @@ func (self *BackupService) feedProvider(
select {
case <-sub_ctx.Done():
return stat, nil
+
case output <- row:
}
}
@@ -238,10 +259,16 @@ func NewBackupService(
// Every day
delay := time.Hour * 24
- if config_obj.Defaults != nil &&
- config_obj.Defaults.BackupPeriodSeconds > 0 {
- delay = time.Duration(
- config_obj.Defaults.BackupPeriodSeconds) * time.Second
+ if config_obj.Defaults != nil {
+ // Backups are disabled.
+ if config_obj.Defaults.BackupPeriodSeconds < 0 {
+ return result
+ }
+
+ if config_obj.Defaults.BackupPeriodSeconds > 0 {
+ delay = time.Duration(
+ config_obj.Defaults.BackupPeriodSeconds) * time.Second
+ }
}
logger := logging.GetLogger(config_obj, &logging.FrontendComponent)
diff --git a/services/backup/backup_test.go b/services/backup/backup_test.go
index 2d956ed27db..f6f730afc98 100644
--- a/services/backup/backup_test.go
+++ b/services/backup/backup_test.go
@@ -3,6 +3,7 @@ package backup_test
import (
"archive/zip"
"context"
+ "errors"
"io/ioutil"
"strings"
"sync"
@@ -30,7 +31,8 @@ type TestBackupProvider struct {
rows []*ordereddict.Dict
// Restored rows from backup
- restored []vfilter.Row
+ restored []vfilter.Row
+ restored_error error
}
func (self TestBackupProvider) ProviderName() string {
@@ -62,6 +64,14 @@ func (self TestBackupProvider) BackupResults(
func (self *TestBackupProvider) Restore(
ctx context.Context, in <-chan vfilter.Row) (services.BackupStat, error) {
+
+ if self.restored_error != nil {
+ return services.BackupStat{
+ Error: self.restored_error,
+ Message: self.restored_error.Error(),
+ }, self.restored_error
+ }
+
for row := range in {
self.restored = append(self.restored, row)
}
@@ -130,6 +140,17 @@ func (self *BackupTestSuite) TestBackups() {
golden.Set("RestoredTestProvider", provider.restored).
Set("RestoredTestProviderStats", filterStats(stats))
+ // Now restore the data from backup with an error
+ provider.restored_error = errors.New("I have an error")
+ provider.restored = nil
+
+ stats, err = backup_service.(*backup.BackupService).
+ RestoreBackup(export_path)
+ assert.NoError(self.T(), err)
+
+ golden.Set("RestoredTestProvider With Error", provider.restored).
+ Set("RestoredTestProviderStatsWithError", filterStats(stats))
+
goldie.Assert(self.T(), "TestBackups",
json.MustMarshalIndent(golden))
}
diff --git a/services/backup/fixtures/TestBackups.golden b/services/backup/fixtures/TestBackups.golden
index 28fa026f171..fb26753b662 100644
--- a/services/backup/fixtures/TestBackups.golden
+++ b/services/backup/fixtures/TestBackups.golden
@@ -22,5 +22,13 @@
"Error": null,
"Message": "All good!"
}
+ ],
+ "RestoredTestProvider With Error": null,
+ "RestoredTestProviderStatsWithError": [
+ {
+ "Name": "TestProvider",
+ "Error": {},
+ "Message": "I have an error"
+ }
]
}
\ No newline at end of file
diff --git a/services/sanity/sanity.go b/services/sanity/sanity.go
index 1bbfb0da546..d8268580ec1 100644
--- a/services/sanity/sanity.go
+++ b/services/sanity/sanity.go
@@ -74,14 +74,12 @@ func (self *SanityChecks) CheckRootOrg(
// Make sure our internal VelociraptorServer service account is
// properly created. Default accounts are created with org admin
// so they can add new orgs as required.
- if config_obj.Client != nil && config_obj.Client.PinnedServerName != "" {
- service_account_name := config_obj.Client.PinnedServerName
- err := services.GrantRoles(
- config_obj, service_account_name,
- []string{"administrator", "org_admin"})
- if err != nil {
- return err
- }
+ service_account_name := utils.GetSuperuserName(config_obj)
+ err = services.GrantRoles(
+ config_obj, service_account_name,
+ []string{"administrator", "org_admin"})
+ if err != nil {
+ return err
}
if config_obj.Frontend != nil {
diff --git a/services/sanity/sanity_test.go b/services/sanity/sanity_test.go
index 5ba81c48fcb..52e474f5fff 100644
--- a/services/sanity/sanity_test.go
+++ b/services/sanity/sanity_test.go
@@ -125,7 +125,8 @@ func (self *ServicesTestSuite) TestCreateUser() {
Set("/acl/User1.json", acl_obj)
user_manager := services.GetUserManager()
- user1_full, err := user_manager.GetUserWithHashes(self.Ctx, "VelociraptorServer", "User1")
+ user1_full, err := user_manager.GetUserWithHashes(
+ self.Ctx, utils.GetSuperuserName(self.ConfigObj), "User1")
assert.NoError(self.T(), err)
// Should include the user hashes and their orgs list
@@ -198,7 +199,8 @@ func (self *ServicesTestSuite) TestCreateUserInOrgs() {
}
user_manager := services.GetUserManager()
- user1_full, err := user_manager.GetUserWithHashes(self.Ctx, "VelociraptorServer", "User1")
+ user1_full, err := user_manager.GetUserWithHashes(
+ self.Ctx, utils.GetSuperuserName(self.ConfigObj), "User1")
assert.NoError(self.T(), err)
// Should include the user hashes and all their orgs list
diff --git a/services/sanity/server_artifacts.go b/services/sanity/server_artifacts.go
index 9e32fd14d11..0b3f81a253e 100644
--- a/services/sanity/server_artifacts.go
+++ b/services/sanity/server_artifacts.go
@@ -13,6 +13,7 @@ import (
"www.velocidex.com/golang/velociraptor/logging"
"www.velocidex.com/golang/velociraptor/paths"
"www.velocidex.com/golang/velociraptor/services"
+ "www.velocidex.com/golang/velociraptor/utils"
"www.velocidex.com/golang/velociraptor/vql/acl_managers"
)
@@ -84,11 +85,7 @@ func startInitialArtifacts(
logger := logging.GetLogger(config_obj, &logging.FrontendComponent)
// Run artifacts with full privileges.
- principal := ""
- if config_obj.Client != nil {
- principal = config_obj.Client.PinnedServerName
- }
-
+ principal := utils.GetSuperuserName(config_obj)
_, err = launcher.ScheduleArtifactCollection(ctx, config_obj,
acl_managers.NewRoleACLManager(config_obj, "administrator"),
repository,
diff --git a/services/sanity/users.go b/services/sanity/users.go
index 07f3276cec7..6ec17d6377c 100644
--- a/services/sanity/users.go
+++ b/services/sanity/users.go
@@ -21,11 +21,7 @@ func createInitialUsers(
return nil
}
- superuser := "VelociraptorServer"
- if config_obj.Client != nil {
- superuser = config_obj.Client.PinnedServerName
- }
-
+ superuser := utils.GetSuperuserName(config_obj)
user_names := config_obj.GUI.InitialUsers
logger := logging.GetLogger(config_obj, &logging.FrontendComponent)
diff --git a/services/server_artifacts/collection_context.go b/services/server_artifacts/collection_context.go
index e9c42ef4ec8..43db484a174 100644
--- a/services/server_artifacts/collection_context.go
+++ b/services/server_artifacts/collection_context.go
@@ -354,8 +354,8 @@ func (self *contextManager) RunQuery(
}
principal := arg.Principal
- if principal == "" && self.config_obj.Client != nil {
- principal = self.config_obj.Client.PinnedServerName
+ if principal == "" {
+ return errors.New("Principal must be set")
}
flow_path_manager := paths.NewFlowPathManager("server", self.session_id)
diff --git a/services/server_monitoring/server_monitoring.go b/services/server_monitoring/server_monitoring.go
index 16555919f58..92db6396713 100644
--- a/services/server_monitoring/server_monitoring.go
+++ b/services/server_monitoring/server_monitoring.go
@@ -338,8 +338,7 @@ func (self *EventTable) RunQuery(
// artifact launches other artifacts then it will indicate the
// creator was the server.
ACLManager: acl_managers.NewServerACLManager(
- self.config_obj,
- self.config_obj.Client.PinnedServerName),
+ self.config_obj, utils.GetSuperuserName(config_obj)),
Env: ordereddict.NewDict(),
Repository: repository,
Logger: log.New(self.logger, "", 0),
diff --git a/services/server_monitoring/server_monitoring_test.go b/services/server_monitoring/server_monitoring_test.go
index f41fbdaa2db..15bf1d9ec91 100644
--- a/services/server_monitoring/server_monitoring_test.go
+++ b/services/server_monitoring/server_monitoring_test.go
@@ -360,7 +360,7 @@ sources:
// Install a table with an initial artifact
filename := filepath.Join(tempdir, "testfile1.txt")
err = event_table.Update(self.Ctx,
- self.ConfigObj, "VelociraptorServer",
+ self.ConfigObj, utils.GetSuperuserName(self.ConfigObj),
&flows_proto.ArtifactCollectorArgs{
Artifacts: []string{"TestArtifact"},
Specs: []*flows_proto.ArtifactSpec{{
diff --git a/services/users/add_org_test.go b/services/users/add_org_test.go
index 85fc4dd74f5..b325c271ffd 100644
--- a/services/users/add_org_test.go
+++ b/services/users/add_org_test.go
@@ -6,6 +6,7 @@ import (
acl_proto "www.velocidex.com/golang/velociraptor/acls/proto"
"www.velocidex.com/golang/velociraptor/json"
"www.velocidex.com/golang/velociraptor/services"
+ "www.velocidex.com/golang/velociraptor/utils"
"www.velocidex.com/golang/velociraptor/vtesting/assert"
)
@@ -77,7 +78,8 @@ func (self *UserManagerTestSuite) TestAddUserToOrg() {
// Try to create a reserved user
err = users_manager.AddUserToOrg(
self.Ctx, services.AddNewUser,
- "AdminO2", "VelociraptorServer", []string{"O2"}, reader_policy)
+ "AdminO2", utils.GetSuperuserName(self.ConfigObj),
+ []string{"O2"}, reader_policy)
assert.ErrorContains(self.T(), err, "reserved")
goldie.Assert(self.T(), "TestAddUserToOrg", json.MustMarshalIndent(golden))
diff --git a/services/users/get.go b/services/users/get.go
index 1b69e9d6d01..a7daecde1de 100644
--- a/services/users/get.go
+++ b/services/users/get.go
@@ -6,6 +6,7 @@ import (
"www.velocidex.com/golang/velociraptor/acls"
api_proto "www.velocidex.com/golang/velociraptor/api/proto"
"www.velocidex.com/golang/velociraptor/services"
+ "www.velocidex.com/golang/velociraptor/utils"
)
// Returns the user record after stripping sensitive information like
@@ -22,7 +23,7 @@ func (self *UserManager) GetUser(
// For the server name we dont have a real user record, we make a
// hard coded user record instead.
- if username == self.config_obj.Client.PinnedServerName {
+ if username == utils.GetSuperuserName(self.config_obj) {
return &api_proto.VelociraptorUser{
Name: username,
}, nil
diff --git a/services/users/grpc.go b/services/users/grpc.go
index 230934fc926..3d8f2e604da 100644
--- a/services/users/grpc.go
+++ b/services/users/grpc.go
@@ -25,9 +25,8 @@ func (self UserManager) GetUserFromContext(ctx context.Context) (
// This is not a real user but represents the grpc gateway
// connection - it is always allowed.
- if grpc_user_info.Name == constants.PinnedServerName ||
- (self.config_obj.API != nil &&
- self.config_obj.API.PinnedGwName == grpc_user_info.Name) {
+ if grpc_user_info.Name == utils.GetSuperuserName(org_config_obj) ||
+ grpc_user_info.Name == utils.GetSuperuserGWName(org_config_obj) {
user_record = &api_proto.VelociraptorUser{
Name: grpc_user_info.Name,
}
diff --git a/services/users/users.go b/services/users/users.go
index f822d89723b..5ada640abdf 100644
--- a/services/users/users.go
+++ b/services/users/users.go
@@ -1,19 +1,19 @@
/*
- Velociraptor - Dig Deeper
- Copyright (C) 2019-2024 Rapid7 Inc.
+Velociraptor - Dig Deeper
+Copyright (C) 2019-2024 Rapid7 Inc.
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published
+by the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see .
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
*/
package users
@@ -28,9 +28,9 @@ import (
api_proto "www.velocidex.com/golang/velociraptor/api/proto"
config_proto "www.velocidex.com/golang/velociraptor/config/proto"
- "www.velocidex.com/golang/velociraptor/constants"
"www.velocidex.com/golang/velociraptor/logging"
"www.velocidex.com/golang/velociraptor/services"
+ "www.velocidex.com/golang/velociraptor/utils"
)
const (
@@ -103,17 +103,16 @@ func validateUsername(config_obj *config_proto.Config, name string) error {
return fmt.Errorf("Unacceptable username %v", name)
}
- if config_obj.API != nil &&
- config_obj.API.PinnedGwName == name {
+ if utils.GetSuperuserName(config_obj) == name {
return fmt.Errorf("Username is reserved: %v", name)
}
- if config_obj.Client != nil &&
- config_obj.Client.PinnedServerName == name {
+ if config_obj.API != nil &&
+ config_obj.API.PinnedGwName == name {
return fmt.Errorf("Username is reserved: %v", name)
}
- if name == constants.PinnedGwName || name == constants.PinnedServerName {
+ if name == utils.GetSuperuserGWName(config_obj) {
return fmt.Errorf("Username is reserved: %v", name)
}
diff --git a/services/vfs_service/vfs_service_test.go b/services/vfs_service/vfs_service_test.go
index a6857325e22..41734882afc 100644
--- a/services/vfs_service/vfs_service_test.go
+++ b/services/vfs_service/vfs_service_test.go
@@ -54,7 +54,8 @@ func (self *VFSServiceTestSuite) SetupTest() {
// Register a user manager that returns the superuser user to skip
// any ACLs checks. This helps us test the API server to make sure
// the GUI will present the correct data.
- users.RegisterTestUserManager(self.ConfigObj, "VelociraptorServer")
+ users.RegisterTestUserManager(
+ self.ConfigObj, utils.GetSuperuserName(self.ConfigObj))
self.closer = utils.MockTime(utils.NewMockClock(time.Unix(1000, 0)))
}
diff --git a/utils/orgs.go b/utils/orgs.go
index 1a0ed9e7cc4..43b34f1cffa 100644
--- a/utils/orgs.go
+++ b/utils/orgs.go
@@ -65,3 +65,7 @@ func OrgIdInList(org_id string, list []string) bool {
}
return false
}
+
+func GetOrgId(config_obj *config_proto.Config) string {
+ return NormalizedOrgId(config_obj.OrgId)
+}
diff --git a/utils/users.go b/utils/users.go
new file mode 100644
index 00000000000..806c2e5ebaa
--- /dev/null
+++ b/utils/users.go
@@ -0,0 +1,28 @@
+package utils
+
+import (
+ config_proto "www.velocidex.com/golang/velociraptor/config/proto"
+ "www.velocidex.com/golang/velociraptor/constants"
+)
+
+func GetSuperuserName(
+ config_obj *config_proto.Config) string {
+ if config_obj == nil ||
+ config_obj.Client == nil ||
+ config_obj.Client.PinnedServerName == "" {
+ return constants.PinnedServerName
+ }
+
+ return config_obj.Client.PinnedServerName
+}
+
+func GetSuperuserGWName(
+ config_obj *config_proto.Config) string {
+ if config_obj == nil ||
+ config_obj.API == nil ||
+ config_obj.API.PinnedGwName == "" {
+ return constants.PinnedGwName
+ }
+
+ return config_obj.API.PinnedGwName
+}
diff --git a/vql/acl_managers/null.go b/vql/acl_managers/null.go
index ebeecbd9e33..46ad40d0a2d 100644
--- a/vql/acl_managers/null.go
+++ b/vql/acl_managers/null.go
@@ -1,6 +1,9 @@
package acl_managers
-import "www.velocidex.com/golang/velociraptor/acls"
+import (
+ "www.velocidex.com/golang/velociraptor/acls"
+ "www.velocidex.com/golang/velociraptor/constants"
+)
// Satisfy the interface vql_subsystem.ACLManager
@@ -23,3 +26,7 @@ func (self NullACLManager) CheckAccessInOrg(
org_id string, permission ...acls.ACL_PERMISSION) (bool, error) {
return true, nil
}
+
+func (self NullACLManager) GetPrincipal() string {
+ return constants.PinnedServerName
+}
diff --git a/vql/acl_managers/role.go b/vql/acl_managers/role.go
index 0d5fda28616..06374888c86 100644
--- a/vql/acl_managers/role.go
+++ b/vql/acl_managers/role.go
@@ -4,7 +4,6 @@ import (
"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/constants"
"www.velocidex.com/golang/velociraptor/services"
"www.velocidex.com/golang/velociraptor/utils"
vql_subsystem "www.velocidex.com/golang/velociraptor/vql"
@@ -33,7 +32,7 @@ func (self *RoleACLManager) CheckAccess(
func (self *RoleACLManager) GetPrincipal() string {
if self.is_admin {
- return constants.PinnedServerName
+ return utils.GetSuperuserName(self.config_obj)
}
return ""
}
diff --git a/vql/acl_managers/server.go b/vql/acl_managers/server.go
index 24552abe1d9..47c0f7fc222 100644
--- a/vql/acl_managers/server.go
+++ b/vql/acl_managers/server.go
@@ -8,6 +8,7 @@ import (
acl_proto "www.velocidex.com/golang/velociraptor/acls/proto"
config_proto "www.velocidex.com/golang/velociraptor/config/proto"
"www.velocidex.com/golang/velociraptor/services"
+ "www.velocidex.com/golang/velociraptor/utils"
vql_subsystem "www.velocidex.com/golang/velociraptor/vql"
)
@@ -65,8 +66,7 @@ func (self *ServerACLManager) CheckAccess(
}
// If the principal is the super user we allow them everything.
- if self.config_obj.Client != nil &&
- self.principal == self.config_obj.Client.PinnedServerName {
+ if self.principal == utils.GetSuperuserName(self.config_obj) {
return true, nil
}
diff --git a/vql/networking/tls.go b/vql/networking/tls.go
index 7a3c5b5adda..5f4bcfeb7a4 100644
--- a/vql/networking/tls.go
+++ b/vql/networking/tls.go
@@ -53,7 +53,7 @@ func normalizeThumbPrints(thumbprints []string) []string {
// to be able to trust our own server. Our own server is signed by our
// own CA and also may have a different common name (not related to
// DNS). For example, in self signed mode, the server certificate is
-// signed for VelociraptorServer but may be served over
+// signed for "VelociraptorServer" but may be served over
// "localhost". Using the default TLS configuration this connection
// will be rejected.
diff --git a/vql/server/downloads/downloads_test.go b/vql/server/downloads/downloads_test.go
index 25ab88c5f87..fba6badc4a4 100644
--- a/vql/server/downloads/downloads_test.go
+++ b/vql/server/downloads/downloads_test.go
@@ -106,6 +106,7 @@ func (self *TestSuite) TestExportCollectionServerArtifact() {
self.acl_manager,
repository, &flows_proto.ArtifactCollectorArgs{
Artifacts: []string{"TestArtifact"},
+ Creator: utils.GetSuperuserName(self.ConfigObj),
ClientId: "server",
}, utils.SyncCompleter)
assert.NoError(self.T(), err)
diff --git a/vql/server/downloads/fixtures/TestExportCollectionServerArtifact.golden b/vql/server/downloads/fixtures/TestExportCollectionServerArtifact.golden
index 182ec45ea57..233e8e5716a 100644
--- a/vql/server/downloads/fixtures/TestExportCollectionServerArtifact.golden
+++ b/vql/server/downloads/fixtures/TestExportCollectionServerArtifact.golden
@@ -6,6 +6,7 @@
"client_id": "server",
"session_id": "F.1234",
"request": {
+ "creator": "VelociraptorServer",
"client_id": "server",
"artifacts": [
"TestArtifact"
@@ -92,6 +93,7 @@
{
"query_id": 1,
"total_queries": 1,
+ "principal": "VelociraptorServer",
"Query": [
{
"VQL": "LET TestArtifact_0_0 = SELECT \"Hello\" AS Col, pathspec(parse=\"/bin/ls\", path_type=\"linux\") AS OSPath, upload(accessor=\"data\", file=\"Some Data\", name=\"test.txt\") AS Upload1, upload(accessor=\"data\", file=\"Some Other Data\", name=\"test2.txt\") AS Upload2 FROM scope()"
diff --git a/vql/server/flows/parallel_test.go b/vql/server/flows/parallel_test.go
index ed825ef97b2..2517bb90e7b 100644
--- a/vql/server/flows/parallel_test.go
+++ b/vql/server/flows/parallel_test.go
@@ -171,6 +171,7 @@ func (self *TestSuite) TestHuntsSource() {
self.ConfigObj, acl_managers.NullACLManager{},
repository, &flows_proto.ArtifactCollectorArgs{
ClientId: client_id,
+ Creator: utils.GetSuperuserName(self.ConfigObj),
Artifacts: []string{"Test.Artifact"},
}, nil)
assert.NoError(self.T(), err)
diff --git a/vql/tools/collector/import_hunt_test.go b/vql/tools/collector/import_hunt_test.go
index 0a928b11176..b67a442f9b8 100644
--- a/vql/tools/collector/import_hunt_test.go
+++ b/vql/tools/collector/import_hunt_test.go
@@ -103,6 +103,7 @@ func (self *TestSuite) TestCreateAndImportHunt() {
flow_id, err := launcher.ScheduleArtifactCollection(self.Ctx, self.ConfigObj,
acl_manager, repository, &flows_proto.ArtifactCollectorArgs{
Artifacts: []string{"TestArtifact", "AnotherTestArtifact"},
+ Creator: utils.GetSuperuserName(self.ConfigObj),
ClientId: "server",
}, utils.SyncCompleter)
assert.NoError(self.T(), err)
diff --git a/vql/tools/collector/import_test.go b/vql/tools/collector/import_test.go
index 8cfc4ce3b5a..1d79d87ee9c 100644
--- a/vql/tools/collector/import_test.go
+++ b/vql/tools/collector/import_test.go
@@ -61,6 +61,7 @@ func (self *TestSuite) TestCreateAndImportCollection() {
flow_id, err := launcher.ScheduleArtifactCollection(self.Ctx, self.ConfigObj,
acl_manager, repository, &flows_proto.ArtifactCollectorArgs{
Artifacts: []string{"TestArtifact", "AnotherTestArtifact"},
+ Creator: utils.GetSuperuserName(self.ConfigObj),
ClientId: client_id,
}, utils.SyncCompleter)
assert.NoError(self.T(), err)