diff --git a/actions/proto/vql.pb.go b/actions/proto/vql.pb.go index 249168dd8da..350e57fe42a 100644 --- a/actions/proto/vql.pb.go +++ b/actions/proto/vql.pb.go @@ -152,6 +152,10 @@ type VQLCollectorArgs struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // The principal that created this request - only sent when + // scheduling the server so the server may keep track on who ran + // each query. + Principal string `protobuf:"bytes,28,opt,name=principal,proto3" json:"principal,omitempty"` Env []*VQLEnv `protobuf:"bytes,3,rep,name=env,proto3" json:"env,omitempty"` Query []*VQLRequest `protobuf:"bytes,2,rep,name=Query,proto3" json:"Query,omitempty"` MaxRow uint64 `protobuf:"varint,4,opt,name=max_row,json=maxRow,proto3" json:"max_row,omitempty"` @@ -196,6 +200,13 @@ func (*VQLCollectorArgs) Descriptor() ([]byte, []int) { return file_vql_proto_rawDescGZIP(), []int{2} } +func (x *VQLCollectorArgs) GetPrincipal() string { + if x != nil { + return x.Principal + } + return "" +} + func (x *VQLCollectorArgs) GetEnv() []*VQLEnv { if x != nil { return x.Env @@ -707,171 +718,173 @@ var file_vql_proto_rawDesc = []byte{ 0x0a, 0x06, 0x56, 0x51, 0x4c, 0x45, 0x6e, 0x76, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x22, 0xb5, 0x08, 0x0a, 0x10, 0x56, 0x51, 0x4c, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, - 0x72, 0x41, 0x72, 0x67, 0x73, 0x12, 0x5c, 0x0a, 0x03, 0x65, 0x6e, 0x76, 0x18, 0x03, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x51, 0x4c, 0x45, 0x6e, - 0x76, 0x42, 0x3b, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x35, 0x12, 0x33, 0x45, 0x6e, 0x76, 0x69, 0x72, - 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, - 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, - 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x03, - 0x65, 0x6e, 0x76, 0x12, 0x5a, 0x0a, 0x05, 0x51, 0x75, 0x65, 0x72, 0x79, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x51, 0x4c, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x42, 0x31, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x2b, 0x12, 0x29, 0x54, - 0x68, 0x65, 0x20, 0x56, 0x51, 0x4c, 0x20, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x20, 0x74, - 0x6f, 0x20, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x52, 0x05, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, - 0x9d, 0x01, 0x0a, 0x07, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x6f, 0x77, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x04, 0x42, 0x83, 0x01, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x7d, 0x12, 0x62, 0x54, 0x68, 0x65, 0x20, - 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x20, 0x72, 0x6f, 0x77, 0x73, 0x20, 0x70, 0x65, 0x72, - 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x20, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x73, 0x20, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, - 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x73, 0x70, - 0x6c, 0x69, 0x74, 0x20, 0x61, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, - 0x70, 0x6c, 0x65, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x2e, 0x22, 0x11, - 0x4d, 0x61, 0x78, 0x20, 0x72, 0x6f, 0x77, 0x73, 0x20, 0x70, 0x65, 0x72, 0x20, 0x70, 0x61, 0x72, - 0x74, 0x32, 0x04, 0x31, 0x30, 0x30, 0x30, 0x52, 0x06, 0x6d, 0x61, 0x78, 0x52, 0x6f, 0x77, 0x12, - 0xcb, 0x01, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x04, 0x42, 0xaf, 0x01, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0xa8, 0x01, 0x12, 0x7d, 0x46, 0x6f, - 0x72, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x20, 0x77, - 0x65, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, - 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x74, - 0x68, 0x69, 0x73, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x2e, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, - 0x73, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x65, - 0x76, 0x65, 0x6e, 0x74, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x20, 0x77, - 0x68, 0x69, 0x63, 0x68, 0x20, 0x6e, 0x65, 0x76, 0x65, 0x72, 0x20, 0x72, 0x65, 0x61, 0x6c, 0x6c, - 0x79, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x2e, 0x22, 0x23, 0x42, 0x61, 0x74, - 0x63, 0x68, 0x20, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, - 0x20, 0x74, 0x61, 0x6b, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x2e, - 0x32, 0x02, 0x31, 0x30, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x57, 0x61, 0x69, 0x74, 0x12, 0xc8, 0x01, - 0x0a, 0x0e, 0x6f, 0x70, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, - 0x18, 0x18, 0x20, 0x01, 0x28, 0x02, 0x42, 0xa1, 0x01, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x9a, 0x01, - 0x12, 0x97, 0x01, 0x41, 0x6e, 0x20, 0x4f, 0x70, 0x20, 0x69, 0x73, 0x20, 0x64, 0x65, 0x66, 0x69, - 0x6e, 0x65, 0x64, 0x20, 0x61, 0x73, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x61, 0x72, 0x62, 0x69, - 0x74, 0x72, 0x61, 0x72, 0x79, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x77, 0x6f, - 0x72, 0x6b, 0x2e, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x73, 0x20, - 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, 0x6c, 0x69, 0x6d, 0x69, 0x74, - 0x65, 0x64, 0x2e, 0x20, 0x54, 0x79, 0x70, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x56, 0x51, - 0x4c, 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x6f, 0x70, 0x73, 0x20, 0x74, 0x6f, 0x77, 0x61, 0x72, 0x64, 0x73, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x71, 0x75, 0x65, 0x72, 0x79, 0x20, 0x61, 0x73, 0x20, 0x61, 0x70, - 0x70, 0x72, 0x6f, 0x70, 0x72, 0x69, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x0c, 0x6f, 0x70, 0x73, 0x50, - 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x12, 0x6e, 0x0a, 0x09, 0x61, 0x72, 0x74, 0x69, - 0x66, 0x61, 0x63, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x42, 0x3f, 0xe2, 0xfc, - 0xe3, 0xc4, 0x01, 0x39, 0x12, 0x37, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x20, - 0x73, 0x65, 0x6e, 0x74, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x68, 0x65, 0x6c, 0x70, 0x20, 0x77, 0x69, 0x74, - 0x68, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x09, 0x61, - 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x44, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, - 0x6f, 0x75, 0x74, 0x18, 0x19, 0x20, 0x01, 0x28, 0x04, 0x42, 0x2a, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, - 0x24, 0x12, 0x22, 0x4d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, - 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x71, 0x75, 0x65, 0x72, 0x79, 0x20, 0x74, 0x6f, - 0x20, 0x72, 0x75, 0x6e, 0x2e, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x1c, - 0x0a, 0x09, 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x18, 0x1b, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x09, 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x12, 0x4b, 0x0a, 0x05, - 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x18, 0x1a, 0x20, 0x03, 0x28, 0x09, 0x42, 0x35, 0xe2, 0xfc, 0xe3, - 0xc4, 0x01, 0x2f, 0x12, 0x2d, 0x41, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, - 0x6f, 0x6f, 0x6c, 0x73, 0x20, 0x77, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x6e, 0x65, 0x65, - 0x64, 0x20, 0x74, 0x6f, 0x20, 0x72, 0x75, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x56, 0x51, - 0x4c, 0x2e, 0x52, 0x05, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x3a, 0x0d, 0xea, 0x87, 0x20, 0x09, 0x0a, - 0x07, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x22, 0x38, 0x0a, 0x0a, 0x56, 0x51, 0x4c, 0x54, - 0x79, 0x70, 0x65, 0x4d, 0x61, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x12, 0x12, - 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x22, 0xa0, 0x06, 0x0a, 0x0b, 0x56, 0x51, 0x4c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x1e, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x18, 0x12, 0x16, 0x4a, 0x53, - 0x4f, 0x4e, 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, - 0x0a, 0x0d, 0x4a, 0x53, 0x4f, 0x4e, 0x4c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, - 0x0a, 0x20, 0x01, 0x28, 0x09, 0x42, 0x1e, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x18, 0x12, 0x16, 0x4a, - 0x53, 0x4f, 0x4e, 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x20, 0x72, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x0d, 0x4a, 0x53, 0x4f, 0x4e, 0x4c, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x52, 0x0a, 0x07, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x09, 0x42, 0x38, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x32, 0x12, 0x30, 0x41, - 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x20, - 0x68, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, - 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, - 0x07, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x12, 0x5e, 0x0a, 0x05, 0x74, 0x79, 0x70, 0x65, - 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, - 0x56, 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, 0x4d, 0x61, 0x70, 0x42, 0x35, 0xe2, 0xfc, 0xe3, 0xc4, - 0x01, 0x2f, 0x12, 0x2d, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x20, 0x62, 0x65, 0x74, 0x77, - 0x65, 0x65, 0x6e, 0x20, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, - 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x69, 0x72, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x2e, 0x52, 0x05, 0x74, 0x79, 0x70, 0x65, 0x73, 0x12, 0x52, 0x0a, 0x08, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x42, 0x37, 0xe2, 0xfc, 0xe3, 0xc4, - 0x01, 0x31, 0x12, 0x2f, 0x43, 0x68, 0x72, 0x6f, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, - 0x6c, 0x20, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x71, - 0x75, 0x65, 0x72, 0x79, 0x20, 0x77, 0x65, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x20, - 0x74, 0x6f, 0x2e, 0x52, 0x07, 0x71, 0x75, 0x65, 0x72, 0x79, 0x49, 0x64, 0x12, 0x74, 0x0a, 0x04, - 0x70, 0x61, 0x72, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x42, 0x60, 0xe2, 0xfc, 0xe3, 0xc4, - 0x01, 0x5a, 0x12, 0x58, 0x4c, 0x61, 0x72, 0x67, 0x65, 0x20, 0x56, 0x51, 0x4c, 0x20, 0x72, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x73, 0x70, 0x6c, 0x69, - 0x74, 0x20, 0x61, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x20, 0x6d, 0x61, 0x6e, 0x79, 0x20, 0x70, 0x61, - 0x72, 0x74, 0x73, 0x2e, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x63, 0x61, 0x72, 0x72, 0x69, 0x65, - 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, - 0x69, 0x73, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x04, 0x70, 0x61, - 0x72, 0x74, 0x12, 0x4d, 0x0a, 0x05, 0x51, 0x75, 0x65, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x51, 0x4c, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x42, 0x24, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x1e, 0x12, 0x1c, 0x54, 0x68, - 0x65, 0x20, 0x71, 0x75, 0x65, 0x72, 0x79, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x77, 0x61, 0x73, - 0x20, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x64, 0x2e, 0x52, 0x05, 0x51, 0x75, 0x65, 0x72, - 0x79, 0x12, 0x5c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x04, 0x42, 0x3e, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x38, 0x0a, 0x0b, 0x52, 0x44, - 0x46, 0x44, 0x61, 0x74, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x29, 0x54, 0x68, 0x65, 0x20, 0x74, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x20, 0x77, 0x61, 0x73, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, - 0x74, 0x65, 0x64, 0x2e, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, - 0x52, 0x0a, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x07, 0x20, - 0x01, 0x28, 0x04, 0x42, 0x33, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x2d, 0x12, 0x2b, 0x54, 0x6f, 0x74, - 0x61, 0x6c, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x72, 0x6f, 0x77, - 0x73, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x20, 0x70, 0x61, 0x72, 0x74, 0x2e, 0x52, 0x09, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x52, - 0x6f, 0x77, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x6c, 0x6f, 0x67, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x6c, 0x6f, 0x67, 0x22, 0x45, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x3d, 0x0a, - 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, - 0x21, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x1b, 0x12, 0x19, 0x54, 0x68, 0x65, 0x20, 0x75, 0x73, 0x65, - 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x73, 0x65, - 0x72, 0x2e, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xaa, 0x01, 0x0a, - 0x0d, 0x56, 0x51, 0x4c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x55, - 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x51, 0x4c, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, - 0x6f, 0x72, 0x41, 0x72, 0x67, 0x73, 0x42, 0x26, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x20, 0x12, 0x1e, - 0x41, 0x20, 0x73, 0x65, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x20, 0x71, - 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x72, 0x75, 0x6e, 0x2e, 0x52, 0x05, - 0x65, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x42, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x42, 0x28, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x22, 0x12, 0x20, - 0x54, 0x68, 0x65, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, - 0x68, 0x69, 0x73, 0x20, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, - 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xfb, 0x02, 0x0a, 0x0a, 0x43, 0x6c, - 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x71, 0x64, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x66, 0x71, 0x64, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x18, 0x0a, - 0x07, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x72, 0x63, 0x68, 0x69, - 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x61, - 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x69, - 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x69, 0x70, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x69, - 0x6e, 0x67, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x25, - 0x0a, 0x0e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, - 0x18, 0x0f, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x37, - 0x0a, 0x18, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x6f, 0x67, 0x61, - 0x74, 0x65, 0x5f, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x69, 0x64, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x15, 0x6c, 0x61, 0x73, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x6f, 0x67, 0x61, 0x74, - 0x65, 0x46, 0x6c, 0x6f, 0x77, 0x49, 0x64, 0x42, 0x35, 0x5a, 0x33, 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, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x22, 0xd3, 0x08, 0x0a, 0x10, 0x56, 0x51, 0x4c, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x41, 0x72, 0x67, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, + 0x61, 0x6c, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, + 0x70, 0x61, 0x6c, 0x12, 0x5c, 0x0a, 0x03, 0x65, 0x6e, 0x76, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x0d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x51, 0x4c, 0x45, 0x6e, 0x76, 0x42, + 0x3b, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x35, 0x12, 0x33, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, + 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x20, 0x74, + 0x6f, 0x20, 0x62, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x66, 0x6f, + 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x03, 0x65, 0x6e, + 0x76, 0x12, 0x5a, 0x0a, 0x05, 0x51, 0x75, 0x65, 0x72, 0x79, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x51, 0x4c, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x42, 0x31, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x2b, 0x12, 0x29, 0x54, 0x68, 0x65, + 0x20, 0x56, 0x51, 0x4c, 0x20, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x20, 0x74, 0x6f, 0x20, + 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x52, 0x05, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x9d, 0x01, + 0x0a, 0x07, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x6f, 0x77, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x42, + 0x83, 0x01, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x7d, 0x12, 0x62, 0x54, 0x68, 0x65, 0x20, 0x6d, 0x61, + 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x20, 0x72, 0x6f, 0x77, 0x73, 0x20, 0x70, 0x65, 0x72, 0x20, 0x72, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x20, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x73, 0x20, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x20, 0x74, + 0x68, 0x69, 0x73, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x73, 0x70, 0x6c, 0x69, + 0x74, 0x20, 0x61, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, + 0x65, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x2e, 0x22, 0x11, 0x4d, 0x61, + 0x78, 0x20, 0x72, 0x6f, 0x77, 0x73, 0x20, 0x70, 0x65, 0x72, 0x20, 0x70, 0x61, 0x72, 0x74, 0x32, + 0x04, 0x31, 0x30, 0x30, 0x30, 0x52, 0x06, 0x6d, 0x61, 0x78, 0x52, 0x6f, 0x77, 0x12, 0xcb, 0x01, + 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, + 0x42, 0xaf, 0x01, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0xa8, 0x01, 0x12, 0x7d, 0x46, 0x6f, 0x72, 0x20, + 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x20, 0x77, 0x65, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x69, + 0x73, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x2e, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, + 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x20, 0x77, 0x68, 0x69, + 0x63, 0x68, 0x20, 0x6e, 0x65, 0x76, 0x65, 0x72, 0x20, 0x72, 0x65, 0x61, 0x6c, 0x6c, 0x79, 0x20, + 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x2e, 0x22, 0x23, 0x42, 0x61, 0x74, 0x63, 0x68, + 0x20, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, + 0x61, 0x6b, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x2e, 0x32, 0x02, + 0x31, 0x30, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x57, 0x61, 0x69, 0x74, 0x12, 0xc8, 0x01, 0x0a, 0x0e, + 0x6f, 0x70, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x18, 0x18, + 0x20, 0x01, 0x28, 0x02, 0x42, 0xa1, 0x01, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x9a, 0x01, 0x12, 0x97, + 0x01, 0x41, 0x6e, 0x20, 0x4f, 0x70, 0x20, 0x69, 0x73, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, + 0x64, 0x20, 0x61, 0x73, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x61, 0x72, 0x62, 0x69, 0x74, 0x72, + 0x61, 0x72, 0x79, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x77, 0x6f, 0x72, 0x6b, + 0x2e, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x73, 0x20, 0x77, 0x6f, + 0x72, 0x6b, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, + 0x2e, 0x20, 0x54, 0x79, 0x70, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x56, 0x51, 0x4c, 0x20, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x20, 0x6f, 0x70, 0x73, 0x20, 0x74, 0x6f, 0x77, 0x61, 0x72, 0x64, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x71, 0x75, 0x65, 0x72, 0x79, 0x20, 0x61, 0x73, 0x20, 0x61, 0x70, 0x70, 0x72, + 0x6f, 0x70, 0x72, 0x69, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x0c, 0x6f, 0x70, 0x73, 0x50, 0x65, 0x72, + 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x12, 0x6e, 0x0a, 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x42, 0x3f, 0xe2, 0xfc, 0xe3, 0xc4, + 0x01, 0x39, 0x12, 0x37, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x20, 0x73, 0x65, + 0x6e, 0x74, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x68, 0x65, 0x6c, 0x70, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x20, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x09, 0x61, 0x72, 0x74, + 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x44, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, + 0x74, 0x18, 0x19, 0x20, 0x01, 0x28, 0x04, 0x42, 0x2a, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x24, 0x12, + 0x22, 0x4d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x66, 0x6f, + 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x71, 0x75, 0x65, 0x72, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x72, + 0x75, 0x6e, 0x2e, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x1c, 0x0a, 0x09, + 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x09, 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x12, 0x4b, 0x0a, 0x05, 0x74, 0x6f, + 0x6f, 0x6c, 0x73, 0x18, 0x1a, 0x20, 0x03, 0x28, 0x09, 0x42, 0x35, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, + 0x2f, 0x12, 0x2d, 0x41, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x6f, 0x6f, + 0x6c, 0x73, 0x20, 0x77, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x6e, 0x65, 0x65, 0x64, 0x20, + 0x74, 0x6f, 0x20, 0x72, 0x75, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x56, 0x51, 0x4c, 0x2e, + 0x52, 0x05, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x3a, 0x0d, 0xea, 0x87, 0x20, 0x09, 0x0a, 0x07, 0x47, + 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x22, 0x38, 0x0a, 0x0a, 0x56, 0x51, 0x4c, 0x54, 0x79, 0x70, + 0x65, 0x4d, 0x61, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x12, 0x12, 0x0a, 0x04, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x22, 0xa0, 0x06, 0x0a, 0x0b, 0x56, 0x51, 0x4c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x3a, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x1e, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x18, 0x12, 0x16, 0x4a, 0x53, 0x4f, 0x4e, + 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x2e, 0x52, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0d, + 0x4a, 0x53, 0x4f, 0x4e, 0x4c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x0a, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x1e, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x18, 0x12, 0x16, 0x4a, 0x53, 0x4f, + 0x4e, 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x2e, 0x52, 0x0d, 0x4a, 0x53, 0x4f, 0x4e, 0x4c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x52, 0x0a, 0x07, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x09, 0x42, 0x38, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x32, 0x12, 0x30, 0x41, 0x20, 0x6c, + 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x20, 0x68, 0x65, + 0x61, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x64, 0x20, + 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x07, 0x43, + 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x12, 0x5e, 0x0a, 0x05, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, + 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x51, + 0x4c, 0x54, 0x79, 0x70, 0x65, 0x4d, 0x61, 0x70, 0x42, 0x35, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x2f, + 0x12, 0x2d, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, + 0x6e, 0x20, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x69, 0x72, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x52, + 0x05, 0x74, 0x79, 0x70, 0x65, 0x73, 0x12, 0x52, 0x0a, 0x08, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, + 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x42, 0x37, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x31, + 0x12, 0x2f, 0x43, 0x68, 0x72, 0x6f, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x20, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x71, 0x75, 0x65, + 0x72, 0x79, 0x20, 0x77, 0x65, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x20, 0x74, 0x6f, + 0x2e, 0x52, 0x07, 0x71, 0x75, 0x65, 0x72, 0x79, 0x49, 0x64, 0x12, 0x74, 0x0a, 0x04, 0x70, 0x61, + 0x72, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x42, 0x60, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x5a, + 0x12, 0x58, 0x4c, 0x61, 0x72, 0x67, 0x65, 0x20, 0x56, 0x51, 0x4c, 0x20, 0x72, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x20, + 0x61, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x20, 0x6d, 0x61, 0x6e, 0x79, 0x20, 0x70, 0x61, 0x72, 0x74, + 0x73, 0x2e, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x63, 0x61, 0x72, 0x72, 0x69, 0x65, 0x73, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, + 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x04, 0x70, 0x61, 0x72, 0x74, + 0x12, 0x4d, 0x0a, 0x05, 0x51, 0x75, 0x65, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x51, 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x42, 0x24, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x1e, 0x12, 0x1c, 0x54, 0x68, 0x65, 0x20, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x77, 0x61, 0x73, 0x20, 0x65, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x64, 0x2e, 0x52, 0x05, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, + 0x5c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x04, 0x42, 0x3e, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x38, 0x0a, 0x0b, 0x52, 0x44, 0x46, 0x44, + 0x61, 0x74, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x29, 0x54, 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x20, 0x77, 0x61, 0x73, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, + 0x64, 0x2e, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x52, 0x0a, + 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x04, 0x42, 0x33, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x2d, 0x12, 0x2b, 0x54, 0x6f, 0x74, 0x61, 0x6c, + 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x72, 0x6f, 0x77, 0x73, 0x20, + 0x69, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x20, 0x70, 0x61, 0x72, 0x74, 0x2e, 0x52, 0x09, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x52, 0x6f, 0x77, + 0x73, 0x12, 0x10, 0x0a, 0x03, 0x6c, 0x6f, 0x67, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6c, 0x6f, 0x67, 0x22, 0x45, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x3d, 0x0a, 0x08, 0x75, + 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x21, 0xe2, + 0xfc, 0xe3, 0xc4, 0x01, 0x1b, 0x12, 0x19, 0x54, 0x68, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x6e, + 0x61, 0x6d, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x2e, + 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xaa, 0x01, 0x0a, 0x0d, 0x56, + 0x51, 0x4c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x55, 0x0a, 0x05, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x51, 0x4c, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x41, 0x72, 0x67, 0x73, 0x42, 0x26, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x20, 0x12, 0x1e, 0x41, 0x20, + 0x73, 0x65, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x20, 0x71, 0x75, 0x65, + 0x72, 0x69, 0x65, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x72, 0x75, 0x6e, 0x2e, 0x52, 0x05, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x12, 0x42, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x04, 0x42, 0x28, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x22, 0x12, 0x20, 0x54, 0x68, + 0x65, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, + 0x73, 0x20, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x52, 0x07, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xfb, 0x02, 0x0a, 0x0a, 0x43, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x66, 0x71, 0x64, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, + 0x71, 0x64, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x18, 0x0a, 0x07, 0x72, + 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, + 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, + 0x63, 0x74, 0x75, 0x72, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x72, 0x63, + 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x70, 0x5f, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, + 0x70, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x69, 0x6e, 0x67, + 0x18, 0x0b, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x25, 0x0a, 0x0e, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0c, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x0f, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x18, + 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x6f, 0x67, 0x61, 0x74, 0x65, + 0x5f, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x69, 0x64, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, + 0x6c, 0x61, 0x73, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x6f, 0x67, 0x61, 0x74, 0x65, 0x46, + 0x6c, 0x6f, 0x77, 0x49, 0x64, 0x42, 0x35, 0x5a, 0x33, 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, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/actions/proto/vql.proto b/actions/proto/vql.proto index cdaa0eada04..0b4c23e0921 100644 --- a/actions/proto/vql.proto +++ b/actions/proto/vql.proto @@ -30,6 +30,12 @@ message VQLCollectorArgs { option (flow_metadata) = { category: "Generic"; }; + + // The principal that created this request - only sent when + // scheduling the server so the server may keep track on who ran + // each query. + string principal = 28; + repeated VQLEnv env = 3 [(sem_type) = { description: "Environment variables to be provided for the query.", }]; diff --git a/api/api.go b/api/api.go index fe9b8256f98..5001052f4b4 100644 --- a/api/api.go +++ b/api/api.go @@ -482,9 +482,15 @@ func (self *ApiServer) NotifyClients( "User is not allowed to launch flows.") } + notifier := services.GetNotifier() + if notifier == nil { + return nil, errors.New("Notifier not ready") + } + if in.NotifyAll { self.server_obj.Info("sending notification to everyone") - err = services.GetNotifier().NotifyAllListeners(self.config) + err = notifier.NotifyAllListeners(self.config) + } else if in.ClientId != "" { self.server_obj.Info("sending notification to %s", in.ClientId) err = services.GetNotifier().NotifyListener(self.config, in.ClientId) diff --git a/artifacts/definitions/Server/Utils/ImportCollection.yaml b/artifacts/definitions/Server/Utils/ImportCollection.yaml new file mode 100644 index 00000000000..a4eda62923c --- /dev/null +++ b/artifacts/definitions/Server/Utils/ImportCollection.yaml @@ -0,0 +1,49 @@ +name: Server.Utils.ImportCollection +description: | + The Velociraptor offline collector is an automated, preconfigured + collection tool. Users can use the collector to automatically + collect any artifacts on endpoints that do not have the Velociraptor + client (offline endpoints). + + The collector creates a ZIP archive with the results of the + collection in JSON files (and any uploaded files). + + This artifact allows for these offline collections to be imported + back into the Velociraptor GUI. The collected data can then treated + exactly the same as if it was collected by the regular Velociraptor + client (i.e. post processed through the notebook interface), except + it was collected via the Sneakernet. + + NOTE: This artifact reads the collection ZIP from the server's + filesystem. It is up to you to arrange for the file to be stored on + the server (e.g. scp it over). + + NOTE: This artifact is still experimental - please provide feedback + on our issue board. + +type: SERVER + +parameters: + - name: ClientId + default: auto + description: | + The client id to upload this collection into. The + default is "auto" which will create a new client id. + - name: Hostname + description: If creating a new client, this must contain the hostname. + - name: Path + description: A path on the server containing the zip file to upload. + +sources: + - query: | + LET result = SELECT import_collection( + client_id=ClientId, hostname=Hostname, + filename=Path) AS Import + FROM scope() + + SELECT Import.client_id AS ClientId, Import.session_id AS FlowId, + Import.total_collected_rows AS TotalRows, + Import.total_uploaded_files AS UploadedFiles, + Import.total_uploaded_bytes AS UploadedBytes, + Import.artifacts_with_results AS Artifacts + FROM result diff --git a/bin/config_interactive.go b/bin/config_interactive.go index cf1c344939e..67c18de23d7 100644 --- a/bin/config_interactive.go +++ b/bin/config_interactive.go @@ -65,7 +65,7 @@ What OS will the server be deployed on? } // https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/naming-conventions-for-computer-domain-site-ou#dns-host-names - url_validator = regexValidator("^[a-z0-9.A-Z]+$") + url_validator = regexValidator("^[a-z0-9.A-Z\\-]+$") port_question = &survey.Input{ Message: "Enter the frontend port to listen on.", Default: "8000", @@ -397,8 +397,11 @@ func dynDNSConfig(config_obj *config_proto.Config) error { } func configAutocert(config_obj *config_proto.Config) error { - err := survey.Ask([]*survey.Question{ - {Name: "Hostname", Prompt: url_question}, + err := survey.Ask([]*survey.Question{{ + Name: "Hostname", + Validate: url_validator, + Prompt: url_question, + }, }, config_obj.Frontend) if err != nil { return err diff --git a/flows/hunts.go b/flows/hunts.go index 5bafb4f4e13..9e6f0d0a6e3 100644 --- a/flows/hunts.go +++ b/flows/hunts.go @@ -164,9 +164,14 @@ func CreateHunt( // set it started. } else if hunt.State == api_proto.Hunt_RUNNING { hunt.StartTime = hunt.CreateTime - err = services.GetNotifier().NotifyAllListeners(config_obj) - if err != nil { - return "", err + + // Notify all the clients. + notifier := services.GetNotifier() + if notifier != nil { + err = notifier.NotifyByRegex(config_obj, "^[Cc]\\.") + if err != nil { + return "", err + } } } @@ -353,5 +358,9 @@ func ModifyHunt( // Notify all the clients about the new hunt. New hunts are // not that common so notifying all the clients at once is // probably ok. - return services.GetNotifier().NotifyAllListeners(config_obj) + notifier := services.GetNotifier() + if notifier == nil { + return errors.New("Notifier not ready") + } + return notifier.NotifyByRegex(config_obj, "^[Cc]\\.") } diff --git a/go.mod b/go.mod index 866196441e6..35f4d24697b 100644 --- a/go.mod +++ b/go.mod @@ -117,8 +117,8 @@ require ( www.velocidex.com/golang/go-prefetch v0.0.0-20200722101157-37e4751dd5ca www.velocidex.com/golang/oleparse v0.0.0-20190327031422-34195d413196 www.velocidex.com/golang/regparser v0.0.0-20190625082115-b02dc43c2500 - www.velocidex.com/golang/vfilter v0.0.0-20210111083751-13cae4a7330c - www.velocidex.com/golang/vtypes v0.0.0-20210108052555-8a27f80edada + www.velocidex.com/golang/vfilter v0.0.0-20210114050946-1e02dba2abec + www.velocidex.com/golang/vtypes v0.0.0-20210114034841-b184d28b61b7 ) // replace www.velocidex.com/golang/go-pe => /home/mic/projects/go-pe diff --git a/go.sum b/go.sum index dcccec46ebf..3caf97772b3 100644 --- a/go.sum +++ b/go.sum @@ -77,6 +77,8 @@ github.com/Velocidex/ordereddict v0.0.0-20200723153557-9460a6764ab8 h1:wRt5CLsj5 github.com/Velocidex/ordereddict v0.0.0-20200723153557-9460a6764ab8/go.mod h1:pxJpvN5ISMtDwrdIdqnJ3ZrjIngCw+WT6gfNil6Zjvo= github.com/Velocidex/survey v1.8.7-0.20190926071832-2ff99cc7aa49 h1:TJVN1zYl5sKJUq571gYqU/5VqFIap9MUo2KNujc0fcg= github.com/Velocidex/survey v1.8.7-0.20190926071832-2ff99cc7aa49/go.mod h1:kfPUQ2gP0xtIydiR52dirNYt4OvCr+iZuepL4XaIk58= +github.com/Velocidex/yaml v2.1.0+incompatible h1:XtpJSzJ95+UbheJ5ZwHZOUH8sHhYpypGaL3zmaL2klc= +github.com/Velocidex/yaml v2.1.0+incompatible/go.mod h1:CzH+PG+PA8o7RiH4/ZkHx5rHDWFZlzZVc3R6pe/gJMg= github.com/Velocidex/yaml/v2 v2.2.5 h1:8XZwR8tmm5UWAXotI3fL17s9fjKEMqZ293fgqUiMhBw= github.com/Velocidex/yaml/v2 v2.2.5/go.mod h1:VBjrsTMc/b1h0ankOOnJPYoCbJNwhpGYpnDgICEs2mk= github.com/Velocidex/zip v0.0.0-20210101070220-e7ecefb7aad7 h1:IAry9WUMrVYA+XPvMF5UMN56ya5II/hoUOtqaHKOHrs= @@ -802,11 +804,7 @@ www.velocidex.com/golang/regparser v0.0.0-20190625082115-b02dc43c2500 h1:XqZddiA www.velocidex.com/golang/regparser v0.0.0-20190625082115-b02dc43c2500/go.mod h1:DVzloLH8L+oF3zma1Jisaat5bGF+4VLggDcYlIp00ns= www.velocidex.com/golang/vfilter v0.0.0-20210108051106-c18c13c24eff h1:00WZKnVVXwsfaV18UNn7iGQMCqQUf0cCFQ2RbbprYns= www.velocidex.com/golang/vfilter v0.0.0-20210108051106-c18c13c24eff/go.mod h1:EdP5LDT3l9khZVjDVD2YKoDvECi3AW0e0074quDPNpA= -www.velocidex.com/golang/vfilter v0.0.0-20210108163451-876ce85e7301 h1:ffb5gMiTNREa9+YYxKxzLl3rPbH6FCpjyEu+dSWRxks= -www.velocidex.com/golang/vfilter v0.0.0-20210108163451-876ce85e7301/go.mod h1:EdP5LDT3l9khZVjDVD2YKoDvECi3AW0e0074quDPNpA= -www.velocidex.com/golang/vfilter v0.0.0-20210110142356-d3f572a550df h1:Mq+PKDD3HXVzQy3uDv78oWhEgZZ87qNVkvPvqSMPsn0= -www.velocidex.com/golang/vfilter v0.0.0-20210110142356-d3f572a550df/go.mod h1:EdP5LDT3l9khZVjDVD2YKoDvECi3AW0e0074quDPNpA= -www.velocidex.com/golang/vfilter v0.0.0-20210111083751-13cae4a7330c h1:soa7usa1BoStBC7NkqqRyZzFA0miIy9pdnaNMmcx6VI= -www.velocidex.com/golang/vfilter v0.0.0-20210111083751-13cae4a7330c/go.mod h1:EdP5LDT3l9khZVjDVD2YKoDvECi3AW0e0074quDPNpA= -www.velocidex.com/golang/vtypes v0.0.0-20210108052555-8a27f80edada h1:Rtn8RTS/fTxHts5/PrBP7fei2eq4I6tboHyEm3xX0ew= -www.velocidex.com/golang/vtypes v0.0.0-20210108052555-8a27f80edada/go.mod h1:fkF6W4t1+qr1Nw51+EhAmCwQp2QtwcyNN1Ghwd1vLBM= +www.velocidex.com/golang/vfilter v0.0.0-20210114050946-1e02dba2abec h1:xAkbNZQvivJkCd+HoqFE0fY5aAPjp5UwVjSIiCDuN6E= +www.velocidex.com/golang/vfilter v0.0.0-20210114050946-1e02dba2abec/go.mod h1:EdP5LDT3l9khZVjDVD2YKoDvECi3AW0e0074quDPNpA= +www.velocidex.com/golang/vtypes v0.0.0-20210114034841-b184d28b61b7 h1:mzduH30kLBExDyBkMDdwYMH7nFZG9Pm6kBpIv4nGJnA= +www.velocidex.com/golang/vtypes v0.0.0-20210114034841-b184d28b61b7/go.mod h1:34AZRfhNvJ1QAwPpYrDxjCyOFys+NbSmH6LLVSjsAEg= diff --git a/gui/velociraptor/src/components/events/events.js b/gui/velociraptor/src/components/events/events.js index abb5f64dbb7..3c745c4fad6 100644 --- a/gui/velociraptor/src/components/events/events.js +++ b/gui/velociraptor/src/components/events/events.js @@ -307,6 +307,7 @@ class EventMonitoring extends React.Component { let renderers = { "_ts": timestamp_renderer, + "Timestamp": timestamp_renderer, "client_time": timestamp_renderer, }; diff --git a/notifications/notifications.go b/notifications/notifications.go index 7eb786dbde7..02147466526 100644 --- a/notifications/notifications.go +++ b/notifications/notifications.go @@ -1,6 +1,7 @@ package notifications import ( + "regexp" "sync" ) @@ -67,6 +68,18 @@ func (self *NotificationPool) Notify(client_id string) { } } +func (self *NotificationPool) NotifyByRegex(re *regexp.Regexp) { + self.mu.Lock() + defer self.mu.Unlock() + + for key, ch := range self.clients { + if re.MatchString(key) { + close(ch) + delete(self.clients, key) + } + } +} + func (self *NotificationPool) Shutdown() { self.mu.Lock() defer self.mu.Unlock() diff --git a/services/client_monitoring/client_monitoring.go b/services/client_monitoring/client_monitoring.go index b721df03de1..e31b9292d22 100644 --- a/services/client_monitoring/client_monitoring.go +++ b/services/client_monitoring/client_monitoring.go @@ -75,6 +75,7 @@ func (self *ClientEventTable) CheckClientEventsVersion( if labeler == nil { return false } + if client_version < self.state.Version { return true } diff --git a/services/launcher/artifacts_test.go b/services/launcher/artifacts_test.go index 581734e2c64..2078da2411f 100644 --- a/services/launcher/artifacts_test.go +++ b/services/launcher/artifacts_test.go @@ -22,7 +22,6 @@ import ( "www.velocidex.com/golang/velociraptor/services/repository" "www.velocidex.com/golang/velociraptor/utils" vql_subsystem "www.velocidex.com/golang/velociraptor/vql" - _ "www.velocidex.com/golang/velociraptor/vql_plugins" ) var ( diff --git a/services/launcher/launcher.go b/services/launcher/launcher.go index 5603a606354..f8a6e3c5448 100644 --- a/services/launcher/launcher.go +++ b/services/launcher/launcher.go @@ -332,11 +332,17 @@ func ScheduleArtifactCollectionFromCollectorArgs( tasks := []*crypto_proto.GrrMessage{} for _, arg := range vql_collector_args { + // If sending to the server record who actually launched this. + if client_id == "server" { + arg.Principal = collection_context.Request.Creator + } + // The task we will schedule for the client. task := &crypto_proto.GrrMessage{ SessionId: collection_context.SessionId, RequestId: constants.ProcessVQLResponses, - VQLClientAction: arg} + VQLClientAction: arg, + } // Send an urgent request to the client. if collector_request.Urgent { diff --git a/services/launcher/launcher_test.go b/services/launcher/launcher_test.go index c4274461a44..1aec20e6f3f 100644 --- a/services/launcher/launcher_test.go +++ b/services/launcher/launcher_test.go @@ -35,6 +35,10 @@ import ( "www.velocidex.com/golang/velociraptor/utils" vql_subsystem "www.velocidex.com/golang/velociraptor/vql" "www.velocidex.com/golang/vfilter" + + // Load plugins (timestamp, parse_csv) + _ "www.velocidex.com/golang/velociraptor/vql/functions" + _ "www.velocidex.com/golang/velociraptor/vql/parsers/csv" ) const ( diff --git a/services/notifications.go b/services/notifications.go index 5e6fa42b456..4b8a94853fc 100644 --- a/services/notifications.go +++ b/services/notifications.go @@ -50,9 +50,14 @@ type Notifier interface { ListenForNotification(id string) (chan bool, func()) // Send a notification to everyone - this is a global event - // directed at everyone. + // directed at everyone. Only used in server shutdown - use + // NotifyByRegex instead. NotifyAllListeners(config_obj *config_proto.Config) error + // Send a notification to all listeners with an id matching + // this regex. + NotifyByRegex(config_obj *config_proto.Config, regex string) error + // Send a notification to a specific listener based on its id // that was registered above. NotifyListener(config_obj *config_proto.Config, id string) error diff --git a/services/notifications/notifications.go b/services/notifications/notifications.go index 458d07cde8f..896fa01926d 100644 --- a/services/notifications/notifications.go +++ b/services/notifications/notifications.go @@ -16,6 +16,7 @@ package notifications import ( "context" + "regexp" "sync" "github.com/Velocidex/ordereddict" @@ -90,7 +91,20 @@ func StartNotificationService( } self.pool_mu.Lock() - if target == "All" { + if target == "Regex" { + regex_str, ok := event.GetString("Regex") + if ok { + regex, err := regexp.Compile(regex_str) + if err != nil { + logger.Error("Notification service: "+ + "Unable to compiler regex '%v': %v\n", + regex_str, err) + continue + } + self.notification_pool.NotifyByRegex(regex) + } + + } else if target == "All" { self.notification_pool.NotifyAll() } else { self.notification_pool.Notify(target) @@ -128,6 +142,19 @@ func (self *Notifier) NotifyAllListeners(config_obj *config_proto.Config) error ) } +func (self *Notifier) NotifyByRegex(config_obj *config_proto.Config, regex string) error { + journal, err := services.GetJournal() + if err != nil { + return err + } + + return journal.PushRowsToArtifact(config_obj, + []*ordereddict.Dict{ordereddict.NewDict().Set("Target", "Regex"). + Set("Regex", regex)}, + "Server.Internal.Notifications", "server", "", + ) +} + func (self *Notifier) NotifyListener(config_obj *config_proto.Config, id string) error { journal, err := services.GetJournal() if err != nil { diff --git a/services/server_artifacts/server_artifacts.go b/services/server_artifacts/server_artifacts.go index 98357cabd39..664a94559d6 100644 --- a/services/server_artifacts/server_artifacts.go +++ b/services/server_artifacts/server_artifacts.go @@ -261,6 +261,11 @@ func (self *ServerArtifactsRunner) runQuery( return err } + principal := arg.Principal + if principal == "" { + principal = "administrator" + } + scope := manager.BuildScope(services.ScopeBuilder{ Config: self.config_obj, @@ -270,7 +275,10 @@ func (self *ServerArtifactsRunner) runQuery( // files in the filestore using VQL artifacts. Uploader: NewServerUploader(self.config_obj, path_manager, collection_context), - ACLManager: vql_subsystem.NewRoleACLManager("administrator"), + + // Run this query on behalf of the caller so they are + // subject to ACL checks + ACLManager: vql_subsystem.NewServerACLManager(self.config_obj, principal), Logger: log.New(&serverLogger{ self.config_obj, path_manager.Log(), @@ -278,6 +286,8 @@ func (self *ServerArtifactsRunner) runQuery( }) defer scope.Close() + scope.Log("Running query on behalf of user %v", principal) + env := ordereddict.NewDict() for _, env_spec := range arg.Env { env.Set(env_spec.Key, env_spec.Value) diff --git a/vql/server/hunts/create.go b/vql/server/hunts/create.go index 2cdfdeb1da4..357bb44ffb4 100644 --- a/vql/server/hunts/create.go +++ b/vql/server/hunts/create.go @@ -91,6 +91,7 @@ func (self *ScheduleHuntFunction) Call(ctx context.Context, hunt_request := &api_proto.Hunt{ HuntDescription: arg.Description, + Creator: vql_subsystem.GetPrincipal(scope), StartRequest: request, Expires: arg.Expires, State: api_proto.Hunt_RUNNING, @@ -105,7 +106,9 @@ func (self *ScheduleHuntFunction) Call(ctx context.Context, return vfilter.Null{} } - return ordereddict.NewDict().Set("HuntId", hunt_id) + return ordereddict.NewDict(). + Set("HuntId", hunt_id). + Set("Request", hunt_request) } func (self ScheduleHuntFunction) Info(scope vfilter.Scope, type_map *vfilter.TypeMap) *vfilter.FunctionInfo { diff --git a/vql/server/whoami.go b/vql/server/whoami.go new file mode 100644 index 00000000000..8b1d914eaa2 --- /dev/null +++ b/vql/server/whoami.go @@ -0,0 +1,31 @@ +package server + +import ( + "context" + + "github.com/Velocidex/ordereddict" + vql_subsystem "www.velocidex.com/golang/velociraptor/vql" + "www.velocidex.com/golang/vfilter" +) + +type WhoAmIFunctionArgs struct{} +type WhoAmIFunction struct{} + +func (self *WhoAmIFunction) Call(ctx context.Context, + scope vfilter.Scope, + args *ordereddict.Dict) vfilter.Any { + + return vql_subsystem.GetPrincipal(scope) +} + +func (self WhoAmIFunction) Info(scope vfilter.Scope, type_map *vfilter.TypeMap) *vfilter.FunctionInfo { + return &vfilter.FunctionInfo{ + Name: "whoami", + Doc: "Returns the username that is running the query.", + ArgType: type_map.AddType(scope, &WhoAmIFunctionArgs{}), + } +} + +func init() { + vql_subsystem.RegisterFunction(&WhoAmIFunction{}) +} diff --git a/bin/import.go b/vql/tools/import.go similarity index 55% rename from bin/import.go rename to vql/tools/import.go index 26fb88b0baa..0cfcc2b55ee 100644 --- a/bin/import.go +++ b/vql/tools/import.go @@ -1,15 +1,17 @@ -package main +package tools import ( "archive/zip" + "context" "crypto/rand" "encoding/hex" + "errors" "fmt" "strings" "time" "github.com/Velocidex/ordereddict" - kingpin "gopkg.in/alecthomas/kingpin.v2" + "www.velocidex.com/golang/velociraptor/acls" actions_proto "www.velocidex.com/golang/velociraptor/actions/proto" "www.velocidex.com/golang/velociraptor/api" config_proto "www.velocidex.com/golang/velociraptor/config/proto" @@ -18,185 +20,160 @@ import ( "www.velocidex.com/golang/velociraptor/file_store" "www.velocidex.com/golang/velociraptor/file_store/result_sets" flows_proto "www.velocidex.com/golang/velociraptor/flows/proto" + "www.velocidex.com/golang/velociraptor/glob" + "www.velocidex.com/golang/velociraptor/json" "www.velocidex.com/golang/velociraptor/paths" artifact_paths "www.velocidex.com/golang/velociraptor/paths/artifacts" + "www.velocidex.com/golang/velociraptor/services" "www.velocidex.com/golang/velociraptor/services/launcher" "www.velocidex.com/golang/velociraptor/utils" + vql_subsystem "www.velocidex.com/golang/velociraptor/vql" + "www.velocidex.com/golang/vfilter" ) -var ( - // Command line interface for VQL commands. - import_cmd = app.Command("import", "Import an offline collection to a client") - import_client = import_cmd.Flag("client_id", "The client id to import the client for."). - String() - - import_hostname = import_cmd.Flag("hostname", "The hostname to import the client for."). - String() +type ImportCollectionFunctionArgs struct { + ClientId string `vfilter:"required,field=client_id,doc=The client id to import to. Use 'auto' to generate a new client id."` + Hostname string `vfilter:"optional,field=hostname,doc=When creating a new client, set this as the hostname."` + Filename string `vfilter:"required,field=filename,doc=Path on server to the collector zip."` + Accessor string `vfilter:"optional,field=accessor,doc=The accessor to use"` +} - import_create_host = import_cmd.Flag("create", "Create a client id record if needed."). - Bool() +type ImportCollectionFunction struct{} - import_file = import_cmd.Arg("filename", "The offline zip file to import"). - Required().String() -) +func (self *ImportCollectionFunction) Call(ctx context.Context, + scope vfilter.Scope, + args *ordereddict.Dict) vfilter.Any { -// Generate a new client id -func NewClientId() string { - buf := make([]byte, 8) - _, _ = rand.Read(buf) - dst := make([]byte, hex.EncodedLen(8)) - hex.Encode(dst, buf) - return "C." + string(dst) -} - -// Retrieve the client id from the hostname. -func getClientId(config_obj *config_proto.Config, - hostname string) string { - db, err := datastore.GetDB(config_obj) + err := vql_subsystem.CheckAccess(scope, acls.COLLECT_SERVER) if err != nil { - return "" + scope.Log("import_collection: %s", err) + return vfilter.Null{} } - for _, client_id := range db.SearchClients( - config_obj, constants.CLIENT_INDEX_URN, - hostname, "", 0, 1, datastore.SORT_UP) { - return client_id + arg := &ImportCollectionFunctionArgs{} + err = vfilter.ExtractArgs(scope, args, arg) + if err != nil { + scope.Log("import_collection: %v", err) + return vfilter.Null{} } - return "" -} -// Create a new client record -func makeNewClient( - config_obj *config_proto.Config, - hostname string) (string, error) { - client_id := NewClientId() - client_info := &actions_proto.ClientInfo{ - ClientId: client_id, - Hostname: hostname, - Fqdn: hostname, - Architecture: "Offline", - ClientName: "OfflineVelociraptor", + config_obj, ok := vql_subsystem.GetServerConfig(scope) + if !ok { + scope.Log("Command can only run on the server") + return vfilter.Null{} } db, err := datastore.GetDB(config_obj) if err != nil { - return "", err + scope.Log("import_collection: %v", err) + return vfilter.Null{} } - client_path_manager := paths.NewClientPathManager(client_id) - err = db.SetSubject(config_obj, - client_path_manager.Path(), client_info) - if err != nil { - return "", err - } - // Add the new client to the index. - keywords := []string{ - "all", // This is used for "." search - client_id, - client_info.Hostname, - client_info.Fqdn, - "host:" + client_info.Hostname, + if arg.ClientId == "auto" { + arg.ClientId, err = makeNewClient(config_obj, arg.Hostname) + if err != nil { + scope.Log("import_collection: %v", err) + return vfilter.Null{} + } } - return client_id, db.SetIndex(config_obj, - constants.CLIENT_INDEX_URN, - client_id, keywords, - ) -} - -func doImport() { - if *import_client == "" && *import_hostname == "" { - kingpin.Fatalf("One of client_id or hostname should be specified.") + api_client, err := api.GetApiClient(config_obj, nil, arg.ClientId, false /* detailed */) + if err != nil || api_client.AgentInformation == nil || + api_client.AgentInformation.Name == "" { + scope.Log("import_collection: client_id not known") + return vfilter.Null{} } - config_obj, err := DefaultConfigLoader. - WithRequiredFrontend(). - WithRequiredUser(). - WithRequiredLogging().LoadAndValidate() - kingpin.FatalIfError(err, "Unable to load config file") - - ctx, cancel := install_sig_handler() - defer cancel() - - sm, err := startEssentialServices(config_obj) - kingpin.FatalIfError(err, "Load Config ") - defer sm.Close() - - db, err := datastore.GetDB(config_obj) - kingpin.FatalIfError(err, "Saving file ") - - client_id := *import_client - hostname := *import_hostname - if hostname != "" { - client_id = getClientId(config_obj, hostname) - if client_id == "" { - if !*import_create_host { - kingpin.Fatalf("Hostname %v not known, you can "+ - "create one with the --create flag ", hostname) - } - client_id, err = makeNewClient(config_obj, hostname) - kingpin.FatalIfError(err, "Creating new client") - } + file_store_factory := file_store.GetFileStore(config_obj) + manager, err := services.GetRepositoryManager() + if err != nil { + scope.Log("import_collection: %v", err) + return vfilter.Null{} } - api_client, err := api.GetApiClient(config_obj, nil, client_id, false /* detailed */) - kingpin.FatalIfError(err, "Client ID Not known ") + repository, err := manager.GetGlobalRepository(config_obj) + if err != nil { + scope.Log("import_collection: %v", err) + return vfilter.Null{} + } - if api_client.AgentInformation.Name == "" { - kingpin.Fatalf("Client ID not known") + // Open the zip file we are importing. + accessor, err := glob.GetAccessor(arg.Accessor, scope) + if err != nil { + scope.Log("import_collection: %v", err) + return vfilter.Null{} } - file_store_factory := file_store.GetFileStore(config_obj) + fd, err := accessor.Open(arg.Filename) + if err != nil { + scope.Log("import_collection: %v", err) + return vfilter.Null{} + } + defer fd.Close() - repository, err := getRepository(config_obj) - kingpin.FatalIfError(err, "Load Config ") + st, err := accessor.Lstat(arg.Filename) + if err != nil { + scope.Log("import_collection: %v", err) + return vfilter.Null{} + } - // Open the zip file we are importing. - zipfile, err := zip.OpenReader(*import_file) - kingpin.FatalIfError(err, "Loading collection file ") - defer zipfile.Close() + zipfile, err := zip.NewReader(utils.ReaderAtter{fd}, st.Size()) + if err != nil { + scope.Log("import_collection: %v", err) + return vfilter.Null{} + } // Keep track of all the artifacts in the zip file. artifacts := make(map[string]bool) uploads := []string{} // Create a new flow and path manager for it. - flow_id := launcher.NewFlowId(client_id) - path_manager := paths.NewFlowPathManager(client_id, flow_id) + flow_id := launcher.NewFlowId(arg.ClientId) + path_manager := paths.NewFlowPathManager(arg.ClientId, flow_id) new_flow := &flows_proto.ArtifactCollectorContext{ - SessionId: flow_id, - ClientId: client_id, - Request: &flows_proto.ArtifactCollectorArgs{}, + SessionId: flow_id, + ClientId: arg.ClientId, + Request: &flows_proto.ArtifactCollectorArgs{ + Creator: vql_subsystem.GetPrincipal(scope), + ClientId: arg.ClientId, + }, CreateTime: uint64(time.Now().UnixNano() / 1000), State: flows_proto.ArtifactCollectorContext_FINISHED, } + json.Dump(new_flow) + uploaded_files_result_set, err := result_sets.NewResultSetWriter( file_store_factory, path_manager.UploadMetadata(), nil, true /* truncate */) - kingpin.FatalIfError(err, "Loading collection file ") + if err != nil { + scope.Log("import_collection: %v", err) + return vfilter.Null{} + } defer uploaded_files_result_set.Close() log_result_set, err := result_sets.NewResultSetWriter( file_store_factory, path_manager.Log(), nil, true /* truncate */) - kingpin.FatalIfError(err, "Loading collection file ") + if err != nil { + scope.Log("import_collection: %v", err) + return vfilter.Null{} + } defer log_result_set.Close() // A log function that stores messages in the flow log as well // as print them to the screen. log := func(format string, args ...interface{}) { now := time.Now().UTC() - log_result_set.Write(ordereddict.NewDict(). Set("Timestamp", fmt.Sprintf("%v", now)). Set("time", time.Unix(int64(now.UnixNano())/1000000, 0).String()). Set("message", fmt.Sprintf(format, args...))) - fmt.Printf(format+"\n", args...) + scope.Log(format, args...) } - log("Importing zip file %v into client id %v", *import_file, client_id) + log("Importing zip file %v into client id %v", arg.Filename, arg.ClientId) for _, file := range zipfile.File { log("Filename %v", file.Name) @@ -224,7 +201,7 @@ func doImport() { defer fd.Close() artifact_path_manager := artifact_paths.NewArtifactPathManager( - config_obj, client_id, flow_id, artifact_name) + config_obj, arg.ClientId, flow_id, artifact_name) rs_writer, err := result_sets.NewResultSetWriter( file_store_factory, artifact_path_manager, @@ -283,17 +260,96 @@ func doImport() { } err = db.SetSubject(config_obj, path_manager.Path(), new_flow) - kingpin.FatalIfError(err, "Saving new collection ") + if err != nil { + scope.Log("import_collection: %v", err) + return vfilter.Null{} + } + + // Generate a fake System.Flow.Completion event for the + // uploaded flow in case there are any listeners who are + // interested. + journal, err := services.GetJournal() + if err != nil { + scope.Log("import_collection: %v", err) + return vfilter.Null{} + } + + row := ordereddict.NewDict(). + Set("Timestamp", time.Now().UTC().Unix()). + Set("Flow", new_flow). + Set("FlowId", new_flow.SessionId). + Set("ClientId", new_flow.ClientId) + + err = journal.PushRowsToArtifact(config_obj, + []*ordereddict.Dict{row}, + "System.Flow.Completion", new_flow.ClientId, + new_flow.SessionId, + ) + + return new_flow +} + +func (self ImportCollectionFunction) Info(scope vfilter.Scope, type_map *vfilter.TypeMap) *vfilter.FunctionInfo { + return &vfilter.FunctionInfo{ + Name: "import_collection", + Doc: "Imports an offline collection zip file (experimental).", + ArgType: type_map.AddType(scope, &ImportCollectionFunctionArgs{}), + } +} + +// Generate a new client id +func NewClientId() string { + buf := make([]byte, 8) + _, _ = rand.Read(buf) + dst := make([]byte, hex.EncodedLen(8)) + hex.Encode(dst, buf) + return "C." + string(dst) +} + +// Create a new client record +func makeNewClient( + config_obj *config_proto.Config, + hostname string) (string, error) { + + if hostname == "" { + return "", errors.New("New clients must have a hostname") + } + + client_id := NewClientId() + client_info := &actions_proto.ClientInfo{ + ClientId: client_id, + Hostname: hostname, + Fqdn: hostname, + Architecture: "Offline", + ClientName: "OfflineVelociraptor", + } + + db, err := datastore.GetDB(config_obj) + if err != nil { + return "", err + } + + client_path_manager := paths.NewClientPathManager(client_id) + err = db.SetSubject(config_obj, + client_path_manager.Path(), client_info) + if err != nil { + return "", err + } + // Add the new client to the index. + keywords := []string{ + "all", // This is used for "." search + client_id, + client_info.Hostname, + client_info.Fqdn, + "host:" + client_info.Hostname, + } + + return client_id, db.SetIndex(config_obj, + constants.CLIENT_INDEX_URN, + client_id, keywords, + ) } func init() { - command_handlers = append(command_handlers, func(command string) bool { - switch command { - case "import": - doImport() - default: - return false - } - return true - }) + vql_subsystem.RegisterFunction(&ImportCollectionFunction{}) }