forked from Velocidex/velociraptor
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhunt_dispatcher.go
161 lines (128 loc) · 5.25 KB
/
hunt_dispatcher.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/*
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 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 <https://www.gnu.org/licenses/>.
*/
package services
// The hunt dispatcher service maintains in-memory information about
// active hunts. This is a time critical service designed to avoid
// locking as much as possible, since it is in the critical path of
// client requests.
import (
"context"
"os"
api_proto "www.velocidex.com/golang/velociraptor/api/proto"
config_proto "www.velocidex.com/golang/velociraptor/config/proto"
"www.velocidex.com/golang/velociraptor/result_sets"
"www.velocidex.com/golang/velociraptor/utils"
vql_subsystem "www.velocidex.com/golang/velociraptor/vql"
"www.velocidex.com/golang/vfilter"
)
var (
HuntNotFoundError = utils.Wrap(os.ErrNotExist, "Hunt no found")
)
// How was the hunt modified and what should be done about it?
type HuntModificationAction int
const (
// No modifications made - just ignore the changes.
HuntUnmodified HuntModificationAction = iota
// Changes should be propagated to all other hunt dispatchers on
// all frontends.
HuntPropagateChanges
// Hunt was changed - all other hunt dispatchers should trigger
// participation for this hunt. Used when a hunt is started.
HuntTriggerParticipation
// Just write to data store but do not propagate (good for very
// frequent changes).
HuntFlushToDatastore
// Arrange for the change to be eventually written to the data
// store but not right away. Useful for very low priority events.
HuntFlushToDatastoreAsync
)
type HuntSearchOptions int
const (
AllHunts HuntSearchOptions = iota
// Only visit non expired hunts
OnlyRunningHunts
)
type FlowSearchOptions struct {
result_sets.ResultSetOptions
// Additional Options for efficient search.
// BasicInformation includes only client id and flow id.
BasicInformation bool
}
type IHuntDispatcher interface {
// Applies the function on all the hunts. Functions may not
// modify the hunt but will have read only access to the hunt
// objects under lock.
ApplyFuncOnHunts(ctx context.Context, options HuntSearchOptions,
cb func(hunt *api_proto.Hunt) error) error
// As an optimization callers may get the latest hunt's
// timestamp. If the client's last hunt id is earlier than
// this then we need to find out exactly which hunt is missing
// from the client. Most of the time, clients will be up to
// date on the latest hunt version and this will be a noop.
GetLastTimestamp() uint64
// Modify a hunt under lock. The hunt will be synchronized to all
// frontends. Return HuntModificationAction to indicate if the
// hunt was modified.
// This function can only be called on the master node.
ModifyHuntObject(ctx context.Context, hunt_id string,
cb func(hunt *api_proto.Hunt) HuntModificationAction,
) HuntModificationAction
// Modify a hunt by sending a mutation. This function can be
// called anywhere (minion or master).
ModifyHunt(ctx context.Context,
config_obj *config_proto.Config,
hunt_modification *api_proto.Hunt,
user string) error
// Gets read only access to the hunt object.
GetHunt(ctx context.Context,
hunt_id string) (*api_proto.Hunt, bool)
// Paged view into the flows in the hunt
GetFlows(ctx context.Context, config_obj *config_proto.Config,
options FlowSearchOptions, scope vfilter.Scope,
hunt_id string, start int) (
output chan *api_proto.FlowDetails, total_rows int64, err error)
CreateHunt(ctx context.Context,
config_obj *config_proto.Config,
acl_manager vql_subsystem.ACLManager,
hunt *api_proto.Hunt) (*api_proto.Hunt, error)
// Deprecated - use GetHunts for paged access
ListHunts(ctx context.Context,
config_obj *config_proto.Config,
in *api_proto.ListHuntsRequest) (*api_proto.ListHuntsResponse, error)
// Paged access to hunts
GetHunts(ctx context.Context,
config_obj *config_proto.Config,
options result_sets.ResultSetOptions,
start_row, length int64) ([]*api_proto.Hunt, int64, error)
// Send a mutation to a hunt object. Mutations allow the minions
// to send updates to the master node which applies the change.
MutateHunt(ctx context.Context,
config_obj *config_proto.Config,
mutation *api_proto.HuntMutation) error
// Re-read the hunts from the data store. This happens
// periodically and can also be triggered when a change is
// written to the datastore (e.g. new hunt scheduled) to pick
// up the latest hunts.
Refresh(ctx context.Context, config_obj *config_proto.Config) error
// Clean up and close the hunt dispatcher. Only used in tests.
Close(ctx context.Context)
}
func GetHuntDispatcher(config_obj *config_proto.Config) (IHuntDispatcher, error) {
org_manager, err := GetOrgManager()
if err != nil {
return nil, err
}
return org_manager.Services(config_obj.OrgId).HuntDispatcher()
}