diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/.github/workflows/go.yml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/.github/workflows/go.yml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/.github/workflows/go.yml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/.github/workflows/go.yml 2025-11-01 15:52:20.000000000 +0000 @@ -22,5 +22,5 @@ - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe with: - go-version: '^1.23' + go-version: '^1.25' # Caching seems to really slow down the build due to the time @@ -40,5 +40,5 @@ uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e with: - node-version: 20 + node-version: 22.19 - name: npm install gui diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/.github/workflows/musl.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/.github/workflows/musl.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/.github/workflows/musl.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/.github/workflows/musl.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -18,5 +18,5 @@ - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe with: - go-version: '^1.23' + go-version: '^1.25' - run: go version diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/.github/workflows/windows.yml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/.github/workflows/windows.yml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/.github/workflows/windows.yml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/.github/workflows/windows.yml 2025-11-01 15:52:20.000000000 +0000 @@ -10,8 +10,8 @@ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - name: Set up Go 1.23 + - name: Set up Go 1.25 uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe with: - go-version: 1.23 + go-version: 1.25 # Caching seems to really slow down the build due to the time diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/.gitignore /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/.gitignore --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/.gitignore 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/.gitignore 2025-11-03 18:18:39.000000000 +0000 @@ -1,3 +1,2 @@ -vendor/ *~ *.config.yaml diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/README.md /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/README.md --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/README.md 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/README.md 2025-11-01 15:52:20.000000000 +0000 @@ -170,5 +170,3 @@ https://docs.velociraptor.app/blog/ -Hang out on Medium https://medium.com/velociraptor-ir - Follow us on Twitter [@velocidex](https://twitter.com/velocidex) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/api.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/api.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/api.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/api.go 2025-11-01 15:52:20.000000000 +0000 @@ -274,4 +274,11 @@ } +func (self *OSPath) MarshalYAML() (interface{}, error) { + json_string := []byte(self.String()) + buf := bytes.Buffer{} + err := json.Indent(&buf, json_string, " ", " ") + return string(buf.Bytes()), err +} + // MarshalText is used by the YAML marshaller. We indent the text to // make sure it uses multi line yaml which is more readable for diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/collector/collector.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/collector/collector.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/collector/collector.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/collector/collector.go 2025-11-01 15:52:20.000000000 +0000 @@ -5,5 +5,4 @@ "fmt" "io" - "io/ioutil" "os" "strings" @@ -162,17 +161,19 @@ full_path *accessors.OSPath) (*accessors.OSPath, error) { - // Password is already cached in the context - just return it as is. - _, pres := self.scope.GetContext(constants.ZIP_PASSWORDS) - if pres { - - // Transform the path so it is ready to be used by the zip - // accessor. - return collectorPathToDelegatePath(full_path), nil - } - // If password is already set in the scope, just use it as it is. pass, pres := self.scope.Resolve(constants.ZIP_PASSWORDS) - if pres && !utils.IsNil(pass) { - return collectorPathToDelegatePath(full_path), nil + if pres { + if utils.ToString(pass) != "" { + return collectorPathToDelegatePath(full_path), nil + } + } else { + // Password is already cached in the context - just return it as is. + pass, pres = self.scope.GetContext(constants.ZIP_PASSWORDS) + if pres && !utils.IsNil(pass) { + + // Transform the path so it is ready to be used by the zip + // accessor. + return collectorPathToDelegatePath(full_path), nil + } } @@ -197,5 +198,5 @@ } - buf, err := ioutil.ReadAll(mhandle) + buf, err := utils.ReadAllWithLimit(mhandle, constants.MAX_MEMORY) if err != nil { return nil, fmt.Errorf("Decoding metadata.json: %w", err) @@ -283,5 +284,6 @@ } - serialized, err := ioutil.ReadAll(idx_reader) + serialized, err := utils.ReadAllWithLimit(idx_reader, + constants.MAX_MEMORY) if err != nil { return nil, err diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/collector/collector_test.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/collector/collector_test.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/collector/collector_test.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/collector/collector_test.go 2025-11-01 15:52:20.000000000 +0000 @@ -107,5 +107,6 @@ full_path, _ := scope.Associative(row, "OSPath") - lines = append(lines, full_path) + full_path_path, _ := scope.Associative(full_path, "Path") + lines = append(lines, full_path_path) } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/data/scope.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/data/scope.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/data/scope.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/data/scope.go 2025-11-01 15:52:20.000000000 +0000 @@ -4,9 +4,9 @@ "context" "fmt" - "os" "strings" "github.com/go-errors/errors" "www.velocidex.com/golang/velociraptor/accessors" + "www.velocidex.com/golang/velociraptor/utils" "www.velocidex.com/golang/vfilter" "www.velocidex.com/golang/vfilter/types" @@ -40,5 +40,5 @@ result, pres = self.scope.Associative(result, member) if !pres { - return "", os.ErrNotExist + return "", utils.NotFoundError } } @@ -64,5 +64,5 @@ accessors.FileInfo, error) { if len(path.Components) != 1 { - return nil, os.ErrNotExist + return nil, utils.NotFoundError } @@ -101,5 +101,5 @@ accessors.ReadSeekCloser, error) { if len(path.Components) != 1 { - return nil, os.ErrNotExist + return nil, utils.NotFoundError } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/file/accessor_common.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/file/accessor_common.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/file/accessor_common.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/file/accessor_common.go 2025-11-01 15:52:20.000000000 +0000 @@ -181,4 +181,6 @@ root *accessors.OSPath + + scope vfilter.Scope } @@ -205,4 +207,5 @@ root: self.root, nocase: self.nocase, + scope: scope, }, nil } @@ -260,4 +263,6 @@ full_path *accessors.OSPath) (accessors.FileInfo, error) { + defer Instrument("LstatWithOSPath")() + err := CheckPrefix(full_path) if err != nil { @@ -313,4 +318,6 @@ full_path *accessors.OSPath) ([]accessors.FileInfo, error) { + defer Instrument("ReadDirWithOSPath")() + err := CheckPrefix(full_path) if err != nil { @@ -440,4 +447,6 @@ full_path *accessors.OSPath) (accessors.ReadSeekCloser, error) { + defer Instrument("OpenWithOSPath")() + err := CheckPrefix(full_path) if err != nil { diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/file/auto_windows.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/file/auto_windows.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/file/auto_windows.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/file/auto_windows.go 2025-11-01 15:52:20.000000000 +0000 @@ -12,4 +12,5 @@ "io" "os" + "strings" "sync" @@ -86,6 +87,5 @@ n, err := self.ReadSeekCloser.Read(buf) if err != nil && - !errors.Is(err, io.ErrUnexpectedEOF) && - !errors.Is(err, io.EOF) && + shouldTryNTFS(self.path.Basename(), err) && !self.switched_to_ntfs { @@ -183,5 +183,5 @@ path *accessors.OSPath) (accessors.ReadSeekCloser, error) { result, err := self.file_delegate.OpenWithOSPath(path) - if err != nil { + if err != nil && shouldTryNTFS(path.Basename(), err) { ntfs_path := accessors.WindowsNTFSPathFromOSPath(path) result, err1 := self.ntfs_delegate.OpenWithOSPath(ntfs_path) @@ -201,7 +201,42 @@ } +func shouldTryNTFS(path string, err error) bool { + // Special NTFS files start with a $ + if strings.Contains(path, "\\$") || strings.HasPrefix(path, "$") { + return true + } + + // For permission denied we fallback to ntfs parsing. + if errors.Is(err, os.ErrPermission) { + return true + } + + // These are regular errors - falling back to ntfs parsing will + // not help much. + if errors.Is(err, io.ErrUnexpectedEOF) || + errors.Is(err, io.EOF) || + errors.Is(err, os.ErrClosed) { + return false + } + + // If the file does not exist using the APIs then it is unlikely + // that nts parsing will find it. + if errors.Is(err, os.ErrNotExist) { + return false + } + + // This mostly occurs on directories. + if strings.Contains(err.Error(), "Incorrect function") { + return false + } + + // Give ntfs parsing a shot - maybe it will work? + return true +} + func (self *AutoFilesystemAccessor) Lstat(path string) (accessors.FileInfo, error) { result, err := self.file_delegate.Lstat(path) if err != nil { + return self.ntfs_delegate.Lstat(path) } @@ -212,5 +247,5 @@ path *accessors.OSPath) (accessors.FileInfo, error) { result, err := self.file_delegate.LstatWithOSPath(path) - if err != nil { + if err != nil && shouldTryNTFS(path.Basename(), err) { ntfs_path := accessors.WindowsNTFSPathFromOSPath(path) return self.ntfs_delegate.LstatWithOSPath(ntfs_path) Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/file: cache.go Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/file: instrument.go diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/file/os_windows.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/file/os_windows.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/file/os_windows.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/file/os_windows.go 2025-11-01 15:52:20.000000000 +0000 @@ -36,11 +36,8 @@ "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" - ntfs "www.velocidex.com/golang/go-ntfs/parser" "www.velocidex.com/golang/velociraptor/accessors" "www.velocidex.com/golang/velociraptor/acls" "www.velocidex.com/golang/velociraptor/json" "www.velocidex.com/golang/velociraptor/utils" - "www.velocidex.com/golang/velociraptor/utils/files" - "www.velocidex.com/golang/velociraptor/vql/windows/wmi" "www.velocidex.com/golang/vfilter" ) @@ -133,4 +130,5 @@ type OSFileSystemAccessor struct { follow_links bool + scope vfilter.Scope } @@ -143,5 +141,8 @@ accessors.FileSystemAccessor, error) { - return &OSFileSystemAccessor{follow_links: self.follow_links}, nil + return &OSFileSystemAccessor{ + follow_links: self.follow_links, + scope: scope, + }, nil } @@ -159,40 +160,4 @@ } -func discoverDriveLetters() ([]accessors.FileInfo, error) { - result := []accessors.FileInfo{} - - shadow_volumes, err := wmi.Query( - "SELECT DeviceID, Description, VolumeName, FreeSpace, "+ - "Size, SystemName, VolumeSerialNumber "+ - "from Win32_LogicalDisk", - "ROOT\\CIMV2") - if err == nil { - for _, row := range shadow_volumes { - size := utils.GetInt64(row, "Size") - device_name, pres := row.GetString("DeviceID") - if pres { - device_path, err := accessors.NewWindowsOSPath(device_name) - if err != nil { - return nil, err - } - - err = CheckPrefix(device_path) - if err != nil { - continue - } - - result = append(result, &accessors.VirtualFileInfo{ - IsDir_: true, - Size_: size, - Data_: row, - Path: device_path, - }) - } - } - } - - return result, nil -} - func (self OSFileSystemAccessor) ReadDir(path string) ( []accessors.FileInfo, error) { @@ -209,4 +174,6 @@ var result []accessors.FileInfo + defer Instrument("ReadDirWithOSPath")() + err := CheckPrefix(full_path) if err != nil { @@ -216,5 +183,5 @@ // No drive part, so list all drives. if len(full_path.Components) == 0 { - return discoverDriveLetters() + return Cache.DiscoverDriveLetters() } @@ -301,4 +268,6 @@ accessors.ReadSeekCloser, error) { + defer Instrument("OpenWithOSPath")() + err := CheckPrefix(full_path) if err != nil { @@ -310,32 +279,5 @@ if len(full_path.Components) == 1 { device_name := full_path.Components[0] - if !strings.HasPrefix(device_name, "\\\\") { - device_name = "\\\\.\\" + device_name - } - file, err := os.Open(device_name) - if err != nil { - return nil, err - } - - files.Add(device_name) - - // Need to read the raw device in pagesize sizes - reader, err := ntfs.NewPagedReader(file, 0x1000, 1000) - if err != nil { - return nil, err - } - - res := utils.NewReadSeekReaderAdapter(reader, func() { - files.Remove(device_name) - }) - - // Try to figure out the size - not necessary but in case we - // can we can limit readers to this size. - stat, err1 := os.Lstat(device_name) - if err1 == nil { - res.SetSize(stat.Size()) - } - - return res, err + return getDeviceReader(self.scope, device_name) } @@ -354,4 +296,5 @@ func (self *OSFileSystemAccessor) Lstat(path string) (accessors.FileInfo, error) { + defer Instrument("Lstat")() full_path, err := self.ParsePath(path) @@ -376,4 +319,6 @@ accessors.FileInfo, error) { + defer Instrument("LstatWithOSPath")() + err := CheckPrefix(full_path) if err != nil { @@ -383,5 +328,5 @@ // An Lstat of a device returns metadata about the device if len(full_path.Components) == 1 { - devices, err := discoverDriveLetters() + devices, err := Cache.DiscoverDriveLetters() if err != nil { return nil, err @@ -394,5 +339,5 @@ } } - return nil, errors.New("Not found") + return nil, utils.NotFoundError } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/file_store/accessor.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/file_store/accessor.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/file_store/accessor.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/file_store/accessor.go 2025-11-01 15:52:20.000000000 +0000 @@ -7,9 +7,9 @@ "encoding/json" "errors" - "io/ioutil" "www.velocidex.com/golang/velociraptor/accessors" "www.velocidex.com/golang/velociraptor/accessors/file_store_file_info" "www.velocidex.com/golang/velociraptor/acls" + "www.velocidex.com/golang/velociraptor/constants" "www.velocidex.com/golang/velociraptor/file_store" "www.velocidex.com/golang/velociraptor/file_store/api" @@ -342,5 +342,5 @@ defer fd.Close() - data, err := ioutil.ReadAll(fd) + data, err := utils.ReadAllWithLimit(fd, constants.MAX_MEMORY) if err != nil { return nil, err diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/manipulators.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/manipulators.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/manipulators.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/manipulators.go 2025-11-01 15:52:20.000000000 +0000 @@ -666,5 +666,5 @@ for _, c := range path.Components { if c != "" { - components = append(components, utils.SanitizeString(c)) + components = append(components, utils.SanitizeStringForZip(c)) } } @@ -674,9 +674,11 @@ func (self ZipFileManipulator) PathJoin(path *OSPath) string { - components := []string{} - for _, c := range path.Components { - components = append(components, utils.SanitizeStringForZip(c)) + osPathSerializations.Inc() + + result := self.AsPathSpec(path) + if result.GetDelegateAccessor() == "" && result.GetDelegatePath() == "" { + return result.Path } - return "/" + strings.Join(components, "/") + return result.String() } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/mount.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/mount.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/mount.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/mount.go 2025-11-01 15:52:20.000000000 +0000 @@ -141,6 +141,9 @@ delegate_path := self.FileInfo.OSPath() - trimmed_path := delegate_path.TrimComponents( - self.remove_prefix.Components...) + trimmed_path := delegate_path + if self.remove_prefix != nil { + trimmed_path = delegate_path.TrimComponents( + self.remove_prefix.Components...) + } self._ospath = self.prefix.Append(trimmed_path.Components...) @@ -148,4 +151,13 @@ } +func NewFileInfoWrapper(fsinfo FileInfo, + prefix, remove_prefix *OSPath) *FileInfoWrapper { + return &FileInfoWrapper{ + FileInfo: fsinfo, + prefix: prefix, + remove_prefix: remove_prefix, + } +} + // A mount accessor maps several delegate accessors inside the same // filesystem tree emulating mount points. Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/ntfs: cache.go Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/ntfs: instrument.go diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/ntfs/mft.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/ntfs/mft.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/ntfs/mft.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/ntfs/mft.go 2025-11-01 15:52:20.000000000 +0000 @@ -27,9 +27,9 @@ import ( "errors" - "os" ntfs "www.velocidex.com/golang/go-ntfs/parser" "www.velocidex.com/golang/velociraptor/accessors" "www.velocidex.com/golang/velociraptor/accessors/ntfs/readers" + "www.velocidex.com/golang/velociraptor/utils" "www.velocidex.com/golang/vfilter" ) @@ -90,5 +90,5 @@ subpath = full_path.Components[0] } else if len(full_path.Components) < 2 { - return nil, "", "", os.ErrNotExist + return nil, "", "", utils.NotFoundError } else { subpath = full_path.Components[1] @@ -102,5 +102,5 @@ full_path, err := self.ParsePath(path) if err != nil || len(full_path.Components) == 0 { - return nil, os.ErrNotExist + return nil, utils.NotFoundError } @@ -111,4 +111,6 @@ accessors.ReadSeekCloser, error) { + defer Instrument("OpenWithOSPath")() + delegate_device, delegate_accessor, subpath, err := self.parseMFTPath( full_path) @@ -170,5 +172,5 @@ full_path, err := self.ParsePath(path) if err != nil || len(full_path.Components) == 0 { - return nil, os.ErrNotExist + return nil, utils.NotFoundError } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/ntfs/ntfs_accessor.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/ntfs/ntfs_accessor.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/ntfs/ntfs_accessor.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/ntfs/ntfs_accessor.go 2025-11-01 15:52:20.000000000 +0000 @@ -191,4 +191,7 @@ func (self *NTFSFileSystemAccessor) ReadDirWithOSPath( fullpath *accessors.OSPath) (res []accessors.FileInfo, err error) { + + defer Instrument("ReadDirWithOSPath")() + defer func() { r := recover() @@ -367,4 +370,6 @@ fullpath *accessors.OSPath) (res accessors.ReadSeekCloser, err error) { + defer Instrument("OpenWithOSPath")() + defer func() { r := recover() @@ -394,4 +399,6 @@ // special case this as openning the raw device. if len(fullpath.Components) == 0 { + defer Instrument("RawDevice")() + accessor, err := accessors.GetAccessor(accessor, self.scope) if err != nil { @@ -407,5 +414,5 @@ reader, err := ntfs.NewPagedReader( - utils.MakeReaderAtter(file), 0x1000, 10000) + utils.MakeReaderAtter(file), 0x1000, 1000) if err != nil { return nil, err @@ -540,4 +547,6 @@ filename *accessors.OSPath) (*ntfs.MFT_ENTRY, error) { + defer Instrument("Open")() + components := filename.Components diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/ntfs/ntfs_accessor_windows.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/ntfs/ntfs_accessor_windows.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/ntfs/ntfs_accessor_windows.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/ntfs/ntfs_accessor_windows.go 2025-11-01 15:52:20.000000000 +0000 @@ -10,8 +10,6 @@ "www.velocidex.com/golang/velociraptor/accessors" "www.velocidex.com/golang/velociraptor/accessors/file" - "www.velocidex.com/golang/velociraptor/utils" vql_subsystem "www.velocidex.com/golang/velociraptor/vql" "www.velocidex.com/golang/velociraptor/vql/constants" - "www.velocidex.com/golang/velociraptor/vql/windows/wmi" "www.velocidex.com/golang/vfilter" ) @@ -39,4 +37,6 @@ os_path *accessors.OSPath) (accessors.FileInfo, error) { + defer Instrument("LstatWithOSPath")() + err := file.CheckPrefix(os_path) if err != nil { @@ -49,5 +49,5 @@ // Try to match the device to the component required. This can // be either a VSS volume or a Logical disk volume. - devices, err := discoverVSS() + devices, err := Cache.DiscoverVSS() if err != nil { return nil, err @@ -59,5 +59,5 @@ } } - devices, err = discoverLogicalDisks() + devices, err = Cache.DiscoverLogicalDisks() if err != nil { return nil, err @@ -74,65 +74,4 @@ } -func discoverVSS() ([]*accessors.VirtualFileInfo, error) { - shadow_volumes, err := wmi.Query( - "SELECT DeviceObject, VolumeName, InstallDate, "+ - "OriginatingMachine from Win32_ShadowCopy", - "ROOT\\CIMV2") - if err != nil { - return nil, err - } - - result := []*accessors.VirtualFileInfo{} - for _, row := range shadow_volumes { - device_name, pres := row.GetString("DeviceObject") - if pres { - device_path, err := accessors.NewWindowsNTFSPath(device_name) - if err != nil { - return nil, err - } - virtual_directory := &accessors.VirtualFileInfo{ - IsDir_: true, - Path: device_path, - Size_: 0, // WMI does not give the original volume size - Data_: row, - } - result = append(result, virtual_directory) - } - } - - return result, nil -} - -func discoverLogicalDisks() ([]*accessors.VirtualFileInfo, error) { - shadow_volumes, err := wmi.Query( - "SELECT DeviceID, Description, VolumeName, FreeSpace, "+ - "Size, SystemName, VolumeSerialNumber "+ - "from Win32_LogicalDisk WHERE FileSystem = 'NTFS'", - "ROOT\\CIMV2") - if err != nil { - return nil, err - } - - result := []*accessors.VirtualFileInfo{} - for _, row := range shadow_volumes { - device_name, pres := row.GetString("DeviceID") - if pres { - device_path, err := accessors.NewWindowsNTFSPath("\\\\.\\" + device_name) - if err != nil { - return nil, err - } - virtual_directory := &accessors.VirtualFileInfo{ - IsDir_: true, - Size_: utils.GetInt64(row, "Size"), - Path: device_path, - Data_: row, - } - result = append(result, virtual_directory) - } - } - - return result, nil -} - func (self *WindowsNTFSFileSystemAccessor) New( scope vfilter.Scope) (accessors.FileSystemAccessor, error) { @@ -160,5 +99,5 @@ } - vss, err := discoverVSS() + vss, err := Cache.DiscoverVSS() if err == nil { for _, fi := range vss { @@ -172,5 +111,5 @@ } - logical, err := discoverLogicalDisks() + logical, err := Cache.DiscoverLogicalDisks() if err == nil { for _, fi := range logical { Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors: overlay diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/pipe/pipe.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/pipe/pipe.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/pipe/pipe.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/pipe/pipe.go 2025-11-01 15:52:20.000000000 +0000 @@ -183,5 +183,5 @@ variable_data, pres := self.scope.Resolve(variable) if !pres || utils.IsNil(variable_data) { - return nil, os.ErrNotExist + return nil, utils.NotFoundError } variable_data_lazy, ok := variable_data.(types.StoredExpression) @@ -199,5 +199,5 @@ pipe, ok := variable_data.(*Pipe) if !ok { - return nil, os.ErrNotExist + return nil, utils.NotFoundError } @@ -208,5 +208,5 @@ path *accessors.OSPath) (accessors.ReadSeekCloser, error) { if len(path.Components) != 1 { - return nil, os.ErrNotExist + return nil, utils.NotFoundError } return self.Open(path.Components[0]) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/pst/pst_accessor.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/pst/pst_accessor.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/pst/pst_accessor.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/pst/pst_accessor.go 2025-11-01 15:52:20.000000000 +0000 @@ -9,5 +9,4 @@ "errors" "io" - "os" "strconv" "strings" @@ -78,5 +77,5 @@ full_path, err := self.ParsePath(path) if err != nil || len(full_path.Components) == 0 { - return nil, os.ErrNotExist + return nil, utils.NotFoundError } @@ -109,5 +108,5 @@ full_path, err := self.ParsePath(path) if err != nil || len(full_path.Components) == 0 { - return nil, os.ErrNotExist + return nil, utils.NotFoundError } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/s3/s3.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/s3/s3.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/s3/s3.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/s3/s3.go 2025-11-01 15:52:20.000000000 +0000 @@ -5,5 +5,4 @@ import ( "context" - "os" "strings" "sync" @@ -170,5 +169,5 @@ func getBucketAndKey(path *accessors.OSPath) (string, string, error) { if len(path.Components) == 0 { - return "", "", os.ErrNotExist + return "", "", utils.NotFoundError } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/s3/session.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/s3/session.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/s3/session.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/s3/session.go 2025-11-01 15:52:20.000000000 +0000 @@ -126,6 +126,9 @@ } - if config_obj.Security != nil && - !config_obj.Security.VqlMustUseSecrets { + if config_obj.Security == nil { + return nil + } + + if !config_obj.Security.VqlMustUseSecrets { return nil } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/ssh/session.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/ssh/session.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/ssh/session.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/ssh/session.go 2025-11-01 15:52:20.000000000 +0000 @@ -96,6 +96,9 @@ } - if config_obj.Security != nil && - !config_obj.Security.VqlMustUseSecrets { + if config_obj.Security == nil { + return nil + } + + if !config_obj.Security.VqlMustUseSecrets { return nil } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/virtual.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/virtual.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/virtual.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/virtual.go 2025-11-01 15:52:20.000000000 +0000 @@ -11,4 +11,5 @@ "github.com/Velocidex/ordereddict" "www.velocidex.com/golang/velociraptor/json" + "www.velocidex.com/golang/velociraptor/utils" "www.velocidex.com/golang/vfilter" ) @@ -243,5 +244,5 @@ node, err := self.getNode(path) if err != nil { - return nil, os.ErrNotExist + return nil, utils.NotFoundError } @@ -259,5 +260,5 @@ if next_node == nil { return nil, fmt.Errorf("While finding %v: Can not find %v: %w", - path, c, os.ErrNotExist) + path, c, utils.NotFoundError) } node = next_node diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/zip/accessor.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/zip/accessor.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/accessors/zip/accessor.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/accessors/zip/accessor.go 2025-11-01 15:52:20.000000000 +0000 @@ -2,5 +2,4 @@ import ( - "os" "strings" "sync" @@ -114,5 +113,5 @@ } - return nil, os.ErrNotExist + return nil, utils.NotFoundError } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/acls/api.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/acls/api.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/acls/api.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/acls/api.go 2025-11-01 15:52:20.000000000 +0000 @@ -1,7 +1,7 @@ package acls -import "errors" +import "www.velocidex.com/golang/velociraptor/utils" var ( - PermissionDenied = errors.New("PermissionDenied") + PermissionDenied = utils.Wrap(utils.PermissionDenied, "PermissionDenied") ) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/actions/client_info.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/actions/client_info.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/actions/client_info.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/actions/client_info.go 2025-11-01 15:52:20.000000000 +0000 @@ -3,9 +3,9 @@ import ( "context" - "runtime" "github.com/Showmax/go-fqdn" actions_proto "www.velocidex.com/golang/velociraptor/actions/proto" config_proto "www.velocidex.com/golang/velociraptor/config/proto" + "www.velocidex.com/golang/velociraptor/utils" "www.velocidex.com/golang/velociraptor/vql/psutils" ) @@ -43,5 +43,5 @@ result.System = info.OS result.Release = info.Platform + info.PlatformVersion - result.Architecture = runtime.GOARCH + result.Architecture = utils.GetArch() result.Fqdn = fqdn.Get() } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/actions/events.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/actions/events.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/actions/events.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/actions/events.go 2025-11-01 15:52:20.000000000 +0000 @@ -31,4 +31,5 @@ "fmt" "sync" + "time" "google.golang.org/protobuf/proto" @@ -196,5 +197,5 @@ result = append(result, self.Events...) - // If there are no build in additional event artifacts we are done + // If there are no built in additional event artifacts we are done // - just run the queries from the event table. if config_obj.Client == nil || @@ -249,5 +250,4 @@ // Start a new query for each event. - action_obj := &VQLClientAction{} for _, event := range events { @@ -269,7 +269,7 @@ defer query_responder.Close() - // Event tables never time out + // Event tables get refreshed by default every 12 hours. if event.Timeout == 0 { - event.Timeout = 99999999 + event.Timeout = 12 * 60 * 60 } @@ -282,6 +282,6 @@ // Start the query - if it is an event query this will // never complete until it is cancelled. - action_obj.StartQuery( - config_obj, self.Ctx, query_responder, event) + self.RunQuery(self.Ctx, config_obj, + artifact_name, query_responder, event) if artifact_name != "" { logger.Info("Finished monitoring query %s", artifact_name) @@ -290,4 +290,57 @@ } } + +func (self *EventTable) RunQuery( + ctx context.Context, + config_obj *config_proto.Config, + artifact_name string, + query_responder responder.Responder, + event *actions_proto.VQLCollectorArgs) { + + wg := &sync.WaitGroup{} + defer wg.Wait() + + refresh_timeout := event.Timeout + event.Timeout = 999999 + + for { + sub_ctx, cancel := context.WithCancel(ctx) + + refresh := utils.Jitter(time.Second * time.Duration(refresh_timeout)) + + // Start the query - if it is an event query this will not + // complete until we cancell it due to refresh. If it is not + // an event query, it will complete sooner but we wont start + // it again until the refresh time. + wg.Add(1) + go func() { + defer wg.Done() + + query_responder.Log(ctx, logging.DEBUG, + fmt.Sprintf("Starting monitoring query %s with refresh in %v", + artifact_name, refresh.Round(2).String())) + + action_obj := &VQLClientAction{} + action_obj.StartQuery( + config_obj, sub_ctx, query_responder, event) + }() + + select { + // Exit completely when the parent ctx is done. + case <-ctx.Done(): + cancel() + return + + // When the deadline fires, we refresh the query. + case <-time.After(refresh): + query_responder.Log(ctx, logging.DEBUG, + fmt.Sprintf("Refreshing monitoring query %s", artifact_name)) + cancel() + + // Wait here for it to be done. + wg.Wait() + } + } +} func (self *EventTable) StartFromWriteback( diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/actions/events_test.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/actions/events_test.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/actions/events_test.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/actions/events_test.go 2025-11-01 15:52:20.000000000 +0000 @@ -33,4 +33,6 @@ name: EventArtifact1 type: CLIENT_EVENT +parameters: +- name: Foo sources: - query: SELECT * FROM info() @@ -120,18 +122,20 @@ } -var server_state = &flows_proto.ClientEventTable{ - Artifacts: &flows_proto.ArtifactCollectorArgs{ - // These apply to all labels. - Artifacts: []string{"EventArtifact1"}, - }, - - // If the client is labeled as "Label1" then it will - // receive these - LabelEvents: []*flows_proto.LabelEvents{{ - Label: "Label1", +func server_state() *flows_proto.ClientEventTable { + return &flows_proto.ClientEventTable{ Artifacts: &flows_proto.ArtifactCollectorArgs{ - Artifacts: []string{"EventArtifact2"}, - }}, - }, + // These apply to all labels. + Artifacts: []string{"EventArtifact1"}, + }, + + // If the client is labeled as "Label1" then it will + // receive these + LabelEvents: []*flows_proto.LabelEvents{{ + Label: "Label1", + Artifacts: &flows_proto.ArtifactCollectorArgs{ + Artifacts: []string{"EventArtifact2"}, + }}, + }, + } } @@ -151,5 +155,5 @@ require.NoError(self.T(), client_manager.SetClientMonitoringState( - ctx, self.ConfigObj, "", server_state)) + ctx, self.ConfigObj, "", server_state())) // Check the version of the initial Event table it should be 0 @@ -282,4 +286,36 @@ assert.Contains(self.T(), string(data), "EventArtifact1") assert.Contains(self.T(), string(data), "EventArtifact2") + + // The below checks that the event table is updated if only a + // parameter is changed. + + // Check that Foo is empty right now + assert.Equal(self.T(), "", table.Events[0].Env[0].Value) + + // Update the monitoring table but only change artifact + // parameters. Set Foo to "X" + new_state := server_state() + new_state.Artifacts.Specs = append(new_state.Artifacts.Specs, + &flows_proto.ArtifactSpec{ + Artifact: "EventArtifact1", + Parameters: &flows_proto.ArtifactParameters{ + Env: []*actions_proto.VQLEnv{ + {Key: "Foo", Value: "X"}, + }, + }, + }) + + require.NoError(self.T(), client_manager.SetClientMonitoringState( + ctx, self.ConfigObj, "", new_state)) + + new_message = client_manager.GetClientUpdateEventTableMessage( + self.Ctx, self.ConfigObj, self.client_id) + + // Force the update on the table. + table.UpdateEventTable(ctx, wg, self.ConfigObj, output_chan, + new_message.UpdateEventTable) + + // The update took hold - the new parameter value is "X" + assert.Equal(self.T(), "X", table.Events[0].Env[0].Value) } @@ -303,5 +339,5 @@ require.NoError(self.T(), client_manager.SetClientMonitoringState( - ctx, self.ConfigObj, "", server_state)) + ctx, self.ConfigObj, "", server_state())) message := client_manager.GetClientUpdateEventTableMessage( diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/actions/vql.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/actions/vql.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/actions/vql.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/actions/vql.go 2025-11-01 15:52:20.000000000 +0000 @@ -26,4 +26,5 @@ "runtime" "runtime/debug" + "strings" "time" @@ -133,5 +134,5 @@ } - name := utils.GetQueryName(arg.Query) + name := strings.Split(utils.GetQueryName(arg.Query), "/")[0] // Clients do not have a copy of artifacts so they need to be @@ -341,6 +342,14 @@ if uploader.GetCount() > 0 { - responder.Log(ctx, logging.DEFAULT, - fmt.Sprintf("%v: Uploaded %v files.", name, uploader.GetCount())) + if uploader.GetTransactionCount() > 0 { + responder.Log(ctx, logging.DEFAULT, + fmt.Sprintf("%v: Uploaded %v files with %v outstanding upload transactions.", + name, uploader.GetCount(), + uploader.GetTransactionCount())) + } else { + responder.Log(ctx, logging.DEFAULT, + fmt.Sprintf("%v: Uploaded %v files.", + name, uploader.GetCount())) + } } } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/api/artifacts.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/api/artifacts.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/api/artifacts.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/api/artifacts.go 2025-11-01 15:52:20.000000000 +0000 @@ -21,5 +21,4 @@ "bytes" "context" - "io/ioutil" "regexp" "strings" @@ -152,6 +151,22 @@ case api_proto.SetArtifactRequest_SET: - return manager.SetArtifactFile(ctx, + result, err := manager.SetArtifactFile(ctx, config_obj, principal, in.Artifact, required_prefix) + if err != nil { + return nil, Status(config_obj.Verbose, err) + } + + if len(in.Tags) > 0 { + err = manager.SetArtifactMetadata(ctx, config_obj, principal, + result.Name, &artifacts_proto.ArtifactMetadata{ + Tags: in.Tags, + }) + if err != nil { + return nil, Status(config_obj.Verbose, err) + } + } + + return result, nil + } @@ -382,4 +397,19 @@ } +func (self *matchPlan) hideEmptySources() bool { + // User wants to show empty sources + if self.empty_source { + return false + } + + // Tag searches should show all artifacts - including ones without + // sources. + if len(self.tags) > 0 { + return false + } + + return true +} + // All conditions must match func (self *matchPlan) matchArtifact(artifact *artifacts_proto.Artifact) bool { @@ -391,5 +421,5 @@ } - if !self.empty_source && len(artifact.Sources) == 0 { + if self.hideEmptySources() && len(artifact.Sources) == 0 { return false } @@ -644,5 +674,5 @@ } - data, err := ioutil.ReadAll(fd) + data, err := utils.ReadAllWithLimit(fd, constants.MAX_MEMORY) fd.Close() @@ -659,4 +689,5 @@ Op: api_proto.SetArtifactRequest_CHECK, Artifact: artifact_definition, + Tags: in.Tags, } @@ -664,8 +695,16 @@ org_config_obj, principal, request, prefix) if err != nil { - result.Errors = append(result.Errors, &api_proto.LoadArtifactError{ - Filename: file.Name, - Error: err.Error(), - }) + if len(result.Errors) < 10 { + result.Errors = append(result.Errors, &api_proto.LoadArtifactError{ + Filename: file.Name, + Error: err.Error(), + }) + + } else if len(result.Errors) == 10 { + result.Errors = append(result.Errors, &api_proto.LoadArtifactError{ + Filename: file.Name, + Error: "Too many errors - suppressing", + }) + } continue } @@ -748,5 +787,6 @@ } - if in.VfsPath[0] != paths.TEMP_ROOT.Components()[0] { + if in.VfsPath[0] != paths.TEMP_ROOT.Components()[0] && + in.VfsPath[0] != paths.PUBLIC_ROOT.Components()[0] { return nil, nil, errors.New("vfs_path should be a temp path") } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/api/authenticators/azure.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/api/authenticators/azure.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/api/authenticators/azure.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/api/authenticators/azure.go 2025-11-01 15:52:20.000000000 +0000 @@ -22,6 +22,4 @@ "encoding/base64" "fmt" - "io" - "io/ioutil" "net/http" @@ -31,9 +29,9 @@ "www.velocidex.com/golang/velociraptor/acls" api_utils "www.velocidex.com/golang/velociraptor/api/utils" - 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/logging" + utils "www.velocidex.com/golang/velociraptor/utils" ) @@ -131,5 +129,5 @@ logging.GetLogger(self.config_obj, &logging.GUIComponent). Error("invalid oauth azure state") - http.Redirect(w, r, utils.Homepage(self.config_obj), + http.Redirect(w, r, api_utils.Homepage(self.config_obj), http.StatusTemporaryRedirect) return @@ -151,5 +149,5 @@ "err": err.Error(), }).Error("getUserDataFromAzure") - http.Redirect(w, r, utils.Homepage(self.config_obj), + http.Redirect(w, r, api_utils.Homepage(self.config_obj), http.StatusTemporaryRedirect) return @@ -168,5 +166,5 @@ "err": err.Error(), }).Error("getUserDataFromAzure") - http.Redirect(w, r, utils.Homepage(self.config_obj), + http.Redirect(w, r, api_utils.Homepage(self.config_obj), http.StatusTemporaryRedirect) return @@ -174,5 +172,5 @@ http.SetCookie(w, cookie) - http.Redirect(w, r, utils.Homepage(self.config_obj), + http.Redirect(w, r, api_utils.Homepage(self.config_obj), http.StatusTemporaryRedirect) }) @@ -200,6 +198,5 @@ defer response.Body.Close() - contents, err := ioutil.ReadAll( - io.LimitReader(response.Body, constants.MAX_MEMORY)) + contents, err := utils.ReadAllWithLimit(response.Body, constants.MAX_MEMORY) if err != nil { return nil, fmt.Errorf("failed read response: %s", err.Error()) @@ -237,5 +234,6 @@ defer response.Body.Close() - data, _ := ioutil.ReadAll(response.Body) + data, _ := utils.ReadAllWithLimit(response.Body, + constants.MAX_MEMORY) return fmt.Sprintf("data:image/jpeg;base64,%v", diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/api/authenticators/github.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/api/authenticators/github.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/api/authenticators/github.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/api/authenticators/github.go 2025-11-01 15:52:20.000000000 +0000 @@ -21,6 +21,4 @@ "context" "fmt" - "io" - "io/ioutil" "net/http" @@ -30,9 +28,9 @@ "www.velocidex.com/golang/velociraptor/acls" api_utils "www.velocidex.com/golang/velociraptor/api/utils" - 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/logging" + utils "www.velocidex.com/golang/velociraptor/utils" ) @@ -132,5 +130,5 @@ logging.GetLogger(self.config_obj, &logging.GUIComponent). Error("invalid oauth github state") - http.Redirect(w, r, utils.Homepage(self.config_obj), + http.Redirect(w, r, api_utils.Homepage(self.config_obj), http.StatusTemporaryRedirect) return @@ -147,5 +145,5 @@ "err": formError, }).Error("getUserDataFromGithub") - http.Redirect(w, r, utils.Homepage(self.config_obj), + http.Redirect(w, r, api_utils.Homepage(self.config_obj), http.StatusTemporaryRedirect) return @@ -158,5 +156,5 @@ "err": err.Error(), }).Error("getUserDataFromGithub") - http.Redirect(w, r, utils.Homepage(self.config_obj), + http.Redirect(w, r, api_utils.Homepage(self.config_obj), http.StatusTemporaryRedirect) return @@ -170,5 +168,5 @@ "err": err.Error(), }).Error("getUserDataFromGithub") - http.Redirect(w, r, utils.Homepage(self.config_obj), + http.Redirect(w, r, api_utils.Homepage(self.config_obj), http.StatusTemporaryRedirect) return @@ -190,5 +188,5 @@ "err": err.Error(), }).Error("getUserDataFromGithub") - http.Redirect(w, r, utils.Homepage(self.config_obj), + http.Redirect(w, r, api_utils.Homepage(self.config_obj), http.StatusTemporaryRedirect) return @@ -196,5 +194,5 @@ http.SetCookie(w, cookie) - http.Redirect(w, r, utils.Homepage(self.config_obj), + http.Redirect(w, r, api_utils.Homepage(self.config_obj), http.StatusTemporaryRedirect) }) @@ -218,6 +216,5 @@ defer response.Body.Close() - contents, err := ioutil.ReadAll( - io.LimitReader(response.Body, constants.MAX_MEMORY)) + contents, err := utils.ReadAllWithLimit(response.Body, constants.MAX_MEMORY) if err != nil { return nil, fmt.Errorf("failed read response: %s", err.Error()) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/api/authenticators/google.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/api/authenticators/google.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/api/authenticators/google.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/api/authenticators/google.go 2025-11-01 15:52:20.000000000 +0000 @@ -23,6 +23,4 @@ "encoding/base64" "fmt" - "io" - "io/ioutil" "net/http" "time" @@ -36,5 +34,4 @@ api_proto "www.velocidex.com/golang/velociraptor/api/proto" api_utils "www.velocidex.com/golang/velociraptor/api/utils" - utils "www.velocidex.com/golang/velociraptor/api/utils" config_proto "www.velocidex.com/golang/velociraptor/config/proto" "www.velocidex.com/golang/velociraptor/constants" @@ -43,4 +40,5 @@ "www.velocidex.com/golang/velociraptor/logging" "www.velocidex.com/golang/velociraptor/services" + utils "www.velocidex.com/golang/velociraptor/utils" ) @@ -143,5 +141,5 @@ cookie := http.Cookie{ Name: "oauthstate", - Path: utils.GetBasePath(config_obj), + Path: api_utils.GetBasePath(config_obj), Value: state, Secure: true, @@ -161,5 +159,5 @@ logging.GetLogger(self.config_obj, &logging.GUIComponent). Error("invalid oauth google state") - http.Redirect(w, r, utils.Homepage(self.config_obj), + http.Redirect(w, r, api_utils.Homepage(self.config_obj), http.StatusTemporaryRedirect) return @@ -172,5 +170,5 @@ "err": err.Error(), }).Error("getUserDataFromGoogle") - http.Redirect(w, r, utils.Homepage(self.config_obj), + http.Redirect(w, r, api_utils.Homepage(self.config_obj), http.StatusTemporaryRedirect) return @@ -184,5 +182,5 @@ "err": err.Error(), }).Error("getUserDataFromGoogle") - http.Redirect(w, r, utils.Homepage(self.config_obj), + http.Redirect(w, r, api_utils.Homepage(self.config_obj), http.StatusTemporaryRedirect) return @@ -205,5 +203,5 @@ "err": err.Error(), }).Error("getUserDataFromGoogle") - http.Redirect(w, r, utils.Homepage(self.config_obj), + http.Redirect(w, r, api_utils.Homepage(self.config_obj), http.StatusTemporaryRedirect) return @@ -211,5 +209,5 @@ http.SetCookie(w, cookie) - http.Redirect(w, r, utils.Homepage(self.config_obj), + http.Redirect(w, r, api_utils.Homepage(self.config_obj), http.StatusTemporaryRedirect) }) @@ -243,6 +241,5 @@ defer response.Body.Close() - contents, err := ioutil.ReadAll( - io.LimitReader(response.Body, constants.MAX_MEMORY)) + contents, err := utils.ReadAllWithLimit(response.Body, constants.MAX_MEMORY) if err != nil { return nil, fmt.Errorf("failed read response: %s", err.Error()) @@ -253,5 +250,5 @@ func installLogoff(config_obj *config_proto.Config, mux *api_utils.ServeMux) { - mux.Handle(utils.GetBasePath(config_obj, "/app/logoff.html"), + mux.Handle(api_utils.GetBasePath(config_obj, "/app/logoff.html"), IpFilter(config_obj, api_utils.HandlerFunc(nil, @@ -274,5 +271,5 @@ http.SetCookie(w, &http.Cookie{ Name: "VelociraptorAuth", - Path: utils.GetBaseDirectory(config_obj), + Path: api_utils.GetBaseDirectory(config_obj), Value: "deleted", Secure: true, diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/api/download.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/api/download.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/api/download.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/api/download.go 2025-11-01 15:52:20.000000000 +0000 @@ -31,5 +31,4 @@ "html" "io" - "io/ioutil" "net/http" "net/url" @@ -50,4 +49,5 @@ 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/file_store" "www.velocidex.com/golang/velociraptor/file_store/api" @@ -790,5 +790,5 @@ defer fd.Close() - data, err := ioutil.ReadAll(fd) + data, err := utils.ReadAllWithLimit(fd, constants.MAX_MEMORY) if err != nil { return nil, err diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/api/proto/artifacts.pb.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/api/proto/artifacts.pb.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/api/proto/artifacts.pb.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/api/proto/artifacts.pb.go 2025-11-01 15:52:20.000000000 +0000 @@ -263,9 +263,4 @@ unknownFields protoimpl.UnknownFields - // Deprecated. - // - // string vfs_path = 1 [(sem_type) = { - // description: "The vfs path relative to the artifacts definition store." - // }]; Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` } @@ -362,6 +357,8 @@ unknownFields protoimpl.UnknownFields - Artifact string `protobuf:"bytes,2,opt,name=artifact,proto3" json:"artifact,omitempty"` - Op SetArtifactRequest_Operation `protobuf:"varint,3,opt,name=op,proto3,enum=proto.SetArtifactRequest_Operation" json:"op,omitempty"` + Artifact string `protobuf:"bytes,2,opt,name=artifact,proto3" json:"artifact,omitempty"` + // Also set these tags. + Tags []string `protobuf:"bytes,4,rep,name=tags,proto3" json:"tags,omitempty"` + Op SetArtifactRequest_Operation `protobuf:"varint,3,opt,name=op,proto3,enum=proto.SetArtifactRequest_Operation" json:"op,omitempty"` } @@ -405,4 +402,11 @@ } +func (x *SetArtifactRequest) GetTags() []string { + if x != nil { + return x.Tags + } + return nil +} + func (x *SetArtifactRequest) GetOp() SetArtifactRequest_Operation { if x != nil { @@ -543,6 +547,7 @@ unknownFields protoimpl.UnknownFields - Prefix string `protobuf:"bytes,1,opt,name=prefix,proto3" json:"prefix,omitempty"` - Filter string `protobuf:"bytes,2,opt,name=filter,proto3" json:"filter,omitempty"` + Prefix string `protobuf:"bytes,1,opt,name=prefix,proto3" json:"prefix,omitempty"` + Tags []string `protobuf:"bytes,6,rep,name=tags,proto3" json:"tags,omitempty"` + Filter string `protobuf:"bytes,2,opt,name=filter,proto3" json:"filter,omitempty"` // NOTE: the vfs path must be in the VFS temp directory. Data []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` @@ -590,4 +595,11 @@ } +func (x *LoadArtifactPackRequest) GetTags() []string { + if x != nil { + return x.Tags + } + return nil +} + func (x *LoadArtifactPackRequest) GetFilter() string { if x != nil { @@ -1362,5 +1374,5 @@ 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x61, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x52, 0x08, 0x61, - 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x22, 0xf6, 0x01, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x41, + 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x22, 0x8a, 0x02, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a, 0x08, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, @@ -1368,148 +1380,150 @@ 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x61, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x52, 0x08, 0x61, 0x72, 0x74, 0x69, - 0x66, 0x61, 0x63, 0x74, 0x12, 0x5a, 0x0a, 0x02, 0x6f, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x23, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, - 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4f, 0x70, 0x65, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x25, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x1f, 0x12, 0x1d, 0x57, - 0x68, 0x61, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x64, 0x6f, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x3f, 0x52, 0x02, 0x6f, 0x70, - 0x22, 0x3e, 0x0a, 0x09, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x07, 0x0a, - 0x03, 0x53, 0x45, 0x54, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, - 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x10, 0x02, 0x12, 0x11, 0x0a, - 0x0d, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x5f, 0x41, 0x4e, 0x44, 0x5f, 0x53, 0x45, 0x54, 0x10, 0x03, - 0x22, 0x84, 0x01, 0x0a, 0x13, 0x53, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x23, - 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x03, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x77, - 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x77, - 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x45, 0x0a, 0x11, 0x4c, 0x6f, 0x61, 0x64, 0x41, - 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1a, 0x0a, 0x08, - 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x9a, - 0x01, 0x0a, 0x17, 0x4c, 0x6f, 0x61, 0x64, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x50, - 0x61, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, - 0x65, 0x66, 0x69, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x72, 0x65, 0x66, - 0x69, 0x78, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, - 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x19, - 0x0a, 0x08, 0x76, 0x66, 0x73, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x07, 0x76, 0x66, 0x73, 0x50, 0x61, 0x74, 0x68, 0x12, 0x20, 0x0a, 0x0c, 0x72, 0x65, 0x61, - 0x6c, 0x6c, 0x79, 0x5f, 0x64, 0x6f, 0x5f, 0x69, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0a, 0x72, 0x65, 0x61, 0x6c, 0x6c, 0x79, 0x44, 0x6f, 0x49, 0x74, 0x22, 0x9a, 0x01, 0x0a, 0x18, - 0x4c, 0x6f, 0x61, 0x64, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x50, 0x61, 0x63, 0x6b, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x14, 0x73, 0x75, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x13, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, - 0x75, 0x6c, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x76, - 0x66, 0x73, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x76, - 0x66, 0x73, 0x50, 0x61, 0x74, 0x68, 0x12, 0x30, 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, + 0x66, 0x61, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x04, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x5a, 0x0a, 0x02, 0x6f, 0x70, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x65, 0x74, + 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, + 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x25, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, + 0x1f, 0x12, 0x1d, 0x57, 0x68, 0x61, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x64, 0x6f, 0x20, 0x77, 0x69, + 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x3f, + 0x52, 0x02, 0x6f, 0x70, 0x22, 0x3e, 0x0a, 0x09, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x07, 0x0a, 0x03, 0x53, 0x45, 0x54, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, + 0x4c, 0x45, 0x54, 0x45, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x10, + 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x5f, 0x41, 0x4e, 0x44, 0x5f, 0x53, + 0x45, 0x54, 0x10, 0x03, 0x22, 0x84, 0x01, 0x0a, 0x13, 0x53, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, + 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x12, + 0x1a, 0x0a, 0x08, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x08, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x45, 0x0a, 0x11, 0x4c, 0x6f, 0x61, 0x64, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, - 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x22, 0x79, 0x0a, 0x0b, 0x41, 0x50, 0x49, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x42, 0x2f, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x29, 0x12, 0x27, - 0x41, 0x6e, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6f, 0x63, 0x63, 0x75, 0x72, 0x72, 0x65, - 0x64, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, - 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x2e, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x23, - 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x22, 0xf9, 0x03, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a, 0x08, 0x61, 0x72, 0x74, 0x69, - 0x66, 0x61, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x28, 0xe2, 0xfc, 0xe3, 0xc4, - 0x01, 0x22, 0x12, 0x20, 0x54, 0x68, 0x65, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, - 0x20, 0x66, 0x6f, 0x72, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x77, 0x65, 0x20, 0x72, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x52, 0x08, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x4b, - 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x37, 0xe2, 0xfc, - 0xe3, 0xc4, 0x01, 0x31, 0x12, 0x2f, 0x54, 0x68, 0x65, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x77, 0x65, 0x20, 0x6e, 0x65, 0x65, 0x64, 0x20, 0x28, 0x65, - 0x2e, 0x67, 0x2e, 0x20, 0x4d, 0x4f, 0x4e, 0x49, 0x54, 0x4f, 0x52, 0x49, 0x4e, 0x47, 0x5f, 0x44, - 0x41, 0x49, 0x4c, 0x59, 0x29, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x30, 0x0a, 0x06, 0x66, - 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xe2, 0xfc, 0xe3, - 0xc4, 0x01, 0x12, 0x12, 0x10, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x65, 0x2e, 0x67, 0x2e, - 0x20, 0x68, 0x74, 0x6d, 0x6c, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x1b, 0x0a, - 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x64, 0x61, - 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x61, - 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, - 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, - 0x54, 0x69, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, - 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, - 0x17, 0x0a, 0x07, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x66, 0x6c, 0x6f, 0x77, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x68, 0x75, 0x6e, 0x74, - 0x5f, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x68, 0x75, 0x6e, 0x74, 0x49, - 0x64, 0x12, 0x7c, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, - 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, - 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x42, - 0x42, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x3c, 0x12, 0x3a, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x20, - 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x73, - 0x65, 0x20, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x74, 0x79, 0x70, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x2e, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x22, - 0x83, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x65, 0x6d, - 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x65, 0x6d, - 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x3e, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x42, 0x22, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x1c, 0x12, - 0x1a, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6f, 0x72, 0x20, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, - 0x67, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x52, 0x08, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x73, 0x22, 0x19, 0x0a, 0x17, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, - 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x69, 0x63, 0x74, - 0x22, 0xfb, 0x01, 0x0a, 0x20, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, - 0x6c, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x88, 0x01, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x6b, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, - 0x65, 0x12, 0x63, 0x54, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x49, 0x44, - 0x20, 0x77, 0x65, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x76, 0x61, - 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, - 0x67, 0x20, 0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x20, 0x49, 0x66, 0x20, 0x65, 0x6d, 0x70, 0x74, 0x79, - 0x20, 0x77, 0x65, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x27, 0x73, 0x20, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, - 0x20, 0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, - 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x19, 0x0a, 0x08, - 0x6c, 0x6f, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x6c, 0x6f, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x72, 0x67, 0x5f, 0x69, - 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x72, 0x67, 0x49, 0x64, 0x22, 0xab, - 0x01, 0x0a, 0x0e, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x2f, 0x0a, - 0x0a, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, - 0x63, 0x74, 0x52, 0x0a, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, - 0x0a, 0x0e, 0x72, 0x6f, 0x77, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x73, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x05, 0x52, 0x0d, 0x72, 0x6f, 0x77, 0x54, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x6c, 0x6f, 0x67, 0x5f, 0x74, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x05, 0x52, 0x0d, 0x6c, - 0x6f, 0x67, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x73, 0x22, 0x4e, 0x0a, 0x21, - 0x4c, 0x69, 0x73, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x29, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, - 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x22, 0x31, 0x0a, 0x19, - 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, - 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x22, - 0x5a, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, - 0x08, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x65, 0x74, 0x4d, 0x6f, 0x6e, 0x69, 0x74, + 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x22, 0xae, 0x01, 0x0a, 0x17, 0x4c, 0x6f, 0x61, 0x64, 0x41, 0x72, 0x74, 0x69, 0x66, + 0x61, 0x63, 0x74, 0x50, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, + 0x0a, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x06, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x19, 0x0a, 0x08, 0x76, 0x66, 0x73, 0x5f, 0x70, 0x61, + 0x74, 0x68, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x76, 0x66, 0x73, 0x50, 0x61, 0x74, + 0x68, 0x12, 0x20, 0x0a, 0x0c, 0x72, 0x65, 0x61, 0x6c, 0x6c, 0x79, 0x5f, 0x64, 0x6f, 0x5f, 0x69, + 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x72, 0x65, 0x61, 0x6c, 0x6c, 0x79, 0x44, + 0x6f, 0x49, 0x74, 0x22, 0x9a, 0x01, 0x0a, 0x18, 0x4c, 0x6f, 0x61, 0x64, 0x41, 0x72, 0x74, 0x69, + 0x66, 0x61, 0x63, 0x74, 0x50, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x31, 0x0a, 0x14, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x5f, 0x61, + 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x13, + 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x76, 0x66, 0x73, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, + 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x76, 0x66, 0x73, 0x50, 0x61, 0x74, 0x68, 0x12, 0x30, + 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x41, 0x72, 0x74, 0x69, 0x66, + 0x61, 0x63, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, + 0x22, 0x79, 0x0a, 0x0b, 0x41, 0x50, 0x49, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x45, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x42, 0x2f, + 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x29, 0x12, 0x27, 0x41, 0x6e, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x20, 0x6f, 0x63, 0x63, 0x75, 0x72, 0x72, 0x65, 0x64, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, + 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x2e, 0x52, + 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xf9, 0x03, 0x0a, 0x10, + 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x44, 0x0a, 0x08, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x28, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x22, 0x12, 0x20, 0x54, 0x68, 0x65, 0x20, + 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x77, 0x68, 0x69, + 0x63, 0x68, 0x20, 0x77, 0x65, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x08, 0x61, 0x72, + 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x4b, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x37, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x31, 0x12, 0x2f, 0x54, 0x68, + 0x65, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x77, 0x65, + 0x20, 0x6e, 0x65, 0x65, 0x64, 0x20, 0x28, 0x65, 0x2e, 0x67, 0x2e, 0x20, 0x4d, 0x4f, 0x4e, 0x49, + 0x54, 0x4f, 0x52, 0x49, 0x4e, 0x47, 0x5f, 0x44, 0x41, 0x49, 0x4c, 0x59, 0x29, 0x52, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x12, 0x30, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x18, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x12, 0x12, 0x10, 0x46, 0x6f, 0x72, + 0x6d, 0x61, 0x74, 0x20, 0x65, 0x2e, 0x67, 0x2e, 0x20, 0x68, 0x74, 0x6d, 0x6c, 0x52, 0x06, 0x66, + 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, + 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x64, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, + 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x08, + 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, + 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x6c, 0x6f, 0x77, 0x5f, + 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x6c, 0x6f, 0x77, 0x49, 0x64, + 0x12, 0x17, 0x0a, 0x07, 0x68, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x68, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x7c, 0x0a, 0x0a, 0x70, 0x61, 0x72, + 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x42, 0x42, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x3c, 0x12, + 0x3a, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, + 0x72, 0x73, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x73, 0x65, 0x20, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, + 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x6f, 0x66, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x52, 0x0a, 0x70, 0x61, 0x72, + 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x22, 0x83, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x52, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, + 0x61, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x3e, 0x0a, + 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x42, + 0x22, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x1c, 0x12, 0x1a, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6f, + 0x72, 0x20, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x73, 0x2e, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x22, 0x19, 0x0a, + 0x17, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x69, 0x63, 0x74, 0x22, 0xfb, 0x01, 0x0a, 0x20, 0x4c, 0x69, 0x73, + 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x88, 0x01, + 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x6b, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x65, 0x12, 0x63, 0x54, 0x68, 0x65, 0x20, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x49, 0x44, 0x20, 0x77, 0x65, 0x20, 0x6c, 0x69, 0x73, 0x74, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x6d, + 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x20, + 0x49, 0x66, 0x20, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x20, 0x77, 0x65, 0x20, 0x6c, 0x69, 0x73, 0x74, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x27, 0x73, 0x20, 0x6d, 0x6f, + 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x52, 0x08, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x72, 0x74, 0x69, + 0x66, 0x61, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x72, 0x74, 0x69, + 0x66, 0x61, 0x63, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x6c, 0x6f, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6c, 0x6f, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x15, 0x0a, 0x06, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x6f, 0x72, 0x67, 0x49, 0x64, 0x22, 0xab, 0x01, 0x0a, 0x0e, 0x41, 0x76, 0x61, 0x69, 0x6c, + 0x61, 0x62, 0x6c, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x72, 0x74, + 0x69, 0x66, 0x61, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x72, 0x74, + 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x2f, 0x0a, 0x0a, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x0a, 0x64, 0x65, 0x66, 0x69, + 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x6f, 0x77, 0x5f, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x05, 0x52, 0x0d, + 0x72, 0x6f, 0x77, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x73, 0x12, 0x25, 0x0a, + 0x0e, 0x6c, 0x6f, 0x67, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x73, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x05, 0x52, 0x0d, 0x6c, 0x6f, 0x67, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x73, 0x22, 0x4e, 0x0a, 0x21, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x76, 0x61, 0x69, + 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x04, 0x6c, 0x6f, 0x67, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x04, + 0x6c, 0x6f, 0x67, 0x73, 0x22, 0x31, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x22, 0x69, 0x0a, 0x19, 0x53, - 0x65, 0x74, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, - 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x36, - 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, - 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x72, 0x67, 0x73, 0x52, 0x07, 0x72, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x42, 0x31, 0x5a, 0x2f, 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, 0x70, 0x69, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x22, 0x5a, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x4d, 0x6f, + 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x53, 0x65, 0x74, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x73, 0x22, 0x69, 0x0a, 0x19, 0x53, 0x65, 0x74, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, + 0x72, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x36, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x41, 0x72, 0x67, 0x73, 0x52, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x42, 0x31, + 0x5a, 0x2f, 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, 0x70, 0x69, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/api/proto/artifacts.proto /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/api/proto/artifacts.proto --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/api/proto/artifacts.proto 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/api/proto/artifacts.proto 2025-11-01 15:52:20.000000000 +0000 @@ -37,8 +37,4 @@ message GetArtifactRequest { - // Deprecated. - // string vfs_path = 1 [(sem_type) = { - // description: "The vfs path relative to the artifacts definition store." - // }]; string name = 2 [(sem_type) = { description: "The artifact name." @@ -54,13 +50,11 @@ message SetArtifactRequest { - // Deprecated - // string vfs_path = 1 [(sem_type) = { - // description: "The vfs path relative to the artifacts definition store." - // }]; - string artifact = 2 [(sem_type) = { description: "The artifact data, or a default.", }]; + // Also set these tags. + repeated string tags = 4; + enum Operation { SET = 0; @@ -92,4 +86,5 @@ message LoadArtifactPackRequest { string prefix = 1; + repeated string tags = 6; string filter = 2; diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/api/proto/download.pb.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/api/proto/download.pb.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/api/proto/download.pb.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/api/proto/download.pb.go 2025-11-01 15:52:20.000000000 +0000 @@ -188,4 +188,6 @@ Filename string `protobuf:"bytes,1,opt,name=filename,proto3" json:"filename,omitempty"` Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"` + // A list of Path components to the VFS + VfsPath []string `protobuf:"bytes,3,rep,name=VfsPath,proto3" json:"VfsPath,omitempty"` } @@ -236,4 +238,11 @@ } +func (x *FormUploadMetadata) GetVfsPath() []string { + if x != nil { + return x.VfsPath + } + return nil +} + var File_download_proto protoreflect.FileDescriptor @@ -263,13 +272,15 @@ 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x76, 0x66, 0x73, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x76, 0x66, 0x73, 0x50, 0x61, 0x74, 0x68, 0x22, 0x42, 0x0a, 0x12, 0x46, 0x6f, 0x72, + 0x52, 0x07, 0x76, 0x66, 0x73, 0x50, 0x61, 0x74, 0x68, 0x22, 0x5c, 0x0a, 0x12, 0x46, 0x6f, 0x72, 0x6d, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, - 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x42, 0x31, 0x5a, - 0x2f, 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, 0x70, 0x69, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x18, 0x0a, + 0x07, 0x56, 0x66, 0x73, 0x50, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, + 0x56, 0x66, 0x73, 0x50, 0x61, 0x74, 0x68, 0x42, 0x31, 0x5a, 0x2f, 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, 0x70, 0x69, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/api/proto/download.proto /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/api/proto/download.proto --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/api/proto/download.proto 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/api/proto/download.proto 2025-11-01 15:52:20.000000000 +0000 @@ -35,3 +35,6 @@ string filename = 1; string url = 2; + + // A list of Path components to the VFS + repeated string VfsPath = 3; } \ No newline at end of file diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/api/upload.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/api/upload.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/api/upload.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/api/upload.go 2025-11-01 15:52:20.000000000 +0000 @@ -231,4 +231,5 @@ form_desc.Url = path_manager.URL() + form_desc.VfsPath = pathspec.Components() writer, err := file_store_factory.WriteFile(pathspec) Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/assets: ab0x.go diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Admin/Client/Uninstall.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Admin/Client/Uninstall.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Admin/Client/Uninstall.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Admin/Client/Uninstall.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -40,5 +40,6 @@ SELECT KeyName, DisplayName, UninstallString, - if(condition=ReallyDoIt, then=uninstall(Name=UninstallString).Stdout) AS UninstallLog + if(condition=ReallyDoIt, + then=uninstall(UninstallString=UninstallString).Stdout) AS UninstallLog FROM packages diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Generic/Utils/DeadDiskRemapping.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Generic/Utils/DeadDiskRemapping.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Generic/Utils/DeadDiskRemapping.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Generic/Utils/DeadDiskRemapping.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -252,5 +252,5 @@ - query: | LET WindowsPartition <= - _FindWindowsPartition(ImagePath=ImagePath, accessor=Accessor)[0] + _FindWindowsPartition(ImagePath=ImagePath, Accessor=Accessor)[0] LET Remappings <= parse_yaml( diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Generic/Utils/FetchBinary.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Generic/Utils/FetchBinary.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Generic/Utils/FetchBinary.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Generic/Utils/FetchBinary.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -51,4 +51,9 @@ sources: - query: | + LET S = scope() + + -- 1GB max + LET HASH_MAX_SIZE <= S.HASH_MAX_SIZE || 1000000000 + -- Optionally accepts multiple download URLs from the server LET ParseUrls(Url) = parse_json_array(data=Url || '[]') diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Generic/Utils/SendEmail.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Generic/Utils/SendEmail.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Generic/Utils/SendEmail.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Generic/Utils/SendEmail.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -84,7 +84,5 @@ boundary=Boundary, sections=Sections, - header=get( - field='Header', - default=''))) + header=Header)) -- Add content type ("plain" or "html") and newlines to text. If Encode is set, @@ -155,5 +153,5 @@ -- Build the email parts - first the text message, then the attachments. - LET Message <= WrapInBoundary( + LET Message <= WrapInBoundary(Header="", Boundary=Boundary, Sections=Texts + AttachFiles(Files=FilesToUpload).Part) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Linux/Network/Netstat.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Linux/Network/Netstat.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Linux/Network/Netstat.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Linux/Network/Netstat.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -45,5 +45,5 @@ // Join them on a . and parse as an IP address - LET ParseIP4(X) = ip(parse=join(array=_ParseIP4(X=X).I, sep=".")) + LET ParseIP4(addr) = ip(parse=join(array=_ParseIP4(X=addr).I, sep=".")) -- https://elixir.bootlin.com/linux/latest/source/include/net/tcp_states.h#L14 @@ -76,5 +76,5 @@ WHERE Type =~ "socket" - LET GetProcByInode(indoe) = SELECT * + LET GetProcByInode(inode) = SELECT * FROM AllSockets WHERE Inode = inode diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Server/Import/ArtifactExchange.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Server/Import/ArtifactExchange.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Server/Import/ArtifactExchange.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Server/Import/ArtifactExchange.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -35,10 +35,27 @@ default: "/**/*.{yaml,yml}" - name: Tag - description: Tag artifacts with this tag. + description: | + Tag artifacts with this tag. + + This applied in addition to any tags contained in the artifact + description. default: "Exchange" +export: | + LET _Tags(Data) = SELECT * FROM foreach(row={ + SELECT * FROM parse_lines(accessor="data", filename=Data, buffer_size=10000000) + WHERE Line =~ '''^\s*tags:''' + }, query={ + SELECT * FROM parse_records_with_regex( + accessor="data", file=Line, regex="#(?P[^ ]+)") + }) + + LET Tags(Data) = _Tags(Data=Data).Tag + sources: - query: | - LET X = SELECT artifact_set(definition=Definition, tags=[Tag,]) AS Definition + LET X = SELECT artifact_set( + definition=Definition, + tags=(Tag,) + Tags(Data=Definition) ) AS Definition FROM foreach(row={ SELECT Content FROM http_client( diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Server/Import/PreviousReleases.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Server/Import/PreviousReleases.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Server/Import/PreviousReleases.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Server/Import/PreviousReleases.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -24,10 +24,9 @@ The Velociraptor Release to import. type: choices - default: v0.73 + default: v0.74 choices: - - v0.7.0 - - v0.7.1 - v0.72 - v0.73 + - v0.74 sources: @@ -37,5 +36,5 @@ LET X = SELECT artifact_set( - prefix=Prefix, + prefix=Prefix, tags=VelociraptorRelease, definition=Definition) AS Definition FROM foreach(row={ diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Server/Internal/ToolDependencies.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Server/Internal/ToolDependencies.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Server/Internal/ToolDependencies.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Server/Internal/ToolDependencies.yaml 2025-11-01 23:56:18.000000000 +0000 @@ -8,17 +8,17 @@ tools: - name: VelociraptorWindows - url: https://github.com/Velocidex/velociraptor/releases/download/v0.75/velociraptor-v0.75.1-rc1-windows-amd64.exe + url: https://github.com/Velocidex/velociraptor/releases/download/v0.75/velociraptor-v0.75.4-windows-amd64.exe serve_locally: true - version: 0.75.1-rc1 + version: 0.75.4 - name: VelociraptorWindows_x86 - url: https://github.com/Velocidex/velociraptor/releases/download/v0.75/velociraptor-v0.75.1-rc1-windows-386.exe + url: https://github.com/Velocidex/velociraptor/releases/download/v0.75/velociraptor-v0.75.4-windows-386.exe serve_locally: true - version: 0.75.1-rc1 + version: 0.75.4 - name: VelociraptorLinux - url: https://github.com/Velocidex/velociraptor/releases/download/v0.75/velociraptor-v0.75.1-rc1-linux-amd64-musl + url: https://github.com/Velocidex/velociraptor/releases/download/v0.75/velociraptor-v0.75.4-linux-amd64-musl serve_locally: true - version: 0.75.1-rc1 + version: 0.75.4 # On MacOS we cannot embed the config in the binary so we use a @@ -32,10 +32,10 @@ - name: VelociraptorWindowsMSI - url: https://github.com/Velocidex/velociraptor/releases/download/v0.75/velociraptor-v0.75.1-rc1-windows-amd64.msi + url: https://github.com/Velocidex/velociraptor/releases/download/v0.75/velociraptor-v0.75.4-windows-amd64.msi serve_locally: true - version: 0.75.1-rc1 + version: 0.75.4 - name: VelociraptorWindows_x86MSI - url: https://github.com/Velocidex/velociraptor/releases/download/v0.75/velociraptor-v0.75.1-rc1-windows-386.msi + url: https://github.com/Velocidex/velociraptor/releases/download/v0.75/velociraptor-v0.75.4-windows-386.msi serve_locally: true - version: 0.75.1-rc1 + version: 0.75.4 diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Server/Internal/Welcome.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Server/Internal/Welcome.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Server/Internal/Welcome.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Server/Internal/Welcome.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -14,4 +14,7 @@ type: SERVER +sources: +- query: SELECT * FROM info() + reports: - type: CLIENT @@ -25,16 +28,25 @@ # Welcome to Velociraptor! - ## Common tasks: +
+ + * View server dashboard + * Import Extra artifacts + * Build Linux client packages + * Build Windows client MSI + * Build an Offline Collector + * Create a new Org + + - * Inspect the server's state - * Build an Offline Collector - * Write VQL notebooks * View Server Configuration * Inspect Server Audit Log * Manage Server Secrets - * Customize this welcome screen + * Manage Velociraptor Users + * Customize this welcome screen * Debug the server - Or simply search for a client in the search bar above. +
+ + Or search for a client in the search bar above. You can always get back to this welcome screen by clicking the diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Server/Monitor/Profile.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Server/Monitor/Profile.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Server/Monitor/Profile.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Server/Monitor/Profile.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -83,5 +83,4 @@ FROM profile(allocs=Allocs, block=Block, goroutine=Goroutine, heap=Heap, mutex=Mutex, profile=Profile, trace=Trace, - logs=Logs, queries=QueryLogs, metrics=Metrics, debug=if(condition=Verbose, then=2, else=1), duration=atoi(string=Duration)) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Server/Utils/CreateCollector.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Server/Utils/CreateCollector.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Server/Utils/CreateCollector.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Server/Utils/CreateCollector.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -86,5 +86,5 @@ - name: opt_level - default: "4" + default: "5" type: int description: Compression level (0=no compression). @@ -169,4 +169,5 @@ concurrency=Concurrency, format=Format, + remapping=Remapping, metadata=ContainerMetadata) @@ -243,4 +244,8 @@ default: | LET S = scope() + LET Remapping <= if(condition=Remapping, + then=log(message="Will load remapping rules from %v", args=Remapping) && + read_file(filename=Remapping), + else="") // Add all the tools we are going to use to the inventory. @@ -366,4 +371,5 @@ level=Level, concurrency=Concurrency, + remapping=Remapping, metadata=ContainerMetadata) @@ -403,4 +409,201 @@ FROM matching_tools +export: | + // Use this JSON schema to validate an offline collector spec.yaml + LET SpecSchema <= ''' + { + "type": "object", + "properties": { + "OS": { + "description": "OS Target to use", + "enum": ["Generic", "Windows", "Linux", "Windows_x86"], + "default": "Generic" + }, + "Artifacts": { + "type": "object", + "description": "Keys are artifact names to collect and values are strings", + "patternProperties": { + "^.+$": { + "type": "object", + "patternProperties": { + "^.+$": { + "type": "string" + } + } + } + } + }, + "Target": { + "description": "The type of collector to use", + "enum": ["ZIP", "GCS", "S3", "Azure", "SMBShare", "SFTP"] + }, + "EncryptionScheme": { + "enum": ["None", "X509"], + "default": "None" + }, + "OptVerbose": { + "type": "boolean", + "default": true + }, + "OptBanner": { + "type": "boolean", + "default": true + }, + "OptPrompt": { + "type": "boolean", + "default": false + }, + "OptAdmin": { + "type": "boolean", + "default": true + }, + "OptTempdir": { + "type": "string", + "default": "$TMP" + }, + "OptLevel": { + "type": "integer", + "default": 5 + }, + "OptConcurrency": { + "type": "integer", + "default": 2 + }, + "OptFilenameTemplate": { + "type": "string", + "default": "Collection-%FQDN%-%TIMESTAMP%" + }, + "OptCollectorTemplate": {"type": "string"}, + "OptFormat": { + "enum": ["jsonl", "csv"], + "default": "jsonl" + }, + "OptOutputDirectory": {"type": "string"}, + "OptCpuLimit": {"type": "integer"}, + "OptProgressTimeout": {"type": "integer"}, + "OptTimeout": {"type": "integer"}, + "OptDeleteAtExit": {"type": "boolean"} + }, + "allOf": [ + { "description": "Target Args for GCS", + "if": { + "properties": { "Target": { "const": "GCS" } } + }, + "then": { + "properties": { + "TargetArgs": { + "type": "object", + "properties": { + "bucket": {"type": "string"}, + "GCSKey": {"type": "string"} + }, + "additionalProperties": false, + "required": ["bucket", "GCSKey"] + } + } + } + }, + { "description": "Target Args for S3", + "if": { + "properties": { "Target": { "const": "S3" } } + }, + "then": { + "properties": { + "TargetArgs": { + "type": "object", + "properties": { + "bucket": {"type": "string"}, + "credentialsKey": {"type": "string"}, + "credentialsSecret": {"type": "string"}, + "credentialsToken": {"type": "string"}, + "region": {"type": "string"}, + "endpoint": {"type": "string"}, + "serverSideEncryption": {"type": "string"}, + "kmsEncryptionKey": {"type": "string"}, + "s3UploadRoot": {"type": "string"}, + "noverifycert": {"type": "boolean"} + }, + "additionalProperties": false, + "required": ["bucket"] + } + } + } + }, + { "description": "Target Args for AzureSASURL", + "if": { + "properties": { "Target": { "const": "AzureSASURL" } } + }, + "then": { + "properties": { + "TargetArgs": { + "type": "object", + "properties": { + "sas_url": {"type": "string"} + }, + "additionalProperties": false, + "required": ["sas_url"] + } + } + } + }, + { "description": "Target Args for SMBCollection", + "if": { + "properties": { "Target": { "const": "SMBCollection" } } + }, + "then": { + "properties": { + "TargetArgs": { + "type": "object", + "properties": { + "username": {"type": "string"}, + "password": {"type": "string"}, + "server_address": {"type": "string"} + }, + "additionalProperties": false, + "required": ["username", "password", "server_address"] + } + } + } + }, + { "description": "Target Args for SFTPCollection", + "if": { + "properties": { "Target": { "const": "SFTPCollection" } } + }, + "then": { + "properties": { + "TargetArgs": { + "type": "object", + "properties": { + "user": {"type": "string"}, + "path": {"type": "string"}, + "privatekey": {"type": "string"}, + "endpoint": {"type": "string"}, + "hostkey": {"type": "string"} + }, + "additionalProperties": false, + "required": ["user", "privatekey", "endpoint"] + } + } + } + }, + { "description": "Target Args for ZIP", + "if": { + "properties": { "Target": { "const": "ZIP" } } + }, + "then": { + "properties": { + "TargetArgs": { + "type": "object", + "default": {}, + "additionalProperties": false, + "properties": {} + } + } + } + } + ] + } + ''' + sources: - query: | @@ -467,5 +670,5 @@ then=dict(public_key=server_frontend_cert(), scheme="x509"), - else=encryption_args + else=encryption_args || dict() ) @@ -491,4 +694,5 @@ ), dict(name="Level", default=opt_level, type="int"), + dict(name="Remapping", default=""), dict(name="Concurrency", default=opt_concurrency, type="int"), dict(name="Format", default=opt_format), @@ -541,4 +745,28 @@ ) + LET _ <= upload(accessor="data", file=serialize(format="yaml", + item=dict( + OS=OS, + Artifacts=parameters, + Target=target, + EncryptionScheme=encryption_scheme || "None", + EncryptionArgs=encryption_args || dict(), + OptVerbose=opt_verbose, + OptBanner=opt_banner, + OptPrompt=opt_prompt, + OptAdmin=opt_admin, + OptTempdir=opt_tempdir, + OptLevel=opt_level, + OptConcurrency=opt_concurrency, + OptFormat=opt_format, + OptOutputDirectory=opt_output_directory, + OptFilenameTemplate=opt_filename_template, + OptCollectorFilename=opt_collector_filename, + OptCpuLimit=opt_cpu_limit, + OptProgressTimeout=opt_progress_timeout, + OptTimeout=opt_timeout, + OptDeleteAtExit=opt_delete_at_exit + )), name="spec.yaml") + // Do the actual repacking. SELECT repack( diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Server/Utils/DeleteMonitoringData.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Server/Utils/DeleteMonitoringData.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Server/Utils/DeleteMonitoringData.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Server/Utils/DeleteMonitoringData.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -43,5 +43,5 @@ AND Hostname =~ HostnameRegex - LET SearchRegisteredClientsQuery = SELECT client_id, + LET SearchRegisteredClientsQuery = SELECT client_id AS ClientId, os_info.hostname AS hostname FROM clients() Only in /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Windows/ActiveDirectory: BloodHound.yaml Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Windows/ActiveDirectory: SharpHound.yaml Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Windows: Collectors diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Windows/Detection/BinaryHunter.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Windows/Detection/BinaryHunter.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Windows/Detection/BinaryHunter.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Windows/Detection/BinaryHunter.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -72,4 +72,8 @@ Enable this to disable potentially flakey APIs which may cause crashes. + - name: UploadFiles + type: bool + description: | + Select to upload files. sources: @@ -121,5 +125,5 @@ -- parse PE attributes and run final filters - SELECT + LET results = SELECT dict(OSPath=OSPath,Name=Name,Size=Size, Timestamps=dict(Mtime=Mtime,Atime=Atime,Ctime=Ctime,Btime=Btime) @@ -150,2 +154,10 @@ then= Hash.SHA256 in SHA256Array) ), else = True ) + + LET upload_files= SELECT *, + upload(file=File.OSPath) as UploadFile + FROM results + + SELECT * FROM if(condition= UploadFiles, + then= upload_files, + else= results) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Windows/Detection/TemplateInjection.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Windows/Detection/TemplateInjection.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Windows/Detection/TemplateInjection.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Windows/Detection/TemplateInjection.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -37,12 +37,12 @@ - name: SearchGlob description: Glob to search - default: C:\Users\**\*.{rtf,doc,dot,docx,docm,dotx,dotm,docb,xls,xlt,xlm,xlsx,xlsm,xltx,xltm,xlsb,ppt,pptx,pptm,potx,potm} + default: C:\Users\**\*.{rtf,doc,dot,docx,docm,dotx,dotm,docb,xls,xlt,xlm,xlsx,xlsm,xltx,xltm,xlsb,ppt,pptx,pptm,potx,potm,ppsx} - name: TemplateFileRegex description: Regex to search inside resource section. - default: '(document|settings)\.xml\.rels$' + default: '\.xml\.rels$' type: regex - name: TemplateTargetRegex description: Regex to search inside resource section. - default: '^(https?|smb|\\\\|//|mhtml)' + default: '^(https?|smb|\\\\|//|mhtml|script)' type: regex - name: UploadDocument diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Windows/Detection/Yara/PhysicalMemory.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Windows/Detection/Yara/PhysicalMemory.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Windows/Detection/Yara/PhysicalMemory.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Windows/Detection/Yara/PhysicalMemory.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -93,17 +93,9 @@ query: | + LET YARA_LOG_LEVEL <= 10 + -- check which Yara to use LET yara_rules <= YaraUrl || YaraRule - LET SparsePath = pathspec( - DelegateAccessor='raw_file', - DelegatePath='''\\.\pmem''', - Path={ - SELECT atoi(string=Start) AS Offset, - atoi(string=Length) AS Length - FROM Artifact.Windows.Sys.PhysicalMemoryRanges() - WHERE Type = 3 - }) - -- Load the WinPmem binary LET _ <= winpmem(service=ServiceName, driver_path=DriverPath) @@ -115,4 +107,4 @@ String.Name as HitName, String.HexData as HitHexData - FROM yara(files=SparsePath, accessor='winpmem', + FROM yara(files="pmem", accessor='winpmem', rules=yara_rules, context=ContextBytes, number=NumberOfHits) Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Windows/Detection: YaraX diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Windows/ETW/DotNetRundown.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Windows/ETW/DotNetRundown.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Windows/ETW/DotNetRundown.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Windows/ETW/DotNetRundown.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -22,4 +22,8 @@ default: . type: regex + - name: AnyKeyword + description: Any keyword level for collection + default: 0x48 + type: int - name: Timeout default: 20 @@ -37,5 +41,5 @@ description="CLR Rundown Provider", guid="{A669021C-C450-4609-A035-5AF59AF4DF18}", - any=0x48, timeout=Timeout) + any=AnyKeyword, timeout=Timeout) SELECT EventID, ProcessID, ProcessDetails.Data.Name AS ProcessName, diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Windows/ETW/KernelFile.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Windows/ETW/KernelFile.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Windows/ETW/KernelFile.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Windows/ETW/KernelFile.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -49,4 +49,5 @@ SELECT System.ID AS EID, + System AS _System, get(item=EIDLookup, field=str(str=System.ID)) AS EventType, process_tracker_get(id=System.ProcessID).Data AS ProcInfo, diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Windows/ETW/KernelNetwork.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Windows/ETW/KernelNetwork.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Windows/ETW/KernelNetwork.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Windows/ETW/KernelNetwork.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -44,4 +44,5 @@ SELECT System.ID AS EID, + System AS _System, get(item=EIDLookup, field=str(str=System.ID)) AS EventType, process_tracker_get(id=EventData.PID).Data AS ProcInfo, diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Windows/ETW/Registry.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Windows/ETW/Registry.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Windows/ETW/Registry.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Windows/ETW/Registry.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -64,4 +64,5 @@ SELECT Timestamp, EventType, + System AS _System, EventData AS _EventData, Process.Name AS ProcessName, Process.Username AS Owner, Process.CommandLine AS CommandLine, diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Windows/Events/TrackProcessesETW.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Windows/Events/TrackProcessesETW.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Windows/Events/TrackProcessesETW.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Windows/Events/TrackProcessesETW.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -73,7 +73,8 @@ Created=System.TimeStamp, ParentId=EventData.ParentId, - UserSID=EventData.UserSID, - ImageFileName=EventData.ImageFileName, - CommandLine=EventData.CommandLine + Username=EventData.UserSID, + Name=EventData.ImageFileName, + CommandLine=EventData.CommandLine, + Exe=EventData.CommandLine )) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Windows/Forensics/JumpLists.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Windows/Forensics/JumpLists.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Windows/Forensics/JumpLists.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Windows/Forensics/JumpLists.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -699,5 +699,5 @@ Parsed.StringData as _StringData, ShowExtraData(Parsed=Parsed) as _ExtraData, - property_store(data=Parsed) as _PropertyStore + property_store(Parsed=Parsed) as _PropertyStore FROM X diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Windows/Forensics/Lnk.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Windows/Forensics/Lnk.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Windows/Forensics/Lnk.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Windows/Forensics/Lnk.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -90,4 +90,7 @@ description: Also upload the link files themselves. type: bool + - name: UploadTarget + description: Also upload the link file's targets. + type: bool - name: SuspiciousOnly description: Only returns LNK files reporting a suspicious attribute @@ -1757,5 +1760,5 @@ FROM targets - LET parsed = SELECT + LET parsed_lnk_files = SELECT dict(OSPath=OSPath, Size=Size, Mtime=Mtime,Btime=Btime) as SourceFile, @@ -1765,5 +1768,5 @@ Parsed.StringData as StringData, ShowExtraData(Parsed=Parsed) as ExtraData, - property_store(data=Parsed) as PropertyStore, + property_store(Parsed=Parsed) as PropertyStore, Parsed.Overlay as Overlay, Parsed @@ -1776,5 +1779,5 @@ LET find_oldsize(propertystore) = SELECT Value FROM propertystore WHERE Description = 'System.Size' - LET results = SELECT parsed, + LET results = SELECT Parsed, SourceFile, ShellLinkHeader, @@ -1800,5 +1803,5 @@ find_oldpath(propertystore=PropertyStore)[0].Value as OldPath, find_oldsize(propertystore=PropertyStore)[0].Value as OldSize - FROM parsed + FROM parsed_lnk_files WHERE if(condition= IocRegex, then= format(format='%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\s%s', @@ -1891,5 +1894,6 @@ LET upload_results = SELECT *, - upload(file=SourceFile.OSPath) as UploadedLnk + upload(file=SourceFile.OSPath) as UploadedLnk, + UploadTarget && upload(file=LinkTarget.LinkTarget) as UploadedTarget FROM add_suspiciousb64 diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Windows/Forensics/Prefetch.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Windows/Forensics/Prefetch.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Windows/Forensics/Prefetch.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Windows/Forensics/Prefetch.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -315,4 +315,19 @@ WHERE SCCAHeader.Signature = "SCCA" + // These functions help to resolve the Kernel Device Filenames + // into a regular filename with drive letter. + LET DriveReplaceLookup <= SELECT + split(sep_string="\\", string=Name)[-1] AS Drive, + upcase(string=SymlinkTarget) AS Target, + len(list=SymlinkTarget) AS Len + FROM winobj() + WHERE Name =~ "^\\\\GLOBAL\\?\\?\\\\.:" + + LET _DriveReplace(Path) = SELECT Drive + Path[Len:] AS ResolvedPath + FROM DriveReplaceLookup + WHERE upcase(string=Path[:Len]) = Target + + LET DriveReplace(Path) = _DriveReplace(Path=Path)[0].ResolvedPath || Path + sources: - query: | @@ -331,4 +346,5 @@ SCCAHeader.Info.RunCount AS RunCount, SCCAHeader.Info.ExecutablePath AS ExecutablePath, + DriveReplace(Path=SCCAHeader.Info.ExecutablePath) AS ExecutableDosPath, OSPath, Name AS PrefetchFileName, diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Windows/KapeFiles/Extract.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Windows/KapeFiles/Extract.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Windows/KapeFiles/Extract.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Windows/KapeFiles/Extract.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -60,5 +60,5 @@ }) - LET ALLUploads = SELECT *, RootPathSpec + _Components AS FileUpload, + LET ALLUploads = SELECT *, ( RootPathSpec + _Components ).Path AS FileUpload, OutputPathSpec + _Components[2:] AS Dest, get(item=AllFileMetadata, diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Windows/Registry/NTUser.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Windows/Registry/NTUser.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Windows/Registry/NTUser.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Windows/Registry/NTUser.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -38,7 +38,7 @@ export: | - -- HivePath: The path to the hive on disk - -- RegistryPath: The path in the registry to mount the hive - -- RegMountPoint: The path inside the hive to mount (usually /) + // HivePath: The path to the hive on disk + // RegistryPath: The path in the registry to mount the hive + // RegMountPoint: The path inside the hive to mount (usually /) LET _map_file_to_reg_path(HivePath, RegistryPath, RegMountPoint, Accessor, Description) = dict( type="mount", description=Description, diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Windows/System/Pslist.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Windows/System/Pslist.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Windows/System/Pslist.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Windows/System/Pslist.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -37,5 +37,5 @@ LET ProcList = SELECT * FROM if(condition=UseTracker, then={ - SELECT Pid, Ppid, NULL AS TokenIsElevated, + SELECT CreateTime, Pid, Ppid, NULL AS TokenIsElevated, Username, Name, CommandLine, Exe, NULL AS Memory FROM process_tracker_pslist() @@ -44,5 +44,5 @@ }) - SELECT Pid, Ppid, TokenIsElevated, Name, CommandLine, Exe, + SELECT CreateTime, Pid, Ppid, TokenIsElevated, Name, CommandLine, Exe, token(pid=int(int=Pid)) as TokenInfo, hash(path=Exe) as Hash, @@ -57,3 +57,3 @@ AND NOT if(condition= UntrustedAuthenticode, then= Authenticode.Trusted = 'trusted' OR NOT Exe, - else= False ) + else= False ) \ No newline at end of file Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Windows/System: Threads.yaml diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Windows/System/VAD.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Windows/System/VAD.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/definitions/Windows/System/VAD.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/definitions/Windows/System/VAD.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -8,7 +8,7 @@ Available filters include process, mapping path, memory permissions or by content with yara. - + Use the UploadSection switch to upload any sections. - + A notebook suggestion is available for Strings analysis on uploaded sections. @@ -18,5 +18,5 @@ all sections and ProtectionRegex can override selection. - To filter on unmapped sections the MappingNameRegex: ^$ can be used. - - When uploading sections during analysis, its recommended to run once for + - When uploading sections during analysis, its recommended to run once for scoping, then a second time once confirmed for upload. @@ -53,4 +53,19 @@ type: int +export: | + // These functions help to resolve the Kernel Device Filenames + // into a regular filename with drive letter. + LET DriveReplaceLookup <= SELECT + split(sep_string="\\", string=Name)[-1] AS Drive, + upcase(string=SymlinkTarget) AS Target, + len(list=SymlinkTarget) AS Len + FROM winobj() + WHERE Name =~ "^\\\\GLOBAL\\?\\?\\\\.:" + + LET _DriveReplace(Path) = SELECT Drive + Path[Len:] AS ResolvedPath + FROM DriveReplaceLookup + WHERE upcase(string=Path[:Len]) = Target + + LET DriveReplace(Path) = _DriveReplace(Path=Path)[0].ResolvedPath || Path sources: @@ -68,5 +83,6 @@ row=processes, query={ - SELECT StartTime as ProcessCreateTime,Pid, Name, MappingName, + SELECT StartTime as ProcessCreateTime,Pid, Name, + DriveReplace(Path=MappingName) AS MappingName, format(format='%x-%x', args=[Address, Address+Size]) AS AddressRange, Address as _Address, @@ -164,5 +180,5 @@ # Strings analysis */ - + LET MinStringSize = 8 LET FindPrintable = ''' @@ -175,20 +191,20 @@ }''' LET YaraRule = regex_replace(source=FindPrintable,re='''\%\#\%''',replace=str(str=MinStringSize)) - - + + LET sections = SELECT vfs_path, client_path,file_size, uploaded_size FROM uploads(client_id=ClientId, flow_id=FlowId) WHERE vfs_path =~ '\.bin$' - + LET find_result(name) = SELECT * FROM source(artifact="Windows.System.VAD") WHERE SectionDump.StoredName = name LIMIT 1 - - + + LET row_results = SELECT *, find_result(name=client_path)[0] as Result FROM sections WHERE Result - + SELECT * FROM foreach(row=row_results, query={ @@ -199,5 +215,5 @@ Result.MappingName as MappingName, Result.AddressRange as AddressRange, - Result.Name as ProcesName, + Result.Name as ProcesName, Result.Pid as Pid, Result.Protection as Protection diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/testdata/server/testcases/artifacts.in.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/testdata/server/testcases/artifacts.in.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/testdata/server/testcases/artifacts.in.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/testdata/server/testcases/artifacts.in.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -1,11 +1,14 @@ +Parameters: + CLIENT_ID: "C.4f5e52adf0a337a9" + Queries: # Check the extension on file_store() - SELECT *, basename(path=file_store(path=vfs_path)) - FROM uploads(client_id='C.4f5e52adf0a337a9', + FROM uploads(client_id=CLIENT_ID, flow_id='F.BN2HJCPOF5U7U') # Schedule an artifact collection - SELECT collect_client( - client_id='C.11a3013ccaXXXXX', + client_id=CLIENT_ID, artifacts='Windows.Search.FileFinder', env=dict(SearchFilesGlobTable ='Glob\nC:/*.txt\n')).request AS Flow @@ -14,5 +17,5 @@ # Schedule using a new style spec decleration. - SELECT collect_client( - client_id='C.11a3013ccaXXXXX', + client_id=CLIENT_ID, artifacts='Windows.Search.FileFinder', spec=dict(`Windows.Search.FileFinder`=dict( @@ -29,5 +32,5 @@ # Test the "fs" accessor - SELECT OSPath FROM glob( - globs="/clients/C.4f5e52adf0a337a9/collections/F.BN2HJCPOF5U7U/uploads/**", + globs="/clients/" + CLIENT_ID + "/collections/F.BN2HJCPOF5U7U/uploads/**", accessor="fs") @@ -54,2 +57,20 @@ - SELECT name, metadata FROM artifact_definitions(names="Custom.Generic.Client.Info") + + # Set artifact tags + - SELECT artifact_set_metadata(name="Custom.Generic.Client.Info", tags=["OneTag"]) + FROM scope() + + - SELECT artifact_set_metadata(name="Custom.Generic.Client.Info", tags="OneTag") + FROM scope() + + # Single tag list + - SELECT artifact_set_metadata(name="Custom.Generic.Client.Info", tags=["OneTag",]) + FROM scope() + + - SELECT artifact_set_metadata(name="Custom.Generic.Client.Info", tags=["OneTag", "TwoTags"]) + FROM scope() + + # Clear the tags + - SELECT artifact_set_metadata(name="Custom.Generic.Client.Info", tags=[]) + FROM scope() diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/testdata/server/testcases/artifacts.out.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/testdata/server/testcases/artifacts.out.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/testdata/server/testcases/artifacts.out.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/testdata/server/testcases/artifacts.out.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -1,4 +1,4 @@ # Check the extension on file_store() -Query: SELECT *, basename(path=file_store(path=vfs_path)) FROM uploads(client_id='C.4f5e52adf0a337a9', flow_id='F.BN2HJCPOF5U7U') +Query: SELECT *, basename(path=file_store(path=vfs_path)) FROM uploads(client_id=CLIENT_ID, flow_id='F.BN2HJCPOF5U7U') Output: [ { @@ -52,5 +52,5 @@ # Schedule an artifact collection -Query: SELECT collect_client( client_id='C.11a3013ccaXXXXX', artifacts='Windows.Search.FileFinder', env=dict(SearchFilesGlobTable ='Glob\nC:/*.txt\n')).request AS Flow FROM scope() +Query: SELECT collect_client( client_id=CLIENT_ID, artifacts='Windows.Search.FileFinder', env=dict(SearchFilesGlobTable ='Glob\nC:/*.txt\n')).request AS Flow FROM scope() Output: [ { @@ -58,5 +58,5 @@ "creator": "VelociraptorServer", "user_data": "", - "client_id": "C.11a3013ccaXXXXX", + "client_id": "C.4f5e52adf0a337a9", "flow_id": "", "urgent": false, @@ -79,5 +79,6 @@ "max_batch_wait": 0, "max_batch_rows": 0, - "max_batch_rows_buffer": 0 + "max_batch_rows_buffer": 0, + "timeout": 0 } ], @@ -99,5 +100,5 @@ # Schedule using a new style spec decleration. -Query: SELECT collect_client( client_id='C.11a3013ccaXXXXX', artifacts='Windows.Search.FileFinder', spec=dict(`Windows.Search.FileFinder`=dict( SearchFilesGlobTable ='Glob\nC:/*.txt\n'))).request AS Flow FROM scope() +Query: SELECT collect_client( client_id=CLIENT_ID, artifacts='Windows.Search.FileFinder', spec=dict(`Windows.Search.FileFinder`=dict( SearchFilesGlobTable ='Glob\nC:/*.txt\n'))).request AS Flow FROM scope() Output: [ { @@ -105,5 +106,5 @@ "creator": "VelociraptorServer", "user_data": "", - "client_id": "C.11a3013ccaXXXXX", + "client_id": "C.4f5e52adf0a337a9", "flow_id": "", "urgent": false, @@ -126,5 +127,6 @@ "max_batch_wait": 0, "max_batch_rows": 0, - "max_batch_rows_buffer": 0 + "max_batch_rows_buffer": 0, + "timeout": 0 } ], @@ -162,5 +164,5 @@ # Test the "fs" accessor -Query: SELECT OSPath FROM glob( globs="/clients/C.4f5e52adf0a337a9/collections/F.BN2HJCPOF5U7U/uploads/**", accessor="fs") +Query: SELECT OSPath FROM glob( globs="/clients/" + CLIENT_ID + "/collections/F.BN2HJCPOF5U7U/uploads/**", accessor="fs") Output: [ { @@ -218,4 +220,65 @@ } } +] + +# Set artifact tags +Query: SELECT artifact_set_metadata(name="Custom.Generic.Client.Info", tags=["OneTag"]) FROM scope() +Output: [ + { + "artifact_set_metadata(name=\"Custom.Generic.Client.Info\", tags=[\"OneTag\"])": { + "hidden": true, + "tags": [ + "OneTag" + ] + } + } +] + +Query: SELECT artifact_set_metadata(name="Custom.Generic.Client.Info", tags="OneTag") FROM scope() +Output: [ + { + "artifact_set_metadata(name=\"Custom.Generic.Client.Info\", tags=\"OneTag\")": { + "hidden": true, + "tags": [ + "OneTag" + ] + } + } +] + +# Single tag list +Query: SELECT artifact_set_metadata(name="Custom.Generic.Client.Info", tags=["OneTag",]) FROM scope() +Output: [ + { + "artifact_set_metadata(name=\"Custom.Generic.Client.Info\", tags=[\"OneTag\", ])": { + "hidden": true, + "tags": [ + "OneTag" + ] + } + } +] + +Query: SELECT artifact_set_metadata(name="Custom.Generic.Client.Info", tags=["OneTag", "TwoTags"]) FROM scope() +Output: [ + { + "artifact_set_metadata(name=\"Custom.Generic.Client.Info\", tags=[\"OneTag\", \"TwoTags\"])": { + "hidden": true, + "tags": [ + "OneTag", + "TwoTags" + ] + } + } +] + +# Clear the tags +Query: SELECT artifact_set_metadata(name="Custom.Generic.Client.Info", tags=[]) FROM scope() +Output: [ + { + "artifact_set_metadata(name=\"Custom.Generic.Client.Info\", tags=[])": { + "hidden": true + } + } ] diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/testdata/server/testcases/clients.in.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/testdata/server/testcases/clients.in.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/testdata/server/testcases/clients.in.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/testdata/server/testcases/clients.in.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -1,46 +1,61 @@ +Parameters: + ClientId: "C.123NewClient" + Queries: + # Create a new client + - LET client_record <= client_create( + first_seen_at="2020-10-01T10:11:23", + last_seen_at="2021-02-03T12:12:24", + labels=["Label1", "Label2"], + os="windows", + hostname="myHostname", + client_id=ClientId, + mac_addresses=["00:11:22", "22:33:44"]) + + # Check client exists + - SELECT *, client_record + FROM clients(client_id=client_record.client_id) + # Clear the labels from all clients. - - LET _ <= SELECT label(client_id=client_id, op='remove', labels=labels), client_id + - LET _ <= SELECT label(client_id=client_id, + op='remove', labels=labels), client_id FROM clients(search='label:*') ORDER BY client_id # Just get a list of all clients and their hostnames. - - SELECT os_info.fqdn as Hostname, client_id, last_seen_at / 1000000 as LastSeen - FROM clients() order by Hostname + - SELECT os_info.fqdn as Hostname, client_id, + last_seen_at / 1000000 as LastSeen + FROM clients() + WHERE Hostname =~ "myHostname" # Check that the clients plugin allows searching by indexes. - SELECT os_info.fqdn as Hostname, os_info.system as System, client_id - FROM clients(search='host:testcomputer') order by client_id + FROM clients(search='host:myHostname') order by client_id - - SELECT * from clients() order by client_id + # Schedule a flow on the client + - SELECT collect_client(client_id=ClientId, + artifacts="Windows.Network.Netstat") + FROM scope() + # Find the flow in the new client - SELECT client_id, timestamp(epoch=create_time/1000000) as CreateTime, request.artifacts as Artifacts, session_id as Flow - FROM flows(client_id='C.4f5e52adf0a337a9') + FROM flows(client_id=ClientId) WHERE Artifacts =~ "Netstat" # Test metadata setting and getting - metadata is additive. - - SELECT client_set_metadata(client_id='C.4f5e52adf0a337a9', + - SELECT client_set_metadata(client_id=ClientId, Foo='Bar', Bar='Baz', IntConvertedToString=5) FROM scope() - - SELECT client_metadata(client_id='C.4f5e52adf0a337a9') FROM scope() + - SELECT client_metadata(client_id=ClientId) FROM scope() # Metadata is additive - NULL removes - - SELECT client_set_metadata(client_id='C.4f5e52adf0a337a9', + - SELECT client_set_metadata(client_id=ClientId, AnotherItem="Hello", Bar=NULL) FROM scope() - - SELECT client_metadata(client_id='C.4f5e52adf0a337a9') FROM scope() - - # Creating clients - - LET client_record <= client_create( - first_seen_at="2020-10-01T10:11:23", - last_seen_at="2021-02-03T12:12:24", - labels=["Label1", "Label2"], - os="windows", - hostname="myHostname", - client_id="C.12345678", - mac_addresses=["00:11:22", "22:33:44"]) - - - SELECT *, client_record FROM clients(client_id=client_record.client_id) + - SELECT client_metadata(client_id=ClientId) FROM scope() # Remove the new client. - - SELECT * FROM client_delete(client_id=client_record.client_id, really_do_it=TRUE) + - SELECT * FROM client_delete( + client_id=client_record.client_id, really_do_it=TRUE) + GROUP BY 1 + - SELECT * FROM clients(client_id=client_record.client_id) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/testdata/server/testcases/clients.out.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/testdata/server/testcases/clients.out.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/testdata/server/testcases/clients.out.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/testdata/server/testcases/clients.out.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -1,109 +1,11 @@ -# Clear the labels from all clients. -Query: LET _ <= SELECT label(client_id=client_id, op='remove', labels=labels), client_id FROM clients(search='label:*') ORDER BY client_id -Output: [] - -# Just get a list of all clients and their hostnames. -Query: SELECT os_info.fqdn as Hostname, client_id, last_seen_at / 1000000 as LastSeen FROM clients() order by Hostname -Output: [ - { - "Hostname": "DESKTOP-BP4S7TF", - "client_id": "C.4f5e52adf0a337a9", - "LastSeen": 1638362977.493088 - } -] - -# Check that the clients plugin allows searching by indexes. -Query: SELECT os_info.fqdn as Hostname, os_info.system as System, client_id FROM clients(search='host:testcomputer') order by client_id -Output: [] - -Query: SELECT * from clients() order by client_id -Output: [ - { - "client_id": "C.4f5e52adf0a337a9", - "agent_information": { - "version": "2019-11-07T22:08:33+10:00", - "name": "velociraptor", - "build_time": "", - "build_url": "" - }, - "os_info": { - "system": "windows", - "hostname": "DESKTOP-BP4S7TF", - "release": "Microsoft Windows 10 Enterprise Evaluation10.0.18362 Build 18362", - "machine": "amd64", - "fqdn": "DESKTOP-BP4S7TF", - "mac_addresses": [] - }, - "first_seen_at": 0, - "last_seen_at": 1638362977493088, - "last_ip": "192.168.1.112:60239", - "last_interrogate_flow_id": "F.BN21C82J8DM8K", - "last_interrogate_artifact_name": "", - "labels": [], - "last_hunt_timestamp": 0, - "last_event_table_version": 0, - "last_label_timestamp": 0, - "in_flight_flows": {} - } -] - -Query: SELECT client_id, timestamp(epoch=create_time/1000000) as CreateTime, request.artifacts as Artifacts, session_id as Flow FROM flows(client_id='C.4f5e52adf0a337a9') WHERE Artifacts =~ "Netstat" -Output: [ - { - "client_id": "C.4f5e52adf0a337a9", - "CreateTime": "2023-11-28T12:43:36.907783031Z", - "Artifacts": [ - "Windows.Network.NetstatEnriched" - ], - "Flow": "F.BSJMEJIPT6P9I" - } -] - -# Test metadata setting and getting - metadata is additive. -Query: SELECT client_set_metadata(client_id='C.4f5e52adf0a337a9', Foo='Bar', Bar='Baz', IntConvertedToString=5) FROM scope() -Output: [ - { - "client_set_metadata(client_id='C.4f5e52adf0a337a9', Foo='Bar', Bar='Baz', IntConvertedToString=5)": true - } -] - -Query: SELECT client_metadata(client_id='C.4f5e52adf0a337a9') FROM scope() -Output: [ - { - "client_metadata(client_id='C.4f5e52adf0a337a9')": { - "Foo": "Bar", - "Bar": "Baz", - "IntConvertedToString": "5" - } - } -] - -# Metadata is additive - NULL removes -Query: SELECT client_set_metadata(client_id='C.4f5e52adf0a337a9', AnotherItem="Hello", Bar=NULL) FROM scope() -Output: [ - { - "client_set_metadata(client_id='C.4f5e52adf0a337a9', AnotherItem=\"Hello\", Bar=NULL)": true - } -] - -Query: SELECT client_metadata(client_id='C.4f5e52adf0a337a9') FROM scope() -Output: [ - { - "client_metadata(client_id='C.4f5e52adf0a337a9')": { - "Foo": "Bar", - "IntConvertedToString": "5", - "AnotherItem": "Hello" - } - } -] - -# Creating clients -Query: LET client_record <= client_create( first_seen_at="2020-10-01T10:11:23", last_seen_at="2021-02-03T12:12:24", labels=["Label1", "Label2"], os="windows", hostname="myHostname", client_id="C.12345678", mac_addresses=["00:11:22", "22:33:44"]) +# Create a new client +Query: LET client_record <= client_create( first_seen_at="2020-10-01T10:11:23", last_seen_at="2021-02-03T12:12:24", labels=["Label1", "Label2"], os="windows", hostname="myHostname", client_id=ClientId, mac_addresses=["00:11:22", "22:33:44"]) Output: [] +# Check client exists Query: SELECT *, client_record FROM clients(client_id=client_record.client_id) Output: [ { - "client_id": "C.12345678", + "client_id": "C.123NewClient", "agent_information": { "version": "", @@ -137,5 +39,5 @@ "in_flight_flows": {}, "client_record": { - "client_id": "C.12345678", + "client_id": "C.123NewClient", "hostname": "myHostname", "fqdn": "myHostname", @@ -172,8 +74,123 @@ ] -# Remove the new client. -Query: SELECT * FROM client_delete(client_id=client_record.client_id, really_do_it=TRUE) +# Clear the labels from all clients. +Query: LET _ <= SELECT label(client_id=client_id, op='remove', labels=labels), client_id FROM clients(search='label:*') ORDER BY client_id Output: [] +# Just get a list of all clients and their hostnames. +Query: SELECT os_info.fqdn as Hostname, client_id, last_seen_at / 1000000 as LastSeen FROM clients() WHERE Hostname =~ "myHostname" +Output: [ + { + "Hostname": "myHostname", + "client_id": "C.123NewClient", + "LastSeen": 1612354344 + } +] + +# Check that the clients plugin allows searching by indexes. +Query: SELECT os_info.fqdn as Hostname, os_info.system as System, client_id FROM clients(search='host:myHostname') order by client_id +Output: [ + { + "Hostname": "myHostname", + "System": "windows", + "client_id": "C.123NewClient" + } +] + +# Schedule a flow on the client +Query: SELECT collect_client(client_id=ClientId, artifacts="Windows.Network.Netstat") FROM scope() +Output: [ + { + "collect_client(client_id=ClientId, artifacts=\"Windows.Network.Netstat\")": { + "flow_id": "F.01", + "request": { + "creator": "VelociraptorServer", + "user_data": "", + "client_id": "C.123NewClient", + "flow_id": "", + "urgent": false, + "artifacts": [ + "Windows.Network.Netstat" + ], + "specs": [], + "cpu_limit": 0, + "iops_limit": 0, + "progress_timeout": 0, + "timeout": 0, + "max_rows": 0, + "max_logs": 0, + "max_upload_bytes": 0, + "trace_freq_sec": 0, + "allow_custom_overrides": false, + "log_batch_time": 0, + "compiled_collector_args": [], + "ops_per_second": 0 + } + } + } +] + +# Find the flow in the new client +Query: SELECT client_id, timestamp(epoch=create_time/1000000) as CreateTime, request.artifacts as Artifacts, session_id as Flow FROM flows(client_id=ClientId) WHERE Artifacts =~ "Netstat" +Output: [ + { + "client_id": "C.123NewClient", + "CreateTime": "2020-05-31T15:28:05Z", + "Artifacts": [ + "Windows.Network.Netstat" + ], + "Flow": "F.01" + } +] + +# Test metadata setting and getting - metadata is additive. +Query: SELECT client_set_metadata(client_id=ClientId, Foo='Bar', Bar='Baz', IntConvertedToString=5) FROM scope() +Output: [ + { + "client_set_metadata(client_id=ClientId, Foo='Bar', Bar='Baz', IntConvertedToString=5)": true + } +] + +Query: SELECT client_metadata(client_id=ClientId) FROM scope() +Output: [ + { + "client_metadata(client_id=ClientId)": { + "Foo": "Bar", + "Bar": "Baz", + "IntConvertedToString": "5" + } + } +] + +# Metadata is additive - NULL removes +Query: SELECT client_set_metadata(client_id=ClientId, AnotherItem="Hello", Bar=NULL) FROM scope() +Output: [ + { + "client_set_metadata(client_id=ClientId, AnotherItem=\"Hello\", Bar=NULL)": true + } +] + +Query: SELECT client_metadata(client_id=ClientId) FROM scope() +Output: [ + { + "client_metadata(client_id=ClientId)": { + "Foo": "Bar", + "IntConvertedToString": "5", + "AnotherItem": "Hello" + } + } +] + +# Remove the new client. +Query: SELECT * FROM client_delete( client_id=client_record.client_id, really_do_it=TRUE) GROUP BY 1 +Output: [ + { + "client_id": "C.123NewClient", + "type": "DeleteDirectory", + "vfs_path": "/clients/C.123NewClient/tasks", + "error": "client_delete: Removing directory /clients/C.123NewClient/tasks: DeleteSubject" + } +] + Query: SELECT * FROM clients(client_id=client_record.client_id) Output: [] diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/testdata/server/testcases/cobalt.out.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/testdata/server/testcases/cobalt.out.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/testdata/server/testcases/cobalt.out.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/testdata/server/testcases/cobalt.out.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -110,4 +110,5 @@ "Path": "data", "Size": 10000, + "UploadId": 0, "StoredSize": 10000, "sha256": "e4827601fe57d67ef030a3d3aa5b7d8d18e5bd51bbee5cd8ce58ce64986aeaba", @@ -118,6 +119,5 @@ "data", "cobalt_strike_beacon_0.bin" - ], - "UploadId": 0 + ] } }, @@ -155,4 +155,5 @@ "Path": "data", "Size": 10000, + "UploadId": 0, "StoredSize": 10000, "sha256": "f80f9893cf9d92f655df9a87841067a17e8296ab758a7b8aee6f3866bcd7ecf4", @@ -163,6 +164,5 @@ "data", "cobalt_strike_beacon_11001.bin" - ], - "UploadId": 0 + ] } } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/testdata/server/testcases/collections.in.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/testdata/server/testcases/collections.in.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/testdata/server/testcases/collections.in.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/testdata/server/testcases/collections.in.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -31,5 +31,5 @@ # Password is set in the scope so it can not leak in output - - LET ZIP_PASSWORDS = "hello" + - LET ZIP_PASSWORDS <= "hello" - SELECT read_file(filename=OSPath, accessor='collector') FROM glob(globs='**/BasicInformation.json', @@ -39,4 +39,29 @@ '/artifacts/testdata/files/encrypted_collector_password.zip')) + + # Clear the password now. + - LET ZIP_PASSWORDS <= "" + + # This file contains a complex filename with illegal characters. We + # escape those for the zip container. We must be able to read the + # file from the serialized version of the pathspec. + - | + SELECT read_file(filename=OSPath, accessor='zip'), + read_file(filename=OSPath.String, accessor='zip'), + OSPath.Components, OSPath.Path + FROM glob(globs='*', accessor='zip', + root=pathspec(Path='/uploads/file/tmp/', + DelegatePath=srcDir + '/vql/tools/collector/fixtures/import.zip')) + + # Same as above for the collector accessor. We must be able to read + # the file from the serialized version of the pathspec. + - | + SELECT read_file(filename=OSPath, accessor='collector'), + read_file(filename=OSPath.String, accessor='collector'), + OSPath.Components, OSPath.Path + FROM glob(globs='*', accessor='collector', + root=pathspec(Path='/uploads/file/tmp/', + DelegatePath=srcDir + '/vql/tools/collector/fixtures/import.zip')) + # Test we can pass definitions to the collect() plugin. This passes # a []string{} to artifact_definitions. diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/testdata/server/testcases/collections.out.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/testdata/server/testcases/collections.out.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/testdata/server/testcases/collections.out.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/testdata/server/testcases/collections.out.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -3,5 +3,5 @@ Output: [ { - "read_file(filename=OSPath, accessor='collector')": "{\"Name\":\"velociraptor\",\"BuildTime\":\"2022-10-12T16:14:40+10:00\",\"Version\":\"0.6.7-dev\",\"build_url\":\"\",\"Labels\":null,\"Hostname\":\"DESKTOP-SU8FH31\",\"OS\":\"windows\",\"Architecture\":\"amd64\",\"Platform\":\"Microsoft Windows 11 Enterprise Evaluation\",\"PlatformVersion\":\"10.0.22000 Build 22000\",\"KernelVersion\":\"10.0.22000 Build 22000\",\"Fqdn\":\"DESKTOP-SU8FH31.lan\",\"MACAddresses\":[\"00:0c:29:00:26:7e\"]}\n" + "read_file(filename=OSPath, accessor='collector')": "" } ] @@ -17,5 +17,5 @@ # Password is set in the scope so it can not leak in output -Query: LET ZIP_PASSWORDS = "hello" +Query: LET ZIP_PASSWORDS <= "hello" Output: [] @@ -26,4 +26,55 @@ } ] + +# Clear the password now. +Query: LET ZIP_PASSWORDS <= "" +Output: [] + +# This file contains a complex filename with illegal characters. We +# escape those for the zip container. We must be able to read the +# file from the serialized version of the pathspec. +Query: SELECT read_file(filename=OSPath, accessor='zip'), + read_file(filename=OSPath.String, accessor='zip'), + OSPath.Components, OSPath.Path +FROM glob(globs='*', accessor='zip', + root=pathspec(Path='/uploads/file/tmp/', + DelegatePath=srcDir + '/vql/tools/collector/fixtures/import.zip')) + +Output: [ + { + "read_file(filename=OSPath, accessor='zip')": "hello world\n", + "read_file(filename=OSPath.String, accessor='zip')": "hello world\n", + "OSPath.Components": [ + "uploads", + "file", + "tmp", + "ls%5Cwith%5Cback%3Aslash" + ], + "OSPath.Path": "/uploads/file/tmp/ls%5Cwith%5Cback%3Aslash" + } +] + +# Same as above for the collector accessor. We must be able to read +# the file from the serialized version of the pathspec. +Query: SELECT read_file(filename=OSPath, accessor='collector'), + read_file(filename=OSPath.String, accessor='collector'), + OSPath.Components, OSPath.Path +FROM glob(globs='*', accessor='collector', + root=pathspec(Path='/uploads/file/tmp/', + DelegatePath=srcDir + '/vql/tools/collector/fixtures/import.zip')) + +Output: [ + { + "read_file(filename=OSPath, accessor='collector')": "hello world\n", + "read_file(filename=OSPath.String, accessor='collector')": "hello world\n", + "OSPath.Components": [ + "uploads", + "file", + "tmp", + "ls\\with\\back:slash" + ], + "OSPath.Path": "/uploads/file/tmp/ls%5Cwith%5Cback%3Aslash" + } +] # Test we can pass definitions to the collect() plugin. This passes Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/testdata/server/testcases: import_artifacts.in.yaml Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/testdata/server/testcases: import_artifacts.out.yaml diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/testdata/server/testcases/kapefiles_extract.in.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/testdata/server/testcases/kapefiles_extract.in.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/testdata/server/testcases/kapefiles_extract.in.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/testdata/server/testcases/kapefiles_extract.in.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -10,5 +10,7 @@ # Should refuse to pad out very sparse files. - - SELECT * FROM test_read_logs() WHERE Log =~ "is too sparse - unable to expand it" AND NOT Log =~ "SELECT" + - | + SELECT Log =~ "Collection-WIN-E5K9RC5GU23-2021-11-21T18_05_56-08_00.zip" + FROM test_read_logs() WHERE Log =~ "is too sparse - unable to expand it" AND NOT Log =~ "SELECT" # On Windows we can adjust all the timestamps but only Linux on the diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/testdata/server/testcases/kapefiles_extract.out.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/testdata/server/testcases/kapefiles_extract.out.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/testdata/server/testcases/kapefiles_extract.out.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/testdata/server/testcases/kapefiles_extract.out.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -49,8 +49,10 @@ # Should refuse to pad out very sparse files. -Query: SELECT * FROM test_read_logs() WHERE Log =~ "is too sparse - unable to expand it" AND NOT Log =~ "SELECT" +Query: SELECT Log =~ "Collection-WIN-E5K9RC5GU23-2021-11-21T18_05_56-08_00.zip" +FROM test_read_logs() WHERE Log =~ "is too sparse - unable to expand it" AND NOT Log =~ "SELECT" + Output: [ { - "Log": "Velociraptor: Error: File /uploads/ntfs/%5C%5C.%5CC%3A/$Extend/$UsnJrnl%3A$J is too sparse - unable to expand it.\n" + "Log =~ \"Collection-WIN-E5K9RC5GU23-2021-11-21T18_05_56-08_00.zip\"": true } ] diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/testdata/server/testcases/netstat.out.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/testdata/server/testcases/netstat.out.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/testdata/server/testcases/netstat.out.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/testdata/server/testcases/netstat.out.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -48,5 +48,5 @@ "Inode": "14610" }, - "LocalAddr": "0.0.0.0", + "LocalAddr": "127.0.0.53", "LocalPort": 53, "RemoteAddr": "0.0.0.0", diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/testdata/server/testcases/orgs.in.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/testdata/server/testcases/orgs.in.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/testdata/server/testcases/orgs.in.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/testdata/server/testcases/orgs.in.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -72,4 +72,15 @@ - SELECT *, name+org_id AS Key FROM gui_users(all_orgs=TRUE) WHERE name =~ "OrgUser" ORDER BY Key +# Create some clients +- | + LET _ <= SELECT * FROM query(query={ + SELECT client_create(client_id="C.123") FROM scope() + }, org_id="ORGID") + +- | + LET _ <= SELECT * FROM query(query={ + SELECT client_create(client_id="C.123") FROM scope() + }, org_id="ORGID2") + # Launching collections on different orgs can be done using a number of ways. # 1. Use the query() plugin to run the query on another org. diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/testdata/server/testcases/orgs.out.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/testdata/server/testcases/orgs.out.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/testdata/server/testcases/orgs.out.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/testdata/server/testcases/orgs.out.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -438,4 +438,17 @@ ] +# Create some clients +Query: LET _ <= SELECT * FROM query(query={ + SELECT client_create(client_id="C.123") FROM scope() +}, org_id="ORGID") + +Output: [] + +Query: LET _ <= SELECT * FROM query(query={ + SELECT client_create(client_id="C.123") FROM scope() +}, org_id="ORGID2") + +Output: [] + # Launching collections on different orgs can be done using a number of ways. # 1. Use the query() plugin to run the query on another org. diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/testdata/server/testcases/util_sendmail.in.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/testdata/server/testcases/util_sendmail.in.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/testdata/server/testcases/util_sendmail.in.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/testdata/server/testcases/util_sendmail.in.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -64,5 +64,5 @@ # Create multipart with just attachments: - | - SELECT D(X=WrapInBoundary(Boundary=Boundary, + SELECT D(X=WrapInBoundary(Boundary=Boundary, Header="", Sections=AttachFiles(Files=[ dict(Path=tmp1, Filename='Attachment 1.txt'), @@ -71,5 +71,5 @@ # Create multipart with plain-text, HTML and attachments: - | - SELECT D(X=WrapInBoundary(Boundary=Boundary, + SELECT D(X=WrapInBoundary(Boundary=Boundary, Header="", Sections=(WrapAlternative(Plain=Plain, HTML=HTML),) + AttachFiles(Files=[ @@ -80,4 +80,4 @@ # Create multipart with no attachments (empty): - | - SELECT D(X=WrapInBoundary(Boundary=Boundary, + SELECT D(X=WrapInBoundary(Boundary=Boundary, Header="", Sections=(WrapAlternative(HTML=HTML),) + AttachFiles(Files=[]))) FROM scope() diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/testdata/server/testcases/util_sendmail.out.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/testdata/server/testcases/util_sendmail.out.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/artifacts/testdata/server/testcases/util_sendmail.out.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/testdata/server/testcases/util_sendmail.out.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -172,5 +172,5 @@ # Create multipart with just attachments: -Query: SELECT D(X=WrapInBoundary(Boundary=Boundary, +Query: SELECT D(X=WrapInBoundary(Boundary=Boundary, Header="", Sections=AttachFiles(Files=[ dict(Path=tmp1, Filename='Attachment 1.txt'), @@ -201,5 +201,5 @@ # Create multipart with plain-text, HTML and attachments: -Query: SELECT D(X=WrapInBoundary(Boundary=Boundary, +Query: SELECT D(X=WrapInBoundary(Boundary=Boundary, Header="", Sections=(WrapAlternative(Plain=Plain, HTML=HTML),) + AttachFiles(Files=[ @@ -244,10 +244,10 @@ # Create multipart with no attachments (empty): -Query: SELECT D(X=WrapInBoundary(Boundary=Boundary, +Query: SELECT D(X=WrapInBoundary(Boundary=Boundary, Header="", Sections=(WrapAlternative(HTML=HTML),) + AttachFiles(Files=[]))) FROM scope() Output: [ { - "D(X=WrapInBoundary(Boundary=Boundary, Sections=(WrapAlternative(HTML=HTML), ) + AttachFiles(Files=[])))": [ + "D(X=WrapInBoundary(Boundary=Boundary, Header=\"\", Sections=(WrapAlternative(HTML=HTML), ) + AttachFiles(Files=[])))": [ "--BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB", "Content-Type: multipart/alternative; boundary=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/testdata/server/testcases: yarax.in.yaml Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/artifacts/testdata/server/testcases: yarax.out.yaml diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/bin/artifacts.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/bin/artifacts.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/bin/artifacts.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/bin/artifacts.go 2025-11-01 15:52:20.000000000 +0000 @@ -246,6 +246,6 @@ Logger: logging.GetLogger( config_obj, &logging.ToolComponent), - OnExit: sm.Close, } + Nanny.RegisterOnWarnings(utils.GetId(), sm.Close) // Keep the nanny running after the query is done so it can diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/bin/banner.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/bin/banner.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/bin/banner.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/bin/banner.go 2025-11-01 15:52:20.000000000 +0000 @@ -30,5 +30,5 @@ for _, line := range strings.Split(banner, "\n") { if len(line) > 0 { - logging.Prelog(line) + logging.Prelog("%s", line) } } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/bin/config_merge.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/bin/config_merge.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/bin/config_merge.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/bin/config_merge.go 2025-11-01 15:52:20.000000000 +0000 @@ -3,11 +3,12 @@ import ( "fmt" - "io/ioutil" "os" jsonpatch "github.com/evanphx/json-patch/v5" config_proto "www.velocidex.com/golang/velociraptor/config/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/utils" ) @@ -92,5 +93,5 @@ result := make([][]byte, 0) if merge_file != nil { - data, err := ioutil.ReadAll(merge_file) + data, err := utils.ReadAllWithLimit(merge_file, constants.MAX_MEMORY) if err != nil { return nil, err @@ -109,5 +110,5 @@ result := make([]jsonpatch.Patch, 0) if patch_file != nil { - data, err := ioutil.ReadAll(patch_file) + data, err := utils.ReadAllWithLimit(patch_file, constants.MAX_MEMORY) if err != nil { return nil, fmt.Errorf("Reading patch file: %w", err) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/bin/fs.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/bin/fs.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/bin/fs.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/bin/fs.go 2025-11-01 15:52:20.000000000 +0000 @@ -366,5 +366,5 @@ logging.DisableLogging() - _, err := APIConfigLoader. + config_obj, err := APIConfigLoader. WithNullLoader().LoadAndValidate() if err != nil { @@ -378,5 +378,29 @@ } - scope := vql_subsystem.MakeScope() + ctx, cancel := install_sig_handler() + defer cancel() + + config_obj.Services = services.GenericToolServices() + sm, err := startup.StartToolServices(ctx, config_obj) + defer sm.Close() + + if err != nil { + return err + } + + logger := &LogWriter{config_obj: config_obj} + builder := services.ScopeBuilder{ + Config: config_obj, + ACLManager: acl_managers.NullACLManager{}, + Logger: log.New(logger, "", 0), + } + + manager, err := services.GetRepositoryManager(config_obj) + if err != nil { + return err + } + scope := manager.BuildScope(builder) + defer scope.Close() + accessor, err := accessors.GetAccessor(accessor_name, scope) if err != nil { @@ -456,22 +480,22 @@ case fs_command_ls.FullCommand(): err := doLS(*fs_command_ls_path, *fs_command_accessor) - kingpin.FatalIfError(err, fs_command_ls.FullCommand()) + kingpin.FatalIfError(err, "%s", fs_command_ls.FullCommand()) case fs_command_rm.FullCommand(): err := doRM(*fs_command_rm_path, *fs_command_accessor) - kingpin.FatalIfError(err, fs_command_rm.FullCommand()) + kingpin.FatalIfError(err, "%s", fs_command_rm.FullCommand()) case fs_command_cp.FullCommand(): err := doCp(*fs_command_cp_path, *fs_command_accessor, *fs_command_cp_outdir) - kingpin.FatalIfError(err, fs_command_cp.FullCommand()) + kingpin.FatalIfError(err, "%s", fs_command_cp.FullCommand()) case fs_command_cat.FullCommand(): err := doCat(*fs_command_cat_path, *fs_command_accessor) - kingpin.FatalIfError(err, fs_command_cat.FullCommand()) + kingpin.FatalIfError(err, "%s", fs_command_cat.FullCommand()) case fs_command_zcat.FullCommand(): err := doZCat(*fs_command_zcat_chunk_path, *fs_command_zcat_file_path) - kingpin.FatalIfError(err, fs_command_zcat.FullCommand()) + kingpin.FatalIfError(err, "%s", fs_command_zcat.FullCommand()) default: diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/bin/fuse_unix.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/bin/fuse_unix.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/bin/fuse_unix.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/bin/fuse_unix.go 2025-11-01 15:52:20.000000000 +0000 @@ -28,21 +28,26 @@ Required().String() - fuse_zip_accessor = fuse_command.Flag("accessor", "The accessor to use (default container)"). + fuse_zip_accessor = fuse_command.Flag("accessor", "The accessor to use (default collector)"). Default("collector").String() - fuse_zip_prefix = fuse_command.Flag("prefix", "Export all files below this directory in the zip file"). - Default("/").String() + fuse_zip_prefix = fuse_command.Flag("prefix", + "Export all files below this directory in the zip file"). + Default("/").String() fuse_files = fuse_zip_command.Arg("files", "list of zip files to mount"). Required().Strings() - fuse_options_map_device_names_to_letters = fuse_zip_command.Flag("map_device_names_to_letters", "Convert raw device names to drive letters"). - Bool() - fuse_options_strip_colons_on_drive_letters = fuse_zip_command.Flag("strip_colons_on_drive_letters", "Remove the : on drive letters"). - Bool() - fuse_options_unix_path_escaping = fuse_zip_command.Flag("unix_path_escaping", "If set we escape only few characters in file names otherwise escape windows compatible chars"). - Bool() - fuse_options_emulate_timestamps = fuse_zip_command.Flag("emulate_timestamps", "If set emulate timestamps for common artifacts like Windows.KapeFiles.Targets."). - Bool() + fuse_options_map_device_names_to_letters = fuse_zip_command.Flag( + "map_device_names_to_letters", "Convert raw device names to drive letters"). + Bool() + fuse_options_strip_colons_on_drive_letters = fuse_zip_command.Flag( + "strip_colons_on_drive_letters", "Remove the : on drive letters"). + Bool() + fuse_options_unix_path_escaping = fuse_zip_command.Flag("unix_path_escaping", + "If set we escape only few characters in file names otherwise escape windows compatible chars"). + Bool() + fuse_options_emulate_timestamps = fuse_zip_command.Flag("emulate_timestamps", + "If set emulate timestamps for common artifacts like Windows.Triage.Targets."). + Bool() ) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/bin/gui.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/bin/gui.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/bin/gui.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/bin/gui.go 2025-11-01 15:52:20.000000000 +0000 @@ -155,5 +155,8 @@ fd.Close() - return config_obj, nil + // Re-read the config from the file we just made. + return makeDefaultConfigLoader(). + WithVerbose(true). + WithFileLoader(server_config_path).LoadAndValidate() } @@ -200,6 +203,6 @@ // to just be able to use the notebook and build an // offline collector. - logging.Prelog("No valid config found - " + - "will generate a new one at " + server_config_path) + logging.Prelog("No valid config found - "+ + "will generate a new one at %s ", server_config_path) config_obj, err = generateGUIConfig( diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/bin/marshal.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/bin/marshal.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/bin/marshal.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/bin/marshal.go 2025-11-01 15:52:20.000000000 +0000 @@ -2,9 +2,10 @@ import ( - "io/ioutil" "os" errors "github.com/go-errors/errors" + "www.velocidex.com/golang/velociraptor/constants" "www.velocidex.com/golang/velociraptor/json" + "www.velocidex.com/golang/velociraptor/utils" "www.velocidex.com/golang/velociraptor/vql/tools" "www.velocidex.com/golang/vfilter" @@ -28,5 +29,5 @@ defer fd.Close() - data, err := ioutil.ReadAll(fd) + data, err := utils.ReadAllWithLimit(fd, constants.MAX_MEMORY) if err != nil { return nil, err diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/bin/offline.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/bin/offline.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/bin/offline.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/bin/offline.go 2025-11-01 15:52:20.000000000 +0000 @@ -32,8 +32,9 @@ # The list of artifacts and their args. Artifacts: - Windows.KapeFiles.Targets: - EventLogs: Y + Windows.Triage.Targets: + HighLevelTargets: '["_SANS_Triage", "_KapeTriage"]' + Devices: '["C:","D:","E:"]' Windows.Sysinternals.Autoruns: - All: Y + All: Y # Can be ZIP, GCS, S3, Azure, SMBShare, SFTP @@ -154,6 +155,6 @@ // the `gui` command makes. You can keep this datastore around // for the next collector. - Prelog("No valid config found - " + - "will generate a new one at " + server_config_path) + Prelog("No valid config found - "+ + "will generate a new one at %s", server_config_path) config_obj, err = generateGUIConfig( @@ -188,5 +189,5 @@ } - logger := &StdoutLogWriter{} + logger := &LogWriter{config_obj: config_obj} builder := services.ScopeBuilder{ Config: sm.Config, @@ -204,7 +205,11 @@ query := ` LET _ <= SELECT name FROM artifact_definitions() -LET Spec <= parse_yaml(filename=SPECFILE) +LET _ <= import(artifact="Server.Utils.CreateCollector") + +LET Spec <= parse_yaml(filename=SPECFILE, schema=SpecSchema) LET _K = SELECT _key FROM items(item=Spec.Artifacts) -SELECT * FROM Artifact.Server.Utils.CreateCollector( + +SELECT * FROM if(condition=Spec.OS, then={ + SELECT * FROM Artifact.Server.Utils.CreateCollector( OS=Spec.OS, artifacts=serialize(item=_K._key), @@ -231,6 +236,12 @@ opt_delete_at_exit=Spec.OptDeleteAtExit ) +}) ` - return runQueryWithEnv(query, builder, "json") + err = runQueryWithEnv(query, builder, "json") + if err != nil { + return err + } + + return logger.Error } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/bin/panic.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/bin/panic.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/bin/panic.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/bin/panic.go 2025-11-01 15:52:20.000000000 +0000 @@ -66,4 +66,4 @@ func FatalIfError(command *kingpin.CmdClause, cb func() error) { err := cb() - kingpin.FatalIfError(err, command.FullCommand()) + kingpin.FatalIfError(err, "%s", command.FullCommand()) } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/bin/query.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/bin/query.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/bin/query.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/bin/query.go 2025-11-01 15:52:20.000000000 +0000 @@ -22,5 +22,4 @@ "fmt" "io" - "io/ioutil" "log" "os" @@ -214,5 +213,5 @@ if response.Log != "" { - logger.Info(response.Log) + logger.Info("%s", response.Log) continue } @@ -302,5 +301,5 @@ return fmt.Errorf("While opening query file %v: %w", q, err) } - data, err := ioutil.ReadAll(fd) + data, err := utils.ReadAllWithLimit(fd, constants.MAX_MEMORY) if err != nil { return fmt.Errorf("While opening query file %v: %w", q, err) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/bin/reformat.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/bin/reformat.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/bin/reformat.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/bin/reformat.go 2025-11-01 15:52:20.000000000 +0000 @@ -3,11 +3,12 @@ import ( "fmt" - "io/ioutil" "os" "www.velocidex.com/golang/velociraptor/config" + "www.velocidex.com/golang/velociraptor/constants" 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" ) @@ -57,5 +58,5 @@ } - data, err := ioutil.ReadAll(fd) + data, err := utils.ReadAllWithLimit(fd, constants.MAX_MEMORY) if err != nil { returned_errs[artifact_path] = err diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/bin/repack.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/bin/repack.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/bin/repack.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/bin/repack.go 2025-11-01 15:52:20.000000000 +0000 @@ -22,5 +22,4 @@ import ( - "io/ioutil" "log" "os" @@ -30,8 +29,10 @@ errors "github.com/go-errors/errors" config_proto "www.velocidex.com/golang/velociraptor/config/proto" + "www.velocidex.com/golang/velociraptor/constants" logging "www.velocidex.com/golang/velociraptor/logging" "www.velocidex.com/golang/velociraptor/services" "www.velocidex.com/golang/velociraptor/startup" "www.velocidex.com/golang/velociraptor/uploads" + "www.velocidex.com/golang/velociraptor/utils" "www.velocidex.com/golang/velociraptor/vql/acl_managers" "www.velocidex.com/golang/vfilter" @@ -87,5 +88,6 @@ // Read the config file - config_data, err := ioutil.ReadAll(*repack_command_config) + config_data, err := utils.ReadAllWithLimit(*repack_command_config, + constants.MAX_MEMORY) if err != nil { return err Binary files /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/bin/rsrc_windows_386.syso and /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/bin/rsrc_windows_386.syso differ Binary files /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/bin/rsrc_windows_amd64.syso and /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/bin/rsrc_windows_amd64.syso differ diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/bin/verify.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/bin/verify.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/bin/verify.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/bin/verify.go 2025-11-01 15:52:20.000000000 +0000 @@ -3,12 +3,13 @@ import ( "fmt" - "io/ioutil" "os" artifacts_proto "www.velocidex.com/golang/velociraptor/artifacts/proto" + "www.velocidex.com/golang/velociraptor/constants" logging "www.velocidex.com/golang/velociraptor/logging" "www.velocidex.com/golang/velociraptor/services" "www.velocidex.com/golang/velociraptor/services/launcher" "www.velocidex.com/golang/velociraptor/startup" + "www.velocidex.com/golang/velociraptor/utils" ) @@ -66,5 +67,5 @@ } - data, err := ioutil.ReadAll(fd) + data, err := utils.ReadAllWithLimit(fd, constants.MAX_MEMORY) if err != nil { state.SetError(err) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/bin/vql.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/bin/vql.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/bin/vql.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/bin/vql.go 2025-11-01 15:52:20.000000000 +0000 @@ -20,5 +20,4 @@ import ( "fmt" - "io/ioutil" "regexp" "sort" @@ -29,4 +28,5 @@ api_proto "www.velocidex.com/golang/velociraptor/api/proto" "www.velocidex.com/golang/velociraptor/config" + "www.velocidex.com/golang/velociraptor/constants" logging "www.velocidex.com/golang/velociraptor/logging" "www.velocidex.com/golang/velociraptor/utils" @@ -282,5 +282,6 @@ old_data := []*api_proto.Completion{} if vql_info_export_old_file != nil { - data, err := ioutil.ReadAll(*vql_info_export_old_file) + data, err := utils.ReadAllWithLimit(*vql_info_export_old_file, + constants.MAX_MEMORY) if err == nil { err = yaml.Unmarshal(data, &old_data) Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/config: ab0x.go diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/config/config.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/config/config.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/config/config.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/config/config.go 2025-11-01 15:52:20.000000000 +0000 @@ -25,4 +25,5 @@ config_proto "www.velocidex.com/golang/velociraptor/config/proto" constants "www.velocidex.com/golang/velociraptor/constants" + "www.velocidex.com/golang/velociraptor/utils" ) @@ -49,5 +50,5 @@ Compiler: runtime.Version(), System: runtime.GOOS, - Architecture: runtime.GOARCH, + Architecture: utils.GetArch(), } } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/config/embedded.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/config/embedded.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/config/embedded.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/config/embedded.go 2025-11-01 15:52:20.000000000 +0000 @@ -5,9 +5,9 @@ "compress/zlib" "io" - "io/ioutil" "os" "github.com/Velocidex/yaml/v2" config_proto "www.velocidex.com/golang/velociraptor/config/proto" + "www.velocidex.com/golang/velociraptor/utils" ) @@ -26,5 +26,5 @@ // will be ignored at this stage (thay can be extracted with the // 'me' accessor). - buf, err := ioutil.ReadAll(io.LimitReader(fd, 10*1024*1024)) + buf, err := utils.ReadAllWithLimit(fd, 10*1024*1024) if err != nil { return nil, err diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/constants/constants.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/constants/constants.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/constants/constants.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/constants/constants.go 2025-11-01 15:52:20.000000000 +0000 @@ -24,5 +24,5 @@ const ( - VERSION = "0.75.1-rc1" + VERSION = "0.75.4" // This is the version of dependent client binaries that will be @@ -99,4 +99,8 @@ REG_CACHE_TIME = "REG_CACHE_TIME" + // Maximum size of files to hash + HASH_MAX_SIZE = "HASH_MAX_SIZE" + BUFFER_MAX_SIZE = "BUFFER_MAX_SIZE" + RAW_REG_CACHE_SIZE = "RAW_REG_CACHE_SIZE" RAW_REG_CACHE_TIME = "RAW_REG_CACHE_TIME" @@ -124,4 +128,7 @@ S3_CREDENTIALS = "S3_CREDENTIALS" + // Used by the overlay accessor to configure delegates' + OVERLAY_ACCESSOR_DELEGATES = "OVERLAY_ACCESSOR_DELEGATES" + // VQL tries to balance memory/cpu tradeoffs and also place limits // on memory use. These parameters control this behavior. You can @@ -161,4 +168,9 @@ TZ = "TZ" + // Log levels for the Yara plugin: + // 1: Log ranges + // 2: Log Bytes scanned with 30 second deduplicated logs + YARA_LOG_LEVEL = "YARA_LOG_LEVEL" + PinnedServerName = "VelociraptorServer" Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/crypto: ab0x.go diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/datastore/filebased.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/datastore/filebased.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/datastore/filebased.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/datastore/filebased.go 2025-11-01 15:52:20.000000000 +0000 @@ -35,6 +35,4 @@ import ( "fmt" - "io" - "io/ioutil" "os" "path/filepath" @@ -87,5 +85,5 @@ if err != nil { return fmt.Errorf("While opening %v: %w", urn.AsClientPath(), - os.ErrNotExist) + utils.NotFoundError) } @@ -95,5 +93,6 @@ // usually this is because the disk was full. if urn.Type() == api.PATH_TYPE_DATASTORE_JSON { - return invalidFileError + return fmt.Errorf("While accessing %v: %w", + urn.AsClientPath(), invalidFileError) } return nil @@ -109,5 +108,5 @@ if err != nil { return fmt.Errorf("While opening %v: %w", - urn.AsClientPath(), os.ErrNotExist) + urn.AsClientPath(), utils.NotFoundError) } return nil @@ -358,6 +357,5 @@ defer file.Close() - result, err := ioutil.ReadAll( - io.LimitReader(file, constants.MAX_MEMORY)) + result, err := utils.ReadAllWithLimit(file, constants.MAX_MEMORY) if err != nil { return nil, errors.Wrap(err, 0) @@ -378,6 +376,5 @@ defer file.Close() - result, err := ioutil.ReadAll( - io.LimitReader(file, constants.MAX_MEMORY)) + result, err := utils.ReadAllWithLimit(file, constants.MAX_MEMORY) if err != nil { return nil, errors.Wrap(err, 0) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/datastore/filebased_supported.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/datastore/filebased_supported.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/datastore/filebased_supported.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/datastore/filebased_supported.go 2025-11-01 15:52:20.000000000 +0000 @@ -7,11 +7,48 @@ "context" "sync" + "sync/atomic" "time" + "github.com/Velocidex/ordereddict" config_proto "www.velocidex.com/golang/velociraptor/config/proto" "www.velocidex.com/golang/velociraptor/logging" + vql_subsystem "www.velocidex.com/golang/velociraptor/vql" "www.velocidex.com/golang/velociraptor/vql/psutils" + "www.velocidex.com/golang/vfilter" + "www.velocidex.com/golang/vfilter/types" ) +var ( + disabledWrites int64 = -1 +) + +func isDisabled(config_obj *config_proto.Config) bool { + // Only peresent in debug mode + if config_obj.DebugMode && + atomic.LoadInt64(&disabledWrites) < 0 { + + atomic.StoreInt64(&disabledWrites, 0) + + vql_subsystem.RegisterFunction( + vfilter.GenericFunction{ + FunctionName: "disable_writes", + Metadata: vql_subsystem.VQLMetadata().Build(), + Function: func( + ctx context.Context, + scope vfilter.Scope, + args *ordereddict.Dict) types.Any { + ok, _ := args.GetBool("clear") + if ok { + atomic.StoreInt64(&disabledWrites, 0) + } else { + atomic.StoreInt64(&disabledWrites, 1) + } + return true + }}) + } + + return atomic.LoadInt64(&disabledWrites) > 0 +} + func AvailableDiskSpace( db DataStore, config_obj *config_proto.Config) (uint64, error) { @@ -22,5 +59,6 @@ } - min_allowed_file_space_mb := uint64(config_obj.Datastore.MinAllowedFileSpaceMb) + min_allowed_file_space_mb := uint64( + config_obj.Datastore.MinAllowedFileSpaceMb) if min_allowed_file_space_mb == 0 { // We need at least 50mb by default. @@ -34,5 +72,6 @@ // If we have insufficient disk space, set the filestore to // stop writing. - if free_mb < min_allowed_file_space_mb { + if isDisabled(config_obj) || + free_mb < min_allowed_file_space_mb { logger := logging.GetLogger(config_obj, &logging.FrontendComponent) logger.Error("FileBaseDataStore: Insufficient free disk space! We need at least %v Mb but we have %v!. Disabling write operations to avoid file corruption. Free some disk space or grow the partition.", diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/datastore/memcache.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/datastore/memcache.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/datastore/memcache.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/datastore/memcache.go 2025-11-01 15:52:20.000000000 +0000 @@ -5,5 +5,4 @@ "errors" "fmt" - "os" "sort" "strings" @@ -383,5 +382,6 @@ if err != nil { return fmt.Errorf( - "While opening %v: %w", urn.AsClientPath(), os.ErrNotExist) + "While opening %v: %w", urn.AsClientPath(), + utils.NotFoundError) } } @@ -412,5 +412,5 @@ if err != nil { return fmt.Errorf("While decoding %v: %w", - urn.AsClientPath(), os.ErrNotExist) + urn.AsClientPath(), utils.NotFoundError) } return nil diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/datastore/remote.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/datastore/remote.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/datastore/remote.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/datastore/remote.go 2025-11-01 15:52:20.000000000 +0000 @@ -416,4 +416,5 @@ g_impl = nil remote_mu.Unlock() + } else if implementation == "FileBaseDataStore" { return startFullDiskChecker(ctx, wg, config_obj) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/docs/references/sample_config/main.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/docs/references/sample_config/main.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/docs/references/sample_config/main.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/docs/references/sample_config/main.go 2025-11-01 15:52:20.000000000 +0000 @@ -3,5 +3,4 @@ import ( "fmt" - "io/ioutil" "os" "reflect" @@ -14,4 +13,6 @@ kingpin "gopkg.in/alecthomas/kingpin.v2" config_proto "www.velocidex.com/golang/velociraptor/config/proto" + "www.velocidex.com/golang/velociraptor/constants" + "www.velocidex.com/golang/velociraptor/utils" ) @@ -79,4 +80,15 @@ "Datastore.remote_datastore_rpc_deadline", + // Deprecated fields that were moved to security: + "defaults.inflight_check_time", + "defaults.allowed_plugins", + "defaults.allowed_functions", + "defaults.allowed_accessors", + "defaults.denied_plugins", + "defaults.denied_functions", + "defaults.denied_accessors", + "defaults.lockdown_denied_permissions", + "defaults.certificate_validity_days", + // Fields that are already handled but their default value is // false or 0. @@ -121,4 +133,7 @@ "defaults.disable_active_inflight_checks", "defaults.write_internal_events", + "security.secrets_dek", + "security.vql_must_use_secrets", + "security.disable_inventory_service_external_access", } ) @@ -252,5 +267,5 @@ } - serialized, err := ioutil.ReadAll(fd) + serialized, err := utils.ReadAllWithLimit(fd, constants.MAX_MEMORY) if err != nil { return err diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/docs/references/server.config.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/docs/references/server.config.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/docs/references/server.config.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/docs/references/server.config.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -1160,5 +1160,5 @@ # this hash against their fetch file to ensure it was # correctly transferred. - hash: 1234 + expected_hash: 1234 # If set on a request we refresh the hash. @@ -1346,26 +1346,4 @@ max_in_memory_group_by: 30000 - # If these are set we enforce VQL to only have the specified allowed - # VQL plugins and functions. This is a way to harden the server by - # removing potentially sensitive functionality to allow only - # approved VQL plugins to run. - allowed_plugins: - - glob - allowed_functions: - - dict - allowed_accessors: - - auto - - # Alternatively, it might be easier to deny specific plugins and - # functions and accessors. - denied_plugins: - - execve - - denied_functions: - - rm - - denied_accessors: - - s3 - # How long to cache ACL policies (default 60 sec) acl_lru_timeout_sec: 60 @@ -1375,23 +1353,4 @@ unauthenticated_lru_timeout_sec: 10 - # Normally the inventory service attempts to download tools in - # its own but if this is set, we prevent any external access. - disable_inventory_service_external_access: false - - # Default expiry of certificate issuance (default 365 days). This - # will apply for e.g. rotating certificates or issuing an api cert. - certificate_validity_days: 365 - - # When the server is in lockdown mode the following permissions - # will be denied (Even for administrators). - lockdown_denied_permissions: - - ARTIFACT_WRITER - - SERVER_ARTIFACT_WRITER - - EXECVE - - SERVER_ADMIN - - FILESYSTEM_WRITE - - FILESYSTEM_READ - - MACHINE_STATE - # Controls how exports work (creating hunt or collection exports to a # zip file). On slow filesystems, increase the number of worker @@ -1512,2 +1471,89 @@ # minions to take over notebook calculations most of he time. notebook_worker_priority: 10 + +security: + # A list of path prefixes allowed for the 'file' accessor. If + # this is empty the file accessor will work on all + # directories. If you want to disable access to the server's + # filesystem you can set this to a non existent directory, + # e.g. /nonexistent/ . + allowed_file_accessor_prefix: + - /tmp/ + + # A list of prefixes allowed for the fs accessor. All other + # prefixes will be rejected. + allowed_fs_accessor_prefix: + - artifact_definitions + - clients + - downloads + - notebooks + - public + - temp + - server_artifacts + - server_artifacts_logs + + + # If these are set we enforce VQL to only have the specified allowed + # VQL plugins and functions. This is a way to harden the server by + # removing potentially sensitive functionality to allow only + # approved VQL plugins to run. + allowed_plugins: + - glob + allowed_functions: + - dict + allowed_accessors: + - auto + + # Alternatively, it might be easier to deny specific plugins and + # functions and accessors. + denied_plugins: + - execve + + denied_functions: + - rm + + denied_accessors: + - s3 + + # When the server is in lockdown mode the following permissions + # will be denied (Even for administrators). + lockdown_denied_permissions: + - ARTIFACT_WRITER + - SERVER_ARTIFACT_WRITER + - EXECVE + - SERVER_ADMIN + - FILESYSTEM_WRITE + - FILESYSTEM_READ + - MACHINE_STATE + + # Default expiry of certificate issuance (default 365 days). This + # will apply for e.g. rotating certificates or issuing an api cert. + certificate_validity_days: 365 + + # Normally the inventory service attempts to download tools in + # its own but if this is set, we prevent any external access. + disable_inventory_service_external_access: false + + # The Data Encryptions Key to use for protecting the secrets in + # storage. This can take a number of forms: + + # 1. If it starts with "env://" the secret will be taken from an + # Environment variable. + # 2. If empty the secret is taken from obfuscation_nonce (which + # by default is the hash of the private key). + # + # In future further methods may be implemented (e.g. EKMS). + secrets_dek: "" + + # This controls VQL plugins that may accept secrets as well full + # parameters. If this flag is set, those plugins will refuse to + # accept direct parameters, instead only accepting a secret + # name. This allows the admin to control exactly how these + # plugins work without disabling them completely. + vql_must_use_secrets: false + + # Prevent VQL from having access to these environment + # variables. Environment Vars sometimes may contain secrets and + # confidential information. + shadowed_env_vars: + - VELOCIRAPTOR_CONFIG diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/docs/references/vql.yaml /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/docs/references/vql.yaml --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/docs/references/vql.yaml 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/docs/references/vql.yaml 2025-11-01 15:52:20.000000000 +0000 @@ -748,4 +748,28 @@ - windows_386_cgo - windows_amd64_cgo +- name: cat + description: |- + Read files in chunks. + + This is mostly useful for character devices on Linux or special files which can not be read in blocks. + type: Plugin + args: + - name: filename + type: accessors.OSPath + description: File to open. + required: true + - name: accessor + type: string + description: An accessor to use. + - name: chunk + type: int + description: length of each chunk to read from the file. + - name: timeout + type: int + description: If specified we abort reading after this much time. + metadata: + permissions: FILESYSTEM_READ + platforms: + - linux_amd64_cgo - name: certificates description: | @@ -1383,8 +1407,22 @@ - name: compress description: | - Compress a file. + Compress a file using GZip. The file is compressed using gzip. You can change the location of the output using the output parameter. + + Note that output is a required parameter - you can consult how + paths are handled in Velociraptor to correctly manipulate paths + + https://docs.velociraptor.app/docs/forensic/filesystem/paths/ + + ## Example + + ```vql + SELECT OSPath, compress(path=OSPath, output=OSPath.Dirname + ( OSPath.Basename + ".gz")) AS Compressed + FROM glob(globs="C:/Windows/*.exe") + ``` + + Unlike the common `gzip` utility the file is not removed after compression. type: Function args: @@ -1396,4 +1434,5 @@ type: string description: A path to write the output - default is the path with a .gz extension + required: true category: encode metadata: @@ -3513,5 +3552,5 @@ This function calculates the MD5, SHA1 and SHA256 hashes of the file. type: Function - version: 2 + version: 3 args: - name: path @@ -3526,4 +3565,7 @@ description: The hash function to use (MD5,SHA1,SHA256) repeated: true + - name: max_size + type: uint64 + description: The maximum size of the file that will be hashed (default 100mb) category: encode metadata: @@ -5833,4 +5875,15 @@ - windows_386_cgo - windows_amd64_cgo +- name: notebooks + description: List all notebooks + type: Plugin + args: + - name: all + type: bool + description: List all notebooks, not just the ones shared with the user + metadata: + permissions: SERVER_ADMIN,READ_RESULTS + platforms: + - linux_amd64_cgo - name: now description: | @@ -6032,4 +6085,41 @@ - windows_386_cgo - windows_amd64_cgo +- name: overlay + description: | + Merges several paths into a single path. + + This accessor allows an overlay of several other paths as possible + prefixes. For example consider the following base paths: + + - /bin/ + - /usr/bin/ + + Then when attempting to open the file "ls", this accessor first + searches for it in in /bin/ls, then /usr/bin/ls. + + The search paths are selected using a scope variable: + + ```vql + LET OVERLAY_ACCESSOR_DELEGATES <= dict( + accessor="file", + paths=["/bin", "/usr/bin"]) + + SELECT * FROM glob(globs='*', accessor="overlay") + ``` + + type: Accessor + args: + - name: paths + type: accessors.OSPath + description: A list of paths to try to resolve each path. + repeated: true + required: true + - name: accessor + type: string + description: File accessor + metadata: + ScopeVar: OVERLAY_ACCESSOR_DELEGATES + platforms: + - linux_amd64_cgo - name: panic description: Crash the program with a panic! @@ -6408,5 +6498,17 @@ those fields that do not exist. Thus there is no error in actually accessing missing fields, the column will just return nil. + + ## Validating against a JSON schema. + + A JSON schema allows us to define a required structure on the JSON + object and reject it if it does not validate. See + https://json-schema.org/docs for an introduction to JSON schemas. + + If the JSON object does not validate the provided schema, several + log messages will be emitted at level ERROR and an empty object + returned. This would normally cause the artifact collection to + fail. type: Function + version: 2 args: - name: data @@ -6414,4 +6516,8 @@ description: Json encoded string. required: true + - name: schema + type: string + description: Json schema to use for validation. + repeated: true category: parsers platforms: @@ -6433,4 +6539,8 @@ description: Json encoded string. required: true + - name: schema + type: string + description: Json schema to use for validation. + repeated: true category: parsers platforms: @@ -6448,4 +6558,8 @@ description: Json encoded string. required: true + - name: schema + type: string + description: Json schema to use for validation. + repeated: true category: parsers platforms: @@ -6721,5 +6835,71 @@ - windows_amd64_cgo - name: parse_pe - description: Parse a PE file. + description: | + Parse a PE file. + + This function parses a PE file from disk or memory to extract the + different aspects of the PE file. The fields include: + + - FileHeader: The basic PE file header information. + - Directories: The different directories in the PE file (For + example Export_Directory, IAT_Directory etc). + - VersionInformation: The VersionInformation field contains + metadata about the binary. + - Imports: Parses the Import table of the PE file. + - Exports: Parses the export table of the PE file. + - Forward: Any linker forward to other DLLs. + - Authenticode: Calculates the Authenticode hash of the PE file + and also check if it is trusted. + + The result of `parse_pe()` is a lazily evaluated dict. This means + that only as fields are accessed the relevant data is + calculated. This allows callers to be selective in what fields + they get. + + For example, the `Authenticode` and `AuthenticodeHash` fields are + usually fairly expensive to calculate (as they need to hash the + file and compare signatures etc). + + If you dont need that field you can remove it or select only some + fields using [set + operations](https://docs.velociraptor.app/knowledge_base/tips/set_operations/). This will make the operations a lot faster. + + ```vql + LET FieldMask <= dict(VersionInformation=TRUE, Imports=TRUE) + LET ExcludeFields <= dict(AuthenticodeHash=TRUE) + + SELECT parse_pe(file="C:/Windows/Notepad.exe") * FieldMask AS PEInfo, + parse_pe(file="C:/Windows/Notepad.exe") - ExcludeFields AS MorePEInfo + FROM scope() + ``` + + ## Parsing PE files from memory + + On Windows, when an executable is loaded into memory, the PE file + is mapped directly into memory. It is therefore possible to parse + the PE file from memory itself using the "process" accessor (in a + similar way to the `pedump` plugin from Volatility) + + To do this you need to know the memory address where the PE file + is loaded at. This is usually called the BaseAddress and plugins + like `vad()` can provide it for a running process. + + ```vql + LET FieldsToClear <= dict(AuthenticodeHash=TRUE, + Authenticode=TRUE) + + SELECT *, parse_pe(accessor="process", + file=str(str=getpid()), + base_offset=Address) - FieldsToClear AS PEInfo + FROM vad(pid=getpid()) + WHERE MappingName =~ ".exe$" + ``` + + Note that when parsing from memory it is likely that some of the + memory would be changed from the pure, on disk PE file. Therefore + things like authenticode signatures are unlikely to be correct. It + is usually safer to remove these fields because they may not be + that relevant or corrupted and may result in slowing down the + query. type: Function args: @@ -7033,4 +7213,8 @@ type: string description: File accessor + - name: schema + type: string + description: Json schema to use for validation. + repeated: true category: parsers metadata: @@ -7570,4 +7754,7 @@ description: Process ID. required: true + - name: max_items + type: int64 + description: The maximum number of process entries to return (default 10) platforms: - darwin_amd64_cgo @@ -7584,4 +7771,7 @@ description: Process ID. required: true + - name: max_items + type: int64 + description: The maximum number of process entries to return (default 10) platforms: - darwin_amd64_cgo @@ -7598,4 +7788,7 @@ description: Process ID. required: true + - name: max_items + type: int64 + description: The maximum number of process entries to return (default 10) category: popular platforms: @@ -7626,4 +7819,7 @@ description: A VQL Lambda function to that receives a ProcessEntry and returns the data node for each process. + - name: max_items + type: int64 + description: The maximum number of process entries to return (default 1000) platforms: - darwin_amd64_cgo @@ -7851,4 +8047,5 @@ You can define the LET statements outside the query block and pass them in: + ```vql LET Foo(X) = .... @@ -7859,5 +8056,7 @@ ``` - Or declare the VQL block as a string; + Or declare the VQL block as a string: + + ```vql SELECT * FROM query(query=''' LET Foo(X) = .... @@ -8872,28 +9071,4 @@ - linux_amd64_cgo - windows_amd64_cgo -- name: secret_define - description: Define a new secret template - type: Function - args: - - name: type - type: string - description: Type of the secret - required: true - - name: verifier - type: string - description: A VQL Lambda function to verify the secret - - name: description - type: string - description: A description of the secret type - - name: template - type: ordereddict.Dict - description: A Set of key/value pairs - required: true - category: server - metadata: - permissions: SERVER_ADMIN - platforms: - - linux_amd64_cgo - - windows_amd64_cgo - name: secret_modify description: Modify the secret @@ -10518,5 +10693,37 @@ If Velociraptor is run locally the file will be copied to the `--dump_dir` path or added to the triage evidence container. + + ## Resumable Uploads + + As of Velociraptor 0.75 the client may support resumable + uploads. The VQL query may elect for uploads to be resumable by + setting the VQL parameter `UPLOAD_IS_RESUMABLE` for example: + + ```vql + LET UPLOAD_IS_RESUMABLE <= TRUE + ``` + + This variable changes the `upload()` function into resumable mode: + + 1. The function will schedule an upload transaction on the client + 2. After scheduling the transaction, the function will return + immediately allowing the VQL query to proceed quickly. + + When using resumable uploads, the returned object from this + function **does not** include a hash since the actual upload will + occur in the background. There is limited error handling for + resumable uploads. + + NOTE: Only some accessors support resumable uploads. Specifically + those accessors which can guarantee the file will remain in place + for a long time (enough time for the user to request + resuming). Usually it only makes sense to upload accessors like + `file`, `ntfs` etc. + + It does not usually make sense to upload temp files using + resumable uploads because the temporary file will be cleared after + the query ends. type: Function + version: 2 args: - name: file @@ -11686,5 +11893,43 @@ - windows_amd64_cgo - name: watch_syslog - description: 'Watch a syslog file and stream events from it. ' + description: | + Watch a syslog file and stream events from it. + + When the plugin starts watching, it seeks to the end of the file + and forwards any new lines from it. + + This plugin will tail a line delimited text file and emit rows for + each new line that appears in the file (It does not have to be a + syslog file, as many programs log into a line delimited text + file). + + You can specify a set of non-existent files in the `filename` arg + and the plugin will wait for the files to appear, then stream + their content. When new files appear, the plugin will also dump + their entire file content to ensure no lines are missed. + + Sometimes it is not known in advance what the filename is, so in + this case you can specify the query parameter to search for new + files to watch periodically. If a new file appears, this plugin + will dump all its existing lines then seek to the end of the file + and continue dumping any new lines (So no lines should be missed). + + ## Example (Dynamic watcher): + + ```vql + SELECT OSPath, Line + FROM watch_syslog(query={ + SELECT OSPath FROM glob(globs='/var/log/logfile*.log') + }) + ``` + + ## Example: + + The following will watch a static file (this can not be a glob). + + ```vql + SELECT OSPath, Line + FROM watch_syslog(filename='/var/log/logfile.log') + ``` type: Plugin args: @@ -11693,5 +11938,4 @@ description: A list of log files to parse. repeated: true - required: true - name: accessor type: string @@ -11700,4 +11944,8 @@ type: int description: Maximum size of line buffer. + - name: query + type: StoredQuery + description: If specified we run this query periodically to watch for new files. + Rows must have an OSPath column. category: event metadata: @@ -11997,5 +12245,5 @@ caching these rules for more efficiency. - It is therefore appropriate to repeatadly call the yara() plugin + It is therefore appropriate to repeatedly call the yara() plugin many times on many different files for scanning. @@ -12076,5 +12324,4 @@ signatures can be easily invalidated, robust rules typically have other conditions as a fallback so the impact should be minimal. - type: Plugin args: @@ -12190,4 +12437,74 @@ - windows_386_cgo - windows_amd64_cgo +- name: yarax + description: | + Scan files using yara rules (Using the new yarax engine). + + This is an experiemental new functionality to use the + [YaraX](https://github.com/VirusTotal/yara-x) project instead of + the more traditional C based Yara engine. + + One of the biggest issues for Velociraptor integration is the very + large size of the `YaraX` library (which is written in + Rust). Including `YaraX` in Velociraptor will increase our binary + size by a third (about 25Mb) for a single experiemental plugin. + + Therefore, we have decided to distribute `YaraX` as a [third party + tool](https://docs.velociraptor.app/docs/artifacts/tools/) and + load the DLL at runtime. + + You must specify a lambda function to the `dll_path` parameter + which will be evaluated only if needed. The function should return + the absolute path to the YaraX DLL on disk. Once the dll is + loaded, it is not unloaded again. This way you can avoid having to + download or hash the dll until actually needed. + type: Plugin + args: + - name: rules + type: string + description: Yara rules in the yara DSL or after being compiled by the yarac compiler. + - name: files + type: Any + description: The list of files to scan. + repeated: true + required: true + - name: accessor + type: string + description: Accessor (e.g. ntfs,file) + - name: context + type: int + description: How many bytes to include around each hit + - name: start + type: uint64 + description: The start offset to scan + - name: end + type: uint64 + description: End scanning at this offset (100mb) + - name: number + type: int64 + description: Stop after this many hits (1). + - name: blocksize + type: uint64 + description: Blocksize for scanning (10mb). + - name: key + type: string + description: If set use this key to cache the yara rules. + - name: namespace + type: string + description: The Yara namespece to use. + - name: vars + type: ordereddict.Dict + description: The Yara variables to use. + - name: dll_path + type: vfilter.Lambda + description: Function to resolve path to the yarax DLL + required: true + - name: force_buffers + type: bool + description: Force buffer scan in all cases. + metadata: + permissions: FILESYSTEM_READ,EXECVE + platforms: + - linux_amd64_cgo - name: zip description: | diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/docs/winres/winres.json /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/docs/winres/winres.json --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/docs/winres/winres.json 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/docs/winres/winres.json 2025-11-01 15:52:20.000000000 +0000 @@ -12,5 +12,5 @@ "identity": { "name": "", - "version": "0.72.0.1" + "version": "0.75.3.0" }, "description": "Velociraptor: Digging deeper!", @@ -36,6 +36,6 @@ "0000": { "fixed": { - "file_version": "0.72.0.1", - "product_version": "0.72.0.1" + "file_version": "0.75.3.0", + "product_version": "0.75.3.0" }, "info": { @@ -44,5 +44,5 @@ "CompanyName": "Rapid 7 Inc", "FileDescription": "Velociraptor: Digging Deeper!", - "FileVersion": "0.72.0.1", + "FileVersion": "0.75.3.0", "InternalName": "", "LegalCopyright": "Rapid 7 Inc", @@ -51,5 +51,5 @@ "PrivateBuild": "", "ProductName": "Velociraptor", - "ProductVersion": "0.72.0.1", + "ProductVersion": "0.75.3.0", "SpecialBuild": "" } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/executor/crash.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/executor/crash.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/executor/crash.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/executor/crash.go 2025-11-01 15:52:20.000000000 +0000 @@ -5,13 +5,14 @@ import ( "context" - "io/ioutil" "os" "sync" config_proto "www.velocidex.com/golang/velociraptor/config/proto" + "www.velocidex.com/golang/velociraptor/constants" crypto_proto "www.velocidex.com/golang/velociraptor/crypto/proto" "www.velocidex.com/golang/velociraptor/json" "www.velocidex.com/golang/velociraptor/logging" "www.velocidex.com/golang/velociraptor/services/writeback" + "www.velocidex.com/golang/velociraptor/utils" ) @@ -51,5 +52,6 @@ } - serialized, err := ioutil.ReadAll(fd) + serialized, err := utils.ReadAllWithLimit(fd, + constants.MAX_MEMORY) // Try to remove the checkpoint in any case _ = fd.Close() diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/executor/executor_test.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/executor/executor_test.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/executor/executor_test.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/executor/executor_test.go 2025-11-01 15:52:20.000000000 +0000 @@ -70,4 +70,17 @@ } +func (self *ExecutorTestSuite) SetupTest() { + self.TestSuite.SetupTest() + + client_info_manager, err := services.GetClientInfoManager(self.ConfigObj) + assert.NoError(self.T(), err) + + err = client_info_manager.Set(self.Ctx, &services.ClientInfo{ + &actions_proto.ClientInfo{ + ClientId: self.client_id, + }}) + assert.NoError(self.T(), err) +} + // Cancelling the flow multiple times will cause a single // cancellation state and then ignore the rest. diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/executor/nanny.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/executor/nanny.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/executor/nanny.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/executor/nanny.go 2025-11-01 15:52:20.000000000 +0000 @@ -5,18 +5,25 @@ "os" "runtime" - "runtime/debug" + os_debug "runtime/debug" "sync" "time" + "github.com/Velocidex/ordereddict" config_proto "www.velocidex.com/golang/velociraptor/config/proto" "www.velocidex.com/golang/velociraptor/logging" + "www.velocidex.com/golang/velociraptor/services/debug" "www.velocidex.com/golang/velociraptor/utils" + "www.velocidex.com/golang/vfilter" ) var ( - Nanny = &NannyService{} + Nanny = &NannyService{ + OnWarnings: make(map[uint64]func()), + } ) type NannyService struct { + Ready bool + mu sync.Mutex last_pump_to_rb_attempt time.Time @@ -34,8 +41,55 @@ // function will only be called once. If the exit condition occurs // further OnExit2 will be called repeatadly. - OnExit func() + + // Called on First warning. + OnWarnings map[uint64]func() + + // Called on hard exit. OnExit2 func() - on_exit_called bool + // Set when we are in the warning phase. Next compliance check + // will call hard exit. + warning bool +} + +func (self *NannyService) ProfileWriter(ctx context.Context, + scope vfilter.Scope, output_chan chan vfilter.Row) { + + self.mu.Lock() + defer self.mu.Unlock() + + now := utils.GetTime().Now() + display := func(t time.Time) string { + if t.IsZero() { + return "" + } + return now.Sub(t).Round(time.Second).String() + } + + var m runtime.MemStats + runtime.ReadMemStats(&m) + + output_chan <- ordereddict.NewDict(). + Set("Timestamp", now.UTC()). + Set("WarningMode", self.warning). + Set("LastPumpToRb", display(self.last_pump_to_rb_attempt)). + Set("LastPumpToServer", display(self.last_pump_rb_to_server_attempt)). + Set("LastReadFromServer", display(self.last_read_from_server)). + Set("LastCheckTime", display(self.last_check_time)). + Set("MaxMemoryHardLimit", self.MaxMemoryHardLimit). + Set("CurrentMemory", m.Alloc). + Set("MaxConnectionDelay", + time.Duration(self.MaxConnectionDelay*time.Second).String()) +} + +func (self *NannyService) RegisterOnWarnings(id uint64, cb func()) { + self.mu.Lock() + defer self.mu.Unlock() + + if cb == nil { + delete(self.OnWarnings, id) + } else { + self.OnWarnings[id] = cb + } } @@ -67,5 +121,5 @@ // just sent data to the server and we wont need that // for a while so we can free our memory to the OS. - debug.FreeOSMemory() + os_debug.FreeOSMemory() if self.MaxMemoryHardLimit == 0 { @@ -94,4 +148,5 @@ } + t = reparseTime(t) now := utils.GetTime().Now() if t.Add(self.MaxConnectionDelay).Before(now) { @@ -99,4 +154,6 @@ "NannyService: Last %v too long ago %v (now is %v MaxConnectionDelay is %v)", message, t, now, self.MaxConnectionDelay) + + // Only exit on first attempt, otherwise record we fired. self._Exit() return true @@ -107,6 +164,7 @@ func (self *NannyService) _Exit() { - // If we already called the OnExit one time, we just hard exit. - if self.OnExit == nil || self.on_exit_called { + // If we already called the OnWarnings one time, we just hard + // exit. + if self.warning { self.Logger.Error("Hard Exit called!") if self.OnExit2 != nil { @@ -118,10 +176,21 @@ } - on_exit := self.OnExit - self.mu.Unlock() - // Release the lock in case the on exit function needs to send things. - on_exit() - self.mu.Lock() - self.on_exit_called = true + self.Logger.Debug("Nanny: First warning... Next compliance check will result in hard exit") + for _, cb := range self.OnWarnings { + // Release the lock in case the warning function needs to send + // things. + self.mu.Unlock() + cb() + self.mu.Lock() + } + + self.warning = true +} + +// Golang handles time shift transparently so suspend should not +// affect time arithmetics. Here we want to fall back on the specific +// handling for time shifts so we can report it. +func reparseTime(t time.Time) time.Time { + return time.Unix(0, t.UnixNano()) } @@ -131,6 +200,6 @@ // Keep track of the last time we checked things. - last_check_time := self.last_check_time - self.last_check_time = utils.GetTime().Now() + last_check_time := reparseTime(self.last_check_time) + self.last_check_time = reparseTime(utils.GetTime().Now()) // We should update self.last_check_time periodically @@ -140,25 +209,43 @@ // this check time. In this case we cosider the check // invalid and try again later. - if last_check_time.Add(period * 2). - Before(self.last_check_time) { + if last_check_time.Add(period * 2).Before(self.last_check_time) { + self.Logger.Error( + "NannyService: Detected timeshift: last_check_time was %v which is %v ago", + last_check_time.UTC().Format(time.RFC3339), + self.last_check_time.Sub(last_check_time). + Round(time.Second).String()) + + // Reset all the times to compensate for the time shift + self.last_pump_rb_to_server_attempt = self.last_check_time + self.last_pump_to_rb_attempt = self.last_check_time + self.last_read_from_server = self.last_check_time return } - called := self._CheckTime(self.last_pump_to_rb_attempt, "Pump to Ring Buffer") - if self._CheckTime(self.last_pump_rb_to_server_attempt, "Pump Ring Buffer to Server") { - called = true + // Only call the exit function once - if it was called skip all + // the other checks until the next round. Otherwise the other + // times will be out of compliance as well and the exit function + // will be called again in this round. + if self._CheckTime(self.last_pump_to_rb_attempt, + "Pump to Ring Buffer") { + return + } + if self._CheckTime(self.last_pump_rb_to_server_attempt, + "Pump Ring Buffer to Server") { + return } if self._CheckTime(self.last_read_from_server, "Read From Server") { - called = true + return } if self._CheckMemory("Exceeded HardMemoryLimit") { - called = true + return } - // Allow the trigger to be disarmed if the on_exit was - // able to reduce memory use or unstick the process. - if !called { - self.on_exit_called = false + // Allow the trigger to be disarmed if the on_exit was able to + // reduce memory use or unstick the process. + if self.warning { + self.Logger.Debug("NannyService: Back in compliance - disarming") } + self.warning = false } @@ -193,9 +280,11 @@ config_obj *config_proto.Config) *NannyService { return &NannyService{ + Ready: true, MaxMemoryHardLimit: config_obj.Client.MaxMemoryHardLimit, last_check_time: utils.GetTime().Now(), MaxConnectionDelay: time.Duration( config_obj.Client.NannyMaxConnectionDelay) * time.Second, - Logger: logging.GetLogger(config_obj, &logging.ClientComponent), + Logger: logging.GetLogger(config_obj, &logging.ClientComponent), + OnWarnings: make(map[uint64]func()), } } @@ -205,5 +294,7 @@ wg *sync.WaitGroup, config_obj *config_proto.Config) error { - if config_obj.Client == nil { + + // Allow at most a single functional nanny + if config_obj.Client == nil || Nanny.Ready { return nil } @@ -212,4 +303,11 @@ if config_obj.Client.NannyMaxConnectionDelay > 0 { Nanny.Start(ctx, wg) + + debug.RegisterProfileWriter(debug.ProfileWriterInfo{ + Name: "Nanny", + Description: "Inspect status of the nanny", + ProfileWriter: Nanny.ProfileWriter, + Categories: []string{"Client"}, + }) } return nil diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/executor/nanny_test.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/executor/nanny_test.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/executor/nanny_test.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/executor/nanny_test.go 2025-11-01 15:52:20.000000000 +0000 @@ -6,4 +6,5 @@ "www.velocidex.com/golang/velociraptor/config" + "www.velocidex.com/golang/velociraptor/logging" "www.velocidex.com/golang/velociraptor/utils" "www.velocidex.com/golang/velociraptor/vtesting/assert" @@ -33,5 +34,5 @@ helper := OnExitHelper{} Nanny := NewNanny(config_obj) - Nanny.OnExit = helper.Exit + Nanny.RegisterOnWarnings(1, helper.Exit) Nanny.OnExit2 = helper.Exit @@ -65,4 +66,7 @@ config_obj := config.GetDefaultConfig() config_obj.Client.NannyMaxConnectionDelay = 60 + config_obj.Verbose = true + + logging.InitLogging(config_obj) closer := utils.MockTime(utils.NewMockClock(time.Unix(1000, 0))) @@ -71,5 +75,6 @@ helper := OnExitHelper{} Nanny := NewNanny(config_obj) - Nanny.OnExit = helper.Exit + Nanny.RegisterOnWarnings(1, helper.Exit) + Nanny.OnExit2 = helper.Exit @@ -83,8 +88,11 @@ Nanny.checkOnce(period) + logging.ClearMemoryLogs() + // Now emulate a suspend cycle - the next check occurs a long time // after the last check utils.MockTime(utils.NewMockClock(time.Unix(2000, 0))) + // This should detect the timeshift and reset the above timers Nanny.checkOnce(period) @@ -92,11 +100,20 @@ assert.True(t, helper.exit_called.IsZero()) - // Step the next check by 10 sec - utils.MockTime(utils.NewMockClock(time.Unix(2010, 0))) + // The nanny detected the timeshift + assert.Regexp(t, "Detected timeshift", logging.GetMemoryLogs()) - // This will now trigger an exit - Nanny.checkOnce(period) + // Now emulate regular nanny heartbeats for the next while. + for t := int64(2010); t < 3000; t += 10 { + // Step the next check by 20 sec + utils.MockTime(utils.NewMockClock(time.Unix(t, 0))) + Nanny.checkOnce(period) + + // Stop as soon as the exit was called. + if !helper.exit_called.IsZero() { + break + } + } // First check after the 60 second timeout will trigger an exit. - assert.Equal(t, int64(2010), helper.exit_called.Unix()) + assert.Equal(t, int64(2070), helper.exit_called.Unix()) } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/executor/testutils.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/executor/testutils.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/executor/testutils.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/executor/testutils.go 2025-11-01 15:52:20.000000000 +0000 @@ -27,4 +27,5 @@ event_manager: &actions.EventTable{}, config_obj: config_obj, + ctx: context.Background(), } } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/executor/throttler/throttler.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/executor/throttler/throttler.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/executor/throttler/throttler.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/executor/throttler/throttler.go 2025-11-01 15:52:20.000000000 +0000 @@ -76,5 +76,5 @@ if self.iops_limit > 0 && - stats.GetAverageIOPS() > self.cpu_load_limit { + stats.GetAverageIOPS() > self.iops_limit { return false } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/file_store/directory/directory.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/file_store/directory/directory.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/file_store/directory/directory.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/file_store/directory/directory.go 2025-11-01 15:52:20.000000000 +0000 @@ -193,5 +193,11 @@ defer api.InstrumentWithDelay("open_write", "DirectoryFileStore", filename)() - err := datastore.MkdirAll(self.db, self.config_obj, filename.Dir()) + // Writes are only possible when the datastore is healthy. + err := self.db.Healthy() + if err != nil { + return nil, err + } + + err = datastore.MkdirAll(self.db, self.config_obj, filename.Dir()) if err != nil { logger := logging.GetLogger(self.config_obj, &logging.FrontendComponent) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/file_store/memcache/memcache.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/file_store/memcache/memcache.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/file_store/memcache/memcache.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/file_store/memcache/memcache.go 2025-11-01 15:52:20.000000000 +0000 @@ -395,4 +395,5 @@ !self.closed && !truncated && self.buffer.Len() == 0 { + self.flushing = false return nil } @@ -404,9 +405,10 @@ // Flush in the foreground and wait until the data hits the disk. if !async { - self.mu.Unlock() self._FlushSync(buffer.Bytes(), truncated, completions) self.mu.Lock() + self.flushing = false + return nil } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/file_store/memory/memory.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/file_store/memory/memory.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/file_store/memory/memory.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/file_store/memory/memory.go 2025-11-01 15:52:20.000000000 +0000 @@ -171,5 +171,5 @@ buff, pres := self.Data.Get(filename) if !pres { - return nil, os.ErrNotExist + return nil, utils.NotFoundError } @@ -191,5 +191,5 @@ buff, pres := self.Data.Get(src_filename) if !pres { - return os.ErrNotExist + return utils.NotFoundError } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/file_store/memory/reader.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/file_store/memory/reader.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/file_store/memory/reader.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/file_store/memory/reader.go 2025-11-01 15:52:20.000000000 +0000 @@ -6,4 +6,5 @@ "www.velocidex.com/golang/velociraptor/file_store/api" + "www.velocidex.com/golang/velociraptor/utils" "www.velocidex.com/golang/velociraptor/vtesting" ) @@ -23,5 +24,5 @@ fs_buf, pres := self.memory_file_store.Get(self.filename) if !pres { - return 0, os.ErrNotExist + return 0, utils.NotFoundError } @@ -71,5 +72,5 @@ fs_buf, pres := self.memory_file_store.Get(self.filename) if !pres { - return nil, os.ErrNotExist + return nil, utils.NotFoundError } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/file_store/memory/writer.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/file_store/memory/writer.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/file_store/memory/writer.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/file_store/memory/writer.go 2025-11-01 15:52:20.000000000 +0000 @@ -4,5 +4,4 @@ "bytes" "encoding/binary" - "os" "www.velocidex.com/golang/velociraptor/file_store/api" @@ -48,9 +47,9 @@ buff, ok := self.memory_file_store.Get(self.filename) if !ok { - return os.ErrNotExist + return utils.NotFoundError } if offset >= int64(len(buff)) { - return os.ErrNotExist + return utils.NotFoundError } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/file_store/test_utils/testing.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/file_store/test_utils/testing.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/file_store/test_utils/testing.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/file_store/test_utils/testing.go 2025-11-01 15:52:20.000000000 +0000 @@ -2,5 +2,4 @@ import ( - "io/ioutil" "testing" @@ -8,4 +7,5 @@ "github.com/stretchr/testify/require" config_proto "www.velocidex.com/golang/velociraptor/config/proto" + "www.velocidex.com/golang/velociraptor/constants" "www.velocidex.com/golang/velociraptor/datastore" "www.velocidex.com/golang/velociraptor/file_store" @@ -45,5 +45,5 @@ defer fd.Close() - data, err := ioutil.ReadAll(fd) + data, err := utils.ReadAllWithLimit(fd, constants.MAX_MEMORY) require.NoError(t, err) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/file_store/test_utils/testsuite.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/file_store/test_utils/testsuite.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/file_store/test_utils/testsuite.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/file_store/test_utils/testsuite.go 2025-11-01 15:52:20.000000000 +0000 @@ -3,5 +3,4 @@ import ( "context" - "io/ioutil" "os" "sort" @@ -266,5 +265,5 @@ assert.NoError(self.T(), err) - def, err := ioutil.ReadAll(fd) + def, err := utils.ReadAllWithLimit(fd, constants.MAX_MEMORY) assert.NoError(self.T(), err) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/file_store/tests/testsuite.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/file_store/tests/testsuite.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/file_store/tests/testsuite.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/file_store/tests/testsuite.go 2025-11-01 15:52:20.000000000 +0000 @@ -7,5 +7,4 @@ "fmt" "io" - "io/ioutil" "os" "sort" @@ -15,4 +14,5 @@ "github.com/stretchr/testify/suite" config_proto "www.velocidex.com/golang/velociraptor/config/proto" + "www.velocidex.com/golang/velociraptor/constants" "www.velocidex.com/golang/velociraptor/file_store/api" "www.velocidex.com/golang/velociraptor/file_store/path_specs" @@ -576,5 +576,5 @@ fd, err := self.file_store.ReadFile(path) assert.NoError(self.T(), err) - value, err := ioutil.ReadAll(fd) + value, err := utils.ReadAllWithLimit(fd, constants.MAX_MEMORY) assert.NoError(self.T(), err) return string(value) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/flows/artifacts.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/flows/artifacts.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/flows/artifacts.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/flows/artifacts.go 2025-11-01 15:52:20.000000000 +0000 @@ -739,5 +739,5 @@ } - logger.Error(fmt.Sprintf("Unable to load flow %s: %v", job.SessionId, err)) + logger.Error("Unable to load flow %s: %v", job.SessionId, err) client_manager, err := services.GetClientInfoManager(self.config_obj) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/flows/proto/artifact_collector.pb.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/flows/proto/artifact_collector.pb.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/flows/proto/artifact_collector.pb.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/flows/proto/artifact_collector.pb.go 2025-11-01 15:52:20.000000000 +0000 @@ -156,4 +156,5 @@ MaxBatchRows uint64 `protobuf:"varint,8,opt,name=max_batch_rows,json=maxBatchRows,proto3" json:"max_batch_rows,omitempty"` MaxBatchRowsBuffer uint64 `protobuf:"varint,9,opt,name=max_batch_rows_buffer,json=maxBatchRowsBuffer,proto3" json:"max_batch_rows_buffer,omitempty"` + Timeout uint64 `protobuf:"varint,11,opt,name=timeout,proto3" json:"timeout,omitempty"` } @@ -232,4 +233,11 @@ } +func (x *ArtifactSpec) GetTimeout() uint64 { + if x != nil { + return x.Timeout + } + return 0 +} + type ArtifactCollectorArgs struct { state protoimpl.MessageState @@ -1177,5 +1185,5 @@ 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x22, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, - 0x52, 0x03, 0x65, 0x6e, 0x76, 0x22, 0x81, 0x02, 0x0a, 0x0c, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x52, 0x03, 0x65, 0x6e, 0x76, 0x22, 0x9b, 0x02, 0x0a, 0x0c, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, @@ -1193,212 +1201,214 @@ 0x74, 0x63, 0x68, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x6d, 0x61, 0x78, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, - 0x6f, 0x77, 0x73, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x22, 0xd6, 0x07, 0x0a, 0x15, 0x41, 0x72, - 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x41, - 0x72, 0x67, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x1b, 0x0a, - 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, - 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x6c, 0x6f, 0x77, 0x5f, - 0x69, 0x64, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x6c, 0x6f, 0x77, 0x49, 0x64, - 0x12, 0x16, 0x0a, 0x06, 0x75, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x18, 0x15, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x06, 0x75, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x46, 0x0a, 0x09, 0x61, 0x72, 0x74, 0x69, - 0x66, 0x61, 0x63, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x42, 0x28, 0xe2, 0xfc, 0xe3, - 0xc4, 0x01, 0x22, 0x12, 0x18, 0x54, 0x68, 0x65, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, - 0x74, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x6c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x2e, 0x22, 0x06, 0x4c, - 0x61, 0x75, 0x6e, 0x63, 0x68, 0x52, 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, - 0x12, 0x29, 0x0a, 0x05, 0x73, 0x70, 0x65, 0x63, 0x73, 0x18, 0x18, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, - 0x53, 0x70, 0x65, 0x63, 0x52, 0x05, 0x73, 0x70, 0x65, 0x63, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x63, - 0x70, 0x75, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x19, 0x20, 0x01, 0x28, 0x02, 0x52, 0x08, - 0x63, 0x70, 0x75, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x6f, 0x70, 0x73, - 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x02, 0x52, 0x09, 0x69, 0x6f, - 0x70, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x70, 0x72, 0x6f, 0x67, 0x72, - 0x65, 0x73, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x1b, 0x20, 0x01, 0x28, - 0x02, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x6f, - 0x75, 0x74, 0x12, 0x65, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x07, 0x20, - 0x01, 0x28, 0x04, 0x42, 0x4b, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x45, 0x12, 0x35, 0x4e, 0x75, 0x6d, - 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x20, 0x74, - 0x6f, 0x20, 0x72, 0x75, 0x6e, 0x20, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x63, 0x61, 0x6e, - 0x63, 0x65, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x2e, 0x22, 0x07, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x32, 0x03, 0x36, 0x30, 0x30, - 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, - 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x16, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x6d, 0x61, 0x78, - 0x52, 0x6f, 0x77, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, 0x6c, 0x6f, 0x67, 0x73, - 0x18, 0x20, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x4c, 0x6f, 0x67, 0x73, 0x12, - 0x28, 0x0a, 0x10, 0x6d, 0x61, 0x78, 0x5f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x62, 0x79, - 0x74, 0x65, 0x73, 0x18, 0x17, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x6d, 0x61, 0x78, 0x55, 0x70, - 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x74, 0x72, 0x61, - 0x63, 0x65, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x5f, 0x73, 0x65, 0x63, 0x18, 0x1d, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x0c, 0x74, 0x72, 0x61, 0x63, 0x65, 0x46, 0x72, 0x65, 0x71, 0x53, 0x65, 0x63, 0x12, - 0x8d, 0x01, 0x0a, 0x16, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, - 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, - 0x42, 0x57, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x51, 0x12, 0x4f, 0x49, 0x66, 0x20, 0x74, 0x72, 0x75, - 0x65, 0x20, 0x77, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x20, - 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x20, - 0x69, 0x66, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x65, - 0x61, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x64, 0x20, - 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x2e, 0x52, 0x14, 0x61, 0x6c, 0x6c, 0x6f, 0x77, - 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x12, - 0x24, 0x0a, 0x0e, 0x6c, 0x6f, 0x67, 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x74, 0x69, 0x6d, - 0x65, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6c, 0x6f, 0x67, 0x42, 0x61, 0x74, 0x63, - 0x68, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x4f, 0x0a, 0x17, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, - 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x72, 0x67, 0x73, - 0x18, 0x14, 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, 0x52, - 0x15, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x64, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, - 0x6f, 0x72, 0x41, 0x72, 0x67, 0x73, 0x12, 0x6a, 0x0a, 0x0e, 0x6f, 0x70, 0x73, 0x5f, 0x70, 0x65, - 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x02, 0x42, 0x44, - 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x3e, 0x12, 0x23, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x20, 0x70, 0x65, 0x72, 0x20, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x28, 0x54, - 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x69, 0x6e, 0x67, 0x29, 0x2e, 0x22, 0x0e, 0x4f, 0x70, 0x73, - 0x20, 0x50, 0x65, 0x72, 0x20, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x32, 0x07, 0x31, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x52, 0x0c, 0x6f, 0x70, 0x73, 0x50, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, - 0x6e, 0x64, 0x22, 0x6c, 0x0a, 0x19, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x43, 0x6f, - 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x17, 0x0a, 0x07, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x66, 0x6c, 0x6f, 0x77, 0x49, 0x64, 0x12, 0x36, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x77, 0x73, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, + 0x65, 0x6f, 0x75, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, + 0x6f, 0x75, 0x74, 0x22, 0xd6, 0x07, 0x0a, 0x15, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, + 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x72, 0x67, 0x73, 0x12, 0x18, 0x0a, + 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, + 0x44, 0x61, 0x74, 0x61, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, + 0x64, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x69, 0x64, 0x18, 0x1f, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x66, 0x6c, 0x6f, 0x77, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x72, + 0x67, 0x65, 0x6e, 0x74, 0x18, 0x15, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x75, 0x72, 0x67, 0x65, + 0x6e, 0x74, 0x12, 0x46, 0x0a, 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x09, 0x42, 0x28, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x22, 0x12, 0x18, 0x54, + 0x68, 0x65, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x20, 0x74, 0x6f, 0x20, + 0x6c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x2e, 0x22, 0x06, 0x4c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x52, + 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x29, 0x0a, 0x05, 0x73, 0x70, + 0x65, 0x63, 0x73, 0x18, 0x18, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x70, 0x65, 0x63, 0x52, 0x05, + 0x73, 0x70, 0x65, 0x63, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x70, 0x75, 0x5f, 0x6c, 0x69, 0x6d, + 0x69, 0x74, 0x18, 0x19, 0x20, 0x01, 0x28, 0x02, 0x52, 0x08, 0x63, 0x70, 0x75, 0x4c, 0x69, 0x6d, + 0x69, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x6f, 0x70, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, + 0x18, 0x1a, 0x20, 0x01, 0x28, 0x02, 0x52, 0x09, 0x69, 0x6f, 0x70, 0x73, 0x4c, 0x69, 0x6d, 0x69, + 0x74, 0x12, 0x29, 0x0a, 0x10, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x69, + 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0f, 0x70, 0x72, 0x6f, + 0x67, 0x72, 0x65, 0x73, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x65, 0x0a, 0x07, + 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x42, 0x4b, 0xe2, + 0xfc, 0xe3, 0xc4, 0x01, 0x45, 0x12, 0x35, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, + 0x20, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x72, 0x75, 0x6e, 0x20, + 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x69, 0x6e, + 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x22, 0x07, 0x54, 0x69, + 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x32, 0x03, 0x36, 0x30, 0x30, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, + 0x6f, 0x75, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, + 0x16, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x52, 0x6f, 0x77, 0x73, 0x12, 0x19, + 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x20, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x07, 0x6d, 0x61, 0x78, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x6d, 0x61, 0x78, + 0x5f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x17, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x0e, 0x6d, 0x61, 0x78, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x79, + 0x74, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x66, 0x72, 0x65, + 0x71, 0x5f, 0x73, 0x65, 0x63, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x74, 0x72, 0x61, + 0x63, 0x65, 0x46, 0x72, 0x65, 0x71, 0x53, 0x65, 0x63, 0x12, 0x8d, 0x01, 0x0a, 0x16, 0x61, 0x6c, + 0x6c, 0x6f, 0x77, 0x5f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, + 0x69, 0x64, 0x65, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x42, 0x57, 0xe2, 0xfc, 0xe3, 0xc4, + 0x01, 0x51, 0x12, 0x4f, 0x49, 0x66, 0x20, 0x74, 0x72, 0x75, 0x65, 0x20, 0x77, 0x65, 0x20, 0x77, + 0x69, 0x6c, 0x6c, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x20, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, + 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x20, 0x69, 0x66, 0x20, 0x70, 0x72, 0x65, + 0x73, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x65, 0x61, 0x64, 0x20, 0x6f, 0x66, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x64, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x2e, 0x52, 0x14, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, + 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x6c, 0x6f, 0x67, + 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x1c, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x0c, 0x6c, 0x6f, 0x67, 0x42, 0x61, 0x74, 0x63, 0x68, 0x54, 0x69, 0x6d, 0x65, 0x12, + 0x4f, 0x0a, 0x17, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6c, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x18, 0x14, 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, 0x52, 0x15, 0x63, 0x6f, 0x6d, 0x70, 0x69, + 0x6c, 0x65, 0x64, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x72, 0x67, 0x73, + 0x12, 0x6a, 0x0a, 0x0e, 0x6f, 0x70, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, + 0x6e, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x02, 0x42, 0x44, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x3e, + 0x12, 0x23, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x70, 0x65, 0x72, + 0x20, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x28, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, + 0x69, 0x6e, 0x67, 0x29, 0x2e, 0x22, 0x0e, 0x4f, 0x70, 0x73, 0x20, 0x50, 0x65, 0x72, 0x20, 0x53, + 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x32, 0x07, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x52, 0x0c, + 0x6f, 0x70, 0x73, 0x50, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x22, 0x6c, 0x0a, 0x19, + 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x6c, 0x6f, + 0x77, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x6c, 0x6f, 0x77, + 0x49, 0x64, 0x12, 0x36, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, + 0x66, 0x61, 0x63, 0x74, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x72, 0x67, + 0x73, 0x52, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xb2, 0x01, 0x0a, 0x18, 0x41, + 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x46, + 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x76, + 0x66, 0x73, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, + 0x66, 0x73, 0x50, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x64, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x0a, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, + 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, + 0x2e, 0x0a, 0x0b, 0x50, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x1f, + 0x0a, 0x0b, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x0a, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x22, + 0xb1, 0x0b, 0x0a, 0x18, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x43, 0x6f, 0x6c, 0x6c, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x1b, 0x0a, 0x09, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x36, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x72, 0x67, 0x73, 0x52, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x22, 0xb2, 0x01, 0x0a, 0x18, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x55, 0x70, 0x6c, - 0x6f, 0x61, 0x64, 0x65, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x19, 0x0a, 0x08, 0x76, 0x66, 0x73, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x66, 0x73, 0x50, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, - 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, - 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x53, 0x69, 0x7a, - 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x18, - 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, - 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x2e, 0x0a, 0x0b, 0x50, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, - 0x74, 0x65, 0x78, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x74, - 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x61, 0x63, 0x74, 0x69, 0x76, - 0x65, 0x54, 0x69, 0x6d, 0x65, 0x22, 0xb1, 0x0b, 0x0a, 0x18, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, - 0x63, 0x74, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x65, - 0x78, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, - 0x1b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, - 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x0d, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x36, - 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, - 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x72, 0x67, 0x73, 0x52, 0x07, 0x72, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x62, 0x61, 0x63, 0x6b, 0x74, 0x72, - 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x61, 0x63, 0x6b, 0x74, - 0x72, 0x61, 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, - 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, - 0x69, 0x6d, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, - 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x74, - 0x69, 0x6d, 0x65, 0x18, 0x11, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x61, 0x63, 0x74, 0x69, 0x76, - 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x66, 0x6c, 0x69, 0x67, 0x68, - 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x24, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x69, 0x6e, - 0x66, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x30, 0x0a, 0x14, 0x74, 0x6f, - 0x74, 0x61, 0x6c, 0x5f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x5f, 0x66, 0x69, 0x6c, - 0x65, 0x73, 0x18, 0x17, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x55, - 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x41, 0x0a, 0x1d, - 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x75, - 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x19, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x1a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x45, 0x78, 0x70, 0x65, 0x63, 0x74, - 0x65, 0x64, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, - 0x30, 0x0a, 0x14, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, - 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x74, - 0x6f, 0x74, 0x61, 0x6c, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, - 0x73, 0x12, 0x30, 0x0a, 0x14, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x6c, 0x6c, 0x65, - 0x63, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x12, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, - 0x6f, 0x77, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x6c, 0x6f, 0x67, - 0x73, 0x18, 0x20, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x4c, 0x6f, - 0x67, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x73, 0x18, 0x23, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x6f, 0x74, 0x61, - 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x12, 0x31, 0x0a, 0x14, 0x6f, 0x75, 0x74, - 0x73, 0x74, 0x61, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x73, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x03, 0x52, 0x13, 0x6f, 0x75, 0x74, 0x73, 0x74, 0x61, 0x6e, - 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x12, 0x39, 0x0a, 0x18, - 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x6f, 0x75, 0x74, - 0x73, 0x74, 0x61, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x25, 0x20, 0x01, 0x28, 0x04, 0x52, 0x17, - 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x73, - 0x74, 0x61, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x28, 0x0a, 0x10, 0x6e, 0x65, 0x78, 0x74, 0x5f, - 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x1e, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x0e, 0x6e, 0x65, 0x78, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, - 0x64, 0x12, 0x2d, 0x0a, 0x12, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, - 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x65, - 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x3b, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x25, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, - 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, - 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x4f, 0x0a, - 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x42, 0x37, 0xe2, - 0xfc, 0xe3, 0xc4, 0x01, 0x31, 0x12, 0x2f, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x20, - 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x73, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x20, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x9f, - 0x01, 0x0a, 0x16, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x5f, 0x77, 0x69, 0x74, - 0x68, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x16, 0x20, 0x03, 0x28, 0x09, 0x42, - 0x69, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x63, 0x12, 0x61, 0x54, 0x68, 0x65, 0x20, 0x66, 0x75, 0x6c, - 0x6c, 0x20, 0x70, 0x61, 0x74, 0x68, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, - 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, - 0x69, 0x72, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x2e, 0x20, 0x54, 0x68, 0x69, 0x73, - 0x20, 0x74, 0x61, 0x6b, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x20, - 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x2f, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x52, 0x14, 0x61, 0x72, 0x74, 0x69, - 0x66, 0x61, 0x63, 0x74, 0x73, 0x57, 0x69, 0x74, 0x68, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, - 0x12, 0x32, 0x0a, 0x0b, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, - 0x22, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x65, - 0x6c, 0x6f, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x0a, 0x71, 0x75, 0x65, 0x72, 0x79, 0x53, - 0x74, 0x61, 0x74, 0x73, 0x12, 0x46, 0x0a, 0x0e, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, - 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x18, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x55, 0x70, 0x6c, - 0x6f, 0x61, 0x64, 0x65, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0d, 0x75, - 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, - 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x10, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x0c, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, - 0x64, 0x12, 0x25, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x14, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x6f, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x69, 0x72, 0x74, - 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x64, 0x69, 0x72, 0x74, 0x79, 0x12, 0x1f, - 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x18, 0x21, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x4c, 0x6f, 0x61, 0x64, 0x73, 0x22, - 0x68, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x55, 0x4e, 0x53, 0x45, - 0x54, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x55, 0x4e, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x01, - 0x12, 0x0b, 0x0a, 0x07, 0x57, 0x41, 0x49, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x06, 0x12, 0x0f, 0x0a, - 0x0b, 0x49, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, 0x04, 0x12, 0x10, - 0x0a, 0x0c, 0x55, 0x4e, 0x52, 0x45, 0x53, 0x50, 0x4f, 0x4e, 0x53, 0x49, 0x56, 0x45, 0x10, 0x05, - 0x12, 0x0c, 0x0a, 0x08, 0x46, 0x49, 0x4e, 0x49, 0x53, 0x48, 0x45, 0x44, 0x10, 0x02, 0x12, 0x09, - 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x22, 0x5f, 0x0a, 0x0b, 0x4c, 0x61, 0x62, - 0x65, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, - 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x3a, - 0x0a, 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, - 0x63, 0x74, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x72, 0x67, 0x73, 0x52, - 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x22, 0x3e, 0x0a, 0x1f, 0x47, 0x65, - 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, - 0x67, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 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, 0x22, 0xda, 0x01, 0x0a, 0x10, 0x43, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, - 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3a, 0x0a, 0x09, 0x61, 0x72, 0x74, - 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x43, 0x6f, 0x6c, - 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x72, 0x67, 0x73, 0x52, 0x09, 0x61, 0x72, 0x74, 0x69, - 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x35, 0x0a, 0x0c, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x5f, 0x65, - 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, - 0x0b, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x39, 0x0a, 0x0e, - 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x65, 0x6c, - 0x6f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x55, 0x0a, 0x10, 0x55, 0x70, 0x6c, 0x6f, 0x61, - 0x64, 0x65, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, - 0x19, 0x0a, 0x08, 0x76, 0x66, 0x73, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x07, 0x76, 0x66, 0x73, 0x50, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, - 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x42, 0x33, - 0x5a, 0x31, 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, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x12, 0x1c, 0x0a, 0x09, 0x62, 0x61, 0x63, 0x6b, 0x74, 0x72, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x61, 0x63, 0x6b, 0x74, 0x72, 0x61, 0x63, 0x65, 0x12, 0x1f, + 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, + 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x12, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1f, + 0x0a, 0x0b, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x11, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x0a, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, + 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x66, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, + 0x18, 0x24, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x69, 0x6e, 0x66, 0x6c, 0x69, 0x67, 0x68, 0x74, + 0x54, 0x69, 0x6d, 0x65, 0x12, 0x30, 0x0a, 0x14, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x75, 0x70, + 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x17, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x12, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, + 0x64, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x41, 0x0a, 0x1d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, + 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, + 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x19, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1a, 0x74, + 0x6f, 0x74, 0x61, 0x6c, 0x45, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x55, 0x70, 0x6c, 0x6f, + 0x61, 0x64, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x74, 0x6f, 0x74, + 0x61, 0x6c, 0x5f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, + 0x73, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x55, 0x70, + 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x74, + 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x72, + 0x6f, 0x77, 0x73, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x74, 0x6f, 0x74, 0x61, 0x6c, + 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x6f, 0x77, 0x73, 0x12, 0x1d, 0x0a, + 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x20, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x09, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x25, 0x0a, 0x0e, + 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x23, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x73, 0x12, 0x31, 0x0a, 0x14, 0x6f, 0x75, 0x74, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x1f, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x13, 0x6f, 0x75, 0x74, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x12, 0x39, 0x0a, 0x18, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x6f, 0x75, 0x74, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x18, 0x25, 0x20, 0x01, 0x28, 0x04, 0x52, 0x17, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x69, 0x6e, + 0x67, 0x12, 0x28, 0x0a, 0x10, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x6e, 0x65, 0x78, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x64, 0x12, 0x2d, 0x0a, 0x12, 0x65, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3b, 0x0a, 0x05, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, + 0x74, 0x6f, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x4f, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x42, 0x37, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x31, 0x12, + 0x2f, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x73, 0x65, 0x6e, + 0x74, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, + 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x9f, 0x01, 0x0a, 0x16, 0x61, 0x72, 0x74, + 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x72, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x73, 0x18, 0x16, 0x20, 0x03, 0x28, 0x09, 0x42, 0x69, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, + 0x63, 0x12, 0x61, 0x54, 0x68, 0x65, 0x20, 0x66, 0x75, 0x6c, 0x6c, 0x20, 0x70, 0x61, 0x74, 0x68, + 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, + 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x69, 0x72, 0x20, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x73, 0x2e, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x74, 0x61, 0x6b, 0x65, 0x73, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x2f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x6e, + 0x61, 0x6d, 0x65, 0x2e, 0x52, 0x14, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x57, + 0x69, 0x74, 0x68, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x32, 0x0a, 0x0b, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x22, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x65, 0x6c, 0x6f, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x0a, 0x71, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x46, + 0x0a, 0x0e, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, + 0x18, 0x18, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, + 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x46, + 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0d, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, + 0x64, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, + 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x75, + 0x73, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x25, 0x0a, 0x04, 0x6c, + 0x6f, 0x67, 0x73, 0x18, 0x14, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x4c, 0x6f, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x04, 0x6c, 0x6f, + 0x67, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x69, 0x72, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x05, 0x64, 0x69, 0x72, 0x74, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, + 0x6c, 0x5f, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x18, 0x21, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x74, + 0x6f, 0x74, 0x61, 0x6c, 0x4c, 0x6f, 0x61, 0x64, 0x73, 0x22, 0x68, 0x0a, 0x05, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x55, 0x4e, 0x53, 0x45, 0x54, 0x10, 0x00, 0x12, 0x0b, 0x0a, + 0x07, 0x52, 0x55, 0x4e, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x57, 0x41, + 0x49, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x06, 0x12, 0x0f, 0x0a, 0x0b, 0x49, 0x4e, 0x5f, 0x50, 0x52, + 0x4f, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, 0x04, 0x12, 0x10, 0x0a, 0x0c, 0x55, 0x4e, 0x52, 0x45, + 0x53, 0x50, 0x4f, 0x4e, 0x53, 0x49, 0x56, 0x45, 0x10, 0x05, 0x12, 0x0c, 0x0a, 0x08, 0x46, 0x49, + 0x4e, 0x49, 0x53, 0x48, 0x45, 0x44, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, + 0x52, 0x10, 0x03, 0x22, 0x5f, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x3a, 0x0a, 0x09, 0x61, 0x72, 0x74, 0x69, + 0x66, 0x61, 0x63, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x43, 0x6f, 0x6c, 0x6c, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x72, 0x67, 0x73, 0x52, 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, + 0x61, 0x63, 0x74, 0x73, 0x22, 0x3e, 0x0a, 0x1f, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 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, 0x22, 0xda, 0x01, 0x0a, 0x10, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x3a, 0x0a, 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, + 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x41, 0x72, 0x67, 0x73, 0x52, 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, + 0x35, 0x0a, 0x0c, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, + 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x61, + 0x62, 0x65, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x0b, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x39, 0x0a, 0x0e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x65, 0x6c, 0x6f, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x52, 0x0d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x22, 0x55, 0x0a, 0x10, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x46, 0x69, 0x6c, + 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x76, 0x66, 0x73, + 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x66, 0x73, + 0x50, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x42, 0x33, 0x5a, 0x31, 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, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/flows/proto/artifact_collector.proto /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/flows/proto/artifact_collector.proto --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/flows/proto/artifact_collector.proto 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/flows/proto/artifact_collector.proto 2025-11-01 15:52:20.000000000 +0000 @@ -25,4 +25,5 @@ uint64 max_batch_rows = 8; uint64 max_batch_rows_buffer = 9; + uint64 timeout = 11; } Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75: go-vendor-tools.toml diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/go.mod /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/go.mod --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/go.mod 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/go.mod 2025-11-03 21:29:47.000000000 +0000 @@ -8,7 +8,6 @@ github.com/Showmax/go-fqdn v1.0.0 github.com/Velocidex/amsi v0.0.0-20250418124629-ea341d1aa3f2 - github.com/Velocidex/etw v0.0.0-20250314035532-6115b05b9430 + github.com/Velocidex/etw v0.0.0-20251027041548-6d97883fd588 github.com/Velocidex/go-elasticsearch/v7 v7.3.1-0.20191001125819-fee0ef9cac6b - github.com/Velocidex/go-magic v0.0.0-20250203094020-32f94b14f00f github.com/Velocidex/go-yara v1.1.10-0.20250823152352-e5fc0843e50e github.com/Velocidex/grpc-go-pool v1.2.2-0.20241016164850-ff0cb80037a8 @@ -18,9 +17,9 @@ github.com/Velocidex/ttlcache/v2 v2.9.1-0.20240517145123-a3f45e86e130 github.com/Velocidex/yaml/v2 v2.2.8 - github.com/Velocidex/zip v0.0.0-20250102162034-1a0ec0ec569c + github.com/Velocidex/zip v0.0.0-20251027040802-582e676739bd github.com/alecthomas/assert v1.0.0 github.com/alecthomas/chroma v0.7.3 github.com/alecthomas/participle v0.7.1 - github.com/alecthomas/repr v0.5.1 // indirect + github.com/alecthomas/repr v0.5.2 // indirect github.com/alexmullins/zip v0.0.0-20180717182244-4affb64b04d0 github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de @@ -48,5 +47,4 @@ github.com/juju/ratelimit v1.0.1 github.com/lib/pq v1.10.9 - github.com/magefile/mage v1.15.0 github.com/mattn/go-isatty v0.0.20 github.com/mattn/go-pointer v0.0.0-20180825124634-49522c3f3791 @@ -67,18 +65,18 @@ github.com/sergi/go-diff v1.3.1 github.com/sirupsen/logrus v1.8.1 - github.com/stretchr/testify v1.10.0 + github.com/stretchr/testify v1.11.1 github.com/xor-gate/ar v0.0.0-20170530204233-5c72ae81e2b7 // indirect github.com/xor-gate/debpkg v1.0.0 go.starlark.net v0.0.0-20230925163745-10651d5192ab golang.org/x/crypto v0.39.0 - golang.org/x/mod v0.26.0 + golang.org/x/mod v0.28.0 golang.org/x/net v0.41.0 - golang.org/x/sys v0.33.0 - golang.org/x/text v0.28.0 + golang.org/x/sys v0.37.0 + golang.org/x/text v0.30.0 golang.org/x/time v0.5.0 google.golang.org/api v0.169.0 google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect google.golang.org/grpc v1.67.1 - google.golang.org/protobuf v1.36.7 + google.golang.org/protobuf v1.36.10 gopkg.in/alecthomas/kingpin.v2 v2.2.6 gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect @@ -89,9 +87,9 @@ www.velocidex.com/golang/go-ese v0.2.1-0.20250215160921-5af66dc0f6ed www.velocidex.com/golang/go-ntfs v0.2.1-0.20250322152626-3c09d909d740 - www.velocidex.com/golang/go-pe v0.1.1-0.20250101153735-7a925ba8334b - www.velocidex.com/golang/go-prefetch v0.0.0-20250529114725-e36ea8a283e2 + www.velocidex.com/golang/go-pe v0.1.1-0.20251015235828-0a2958753ebf + www.velocidex.com/golang/go-prefetch v0.0.0-20251027080408-85407689d0cb www.velocidex.com/golang/oleparse v0.0.0-20250312121321-f7c2b4ec0959 www.velocidex.com/golang/regparser v0.0.0-20250203141505-31e704a67ef7 - www.velocidex.com/golang/vfilter v0.0.0-20250822163628-cf253ab459bc + www.velocidex.com/golang/vfilter v0.0.0-20250915140904-eb07b966bcef ) @@ -100,5 +98,5 @@ github.com/Masterminds/semver/v3 v3.4.0 github.com/Masterminds/sprig/v3 v3.2.2 - github.com/Velocidex/WinPmem/go-winpmem v0.0.0-20250618151512-1385e105b127 + github.com/Velocidex/WinPmem/go-winpmem v0.0.0-20251014141320-f59d776a3def github.com/Velocidex/file-rotatelogs v0.0.0-20211221020724-d12e4dae4e11 github.com/Velocidex/fileb0x v1.1.2-0.20241111170537-c093c89cd042 @@ -106,5 +104,6 @@ github.com/Velocidex/go-ext4 v0.0.0-20250510085914-b0b955af0359 github.com/Velocidex/go-fat v0.0.0-20230923165230-3e6c4265297a - github.com/Velocidex/go-journalctl v0.0.0-20250813052126-d39241ea8ef7 + github.com/Velocidex/go-journalctl v0.0.0-20250902002606-881a5f66df10 + github.com/Velocidex/go-magic v0.0.0-20250203094020-32f94b14f00f github.com/Velocidex/go-mscfb v0.0.0-20240618091452-31f4ccc54002 github.com/Velocidex/go-vhdx v0.0.0-20250511013458-5cba970cdeda @@ -114,4 +113,5 @@ github.com/Velocidex/sigma-go v0.0.0-20241113062227-c1c5ea4b5250 github.com/Velocidex/tracee_velociraptor v0.0.0-20250620124218-01f48d6fc3a1 + github.com/Velocidex/yara-x-go v0.0.0-20251010010632-d8eaad9c539c github.com/VirusTotal/gyp v0.9.1-0.20231202132633-bb35dbf177a6 github.com/alecthomas/kingpin/v2 v2.4.0 @@ -131,4 +131,5 @@ github.com/glaslos/tlsh v0.2.0 github.com/go-errors/errors v1.4.2 + github.com/go-json-experiment/json v0.0.0-20250910080747-cc2cfa0554c3 github.com/golang-jwt/jwt/v4 v4.5.2 github.com/golang/protobuf v1.5.4 @@ -140,6 +141,8 @@ github.com/inconshreveable/mousetrap v1.1.0 github.com/jackwakefield/gopac v1.0.2 + github.com/kaptinlin/jsonschema v0.5.2 github.com/leodido/go-syslog v1.0.1 github.com/lpar/gzipped v1.1.0 + github.com/magefile/mage v1.15.0 github.com/mccutchen/go-httpbin/v2 v2.18.3 github.com/mooijtech/go-pst/v6 v6.0.2 @@ -202,4 +205,6 @@ github.com/charmbracelet/x/term v0.2.1 // indirect github.com/cilium/ebpf v0.18.0 // indirect + github.com/clipperhouse/stringish v0.1.1 // indirect + github.com/clipperhouse/uax29/v2 v2.3.0 // indirect github.com/crewjam/httperr v0.2.0 // indirect github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 // indirect @@ -216,4 +221,5 @@ github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect + github.com/goccy/go-yaml v1.18.0 // indirect github.com/godzie44/go-uring v0.0.0-20220926161041-69611e8b13d5 // indirect github.com/golang/gddo v0.0.0-20210115222349-20d68f94ee1f // indirect @@ -232,4 +238,6 @@ github.com/hillu/go-yara/v4 v4.3.2 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/kaptinlin/go-i18n v0.2.0 // indirect + github.com/kaptinlin/messageformat-go v0.4.6 // indirect github.com/karrick/godirwalk v1.17.0 // indirect github.com/klauspost/compress v1.18.0 // indirect @@ -244,5 +252,5 @@ github.com/mattermost/xml-roundtrip-validator v0.1.0 // indirect github.com/mattn/go-localereader v0.0.1 // indirect - github.com/mattn/go-runewidth v0.0.16 // indirect + github.com/mattn/go-runewidth v0.0.19 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect @@ -269,5 +277,5 @@ github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect - github.com/ulikunitz/xz v0.5.11 // indirect + github.com/ulikunitz/xz v0.5.15 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect github.com/xhit/go-str2duration/v2 v2.1.0 // indirect @@ -283,5 +291,5 @@ go.uber.org/zap v1.27.0 // indirect golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect - golang.org/x/sync v0.16.0 // indirect + golang.org/x/sync v0.17.0 // indirect golang.org/x/term v0.32.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 // indirect @@ -291,4 +299,5 @@ ) +// replace github.com/Velocidex/yara-x-go => ../yara-x-go // replace github.com/Velocidex/grok => ../grok // replace www.velocidex.com/golang/vfilter => ../vfilter @@ -331,5 +340,5 @@ replace github.com/russross/blackfriday/v2 => github.com/Velocidex/blackfriday/v2 v2.0.2-0.20200811050547-4f26a09e2b3b -go 1.23.2 +go 1.25 // Needed for syntax highlighting VQL. Removes extra fat. diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/go.sum /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/go.sum --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/go.sum 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/go.sum 2025-11-01 15:52:20.000000000 +0000 @@ -50,6 +50,6 @@ github.com/Showmax/go-fqdn v1.0.0 h1:0rG5IbmVliNT5O19Mfuvna9LL7zlHyRfsSvBPZmF9tM= github.com/Showmax/go-fqdn v1.0.0/go.mod h1:SfrFBzmDCtCGrnHhoDjuvFnKsWjEQX/Q9ARZvOrJAko= -github.com/Velocidex/WinPmem/go-winpmem v0.0.0-20250618151512-1385e105b127 h1:wGTl6M8jQuu24e7fp3wjYJSRxHFApJE5HRFsNZBuVAk= -github.com/Velocidex/WinPmem/go-winpmem v0.0.0-20250618151512-1385e105b127/go.mod h1:HloPDQtxpV/iPxaKVE45+dz6DELiHZcBC1KFRlZtAtM= +github.com/Velocidex/WinPmem/go-winpmem v0.0.0-20251014141320-f59d776a3def h1:1FiSNT+Xh7UGohKsOoeDMkuw0gVyf6SUlnxeDbqiHPw= +github.com/Velocidex/WinPmem/go-winpmem v0.0.0-20251014141320-f59d776a3def/go.mod h1:HloPDQtxpV/iPxaKVE45+dz6DELiHZcBC1KFRlZtAtM= github.com/Velocidex/amsi v0.0.0-20250418124629-ea341d1aa3f2 h1:2cUc1SS+pldecJ6AH6vR/MSpGJRsdAn9a+7Dye9HDHk= github.com/Velocidex/amsi v0.0.0-20250418124629-ea341d1aa3f2/go.mod h1:1fYhBBGtaKu46Kpmkd2kvTi32zvgI91AusAW8BTiTAI= @@ -60,6 +60,6 @@ github.com/Velocidex/errors v0.0.0-20221019164655-9ace6bf61e26 h1:VwbeNpMRuS3bRieg7WLaSYIMaI8RjH/wGxd37oj6H1g= github.com/Velocidex/errors v0.0.0-20221019164655-9ace6bf61e26/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= -github.com/Velocidex/etw v0.0.0-20250314035532-6115b05b9430 h1:n4dBzJvfPLES9/XAMbBjxUeuuR1Abl/pFG0VdrlxZk0= -github.com/Velocidex/etw v0.0.0-20250314035532-6115b05b9430/go.mod h1:1flhaSAPAtB7fS7InVaBJxxmLttgWOlx7rXG6Sftg5U= +github.com/Velocidex/etw v0.0.0-20251027041548-6d97883fd588 h1:cP4Tk/yo4bqcTm3QC5CGc92WJvh/tS+sWGI681WBUZM= +github.com/Velocidex/etw v0.0.0-20251027041548-6d97883fd588/go.mod h1:VIXXclFpWN0pisSoz1obVWQvQCwqr60HmNWuYMB95Cs= github.com/Velocidex/file-rotatelogs v0.0.0-20211221020724-d12e4dae4e11 h1:pQY9p6hvmbFKXJg8suzGSG9/t8Ij9ece32GUFIdHgqg= github.com/Velocidex/file-rotatelogs v0.0.0-20211221020724-d12e4dae4e11/go.mod h1:Ya1f4Kowt2GC7gbnu1MbNncvI1Lp3i1plN2xLiETJfg= @@ -74,8 +74,6 @@ github.com/Velocidex/go-fat v0.0.0-20230923165230-3e6c4265297a h1:dWHPlB3C86vh+M5P14dZxF6Hh8o2/u8FTRF/bs2EM+Q= github.com/Velocidex/go-fat v0.0.0-20230923165230-3e6c4265297a/go.mod h1:g74FCv59tsVP48V2o1eyIK8aKbNKPLJIJ+HuiUPVc6E= -github.com/Velocidex/go-journalctl v0.0.0-20241004063153-cc1c858415bd h1:CSTW6zYoG1IFxaGM3N42wSwruigV1xZ4gNzjLgb2xIc= -github.com/Velocidex/go-journalctl v0.0.0-20241004063153-cc1c858415bd/go.mod h1:5WxXsCtLdEvnc4FsFa+QfMwOWYkfey3nlQbPssZWqjc= -github.com/Velocidex/go-journalctl v0.0.0-20250813052126-d39241ea8ef7 h1:xRVLqfsZYJO9LAPifPk9y/+IipfdT3LQVQZCSF56zTs= -github.com/Velocidex/go-journalctl v0.0.0-20250813052126-d39241ea8ef7/go.mod h1:5WxXsCtLdEvnc4FsFa+QfMwOWYkfey3nlQbPssZWqjc= +github.com/Velocidex/go-journalctl v0.0.0-20250902002606-881a5f66df10 h1:AGL0nv7O7LoRqdNwx1IZNmcacgC9W+ItMPJL4Vhy2gM= +github.com/Velocidex/go-journalctl v0.0.0-20250902002606-881a5f66df10/go.mod h1:5WxXsCtLdEvnc4FsFa+QfMwOWYkfey3nlQbPssZWqjc= github.com/Velocidex/go-magic v0.0.0-20250203094020-32f94b14f00f h1:KCDi0hKrkDrn0DI2L8cSMkrF0yWj57c6VIhAKmmQFV8= github.com/Velocidex/go-magic v0.0.0-20250203094020-32f94b14f00f/go.mod h1:2oVfOYRdtA0yuSZiN9ai8PRgxvkw6SLUlUXy1Sm76qk= @@ -103,6 +101,4 @@ github.com/Velocidex/sflags v0.3.1-0.20241126160332-cc1a5b66b8f1 h1:fLJ2AjY0dtDZEBhekp3bxyxGpWh5D/+NfOVlGXB5ROA= github.com/Velocidex/sflags v0.3.1-0.20241126160332-cc1a5b66b8f1/go.mod h1:UpFVihkMZWl2JRkVRiZYie0e2l7Ry+vjlCHCs6XVKGU= -github.com/Velocidex/sigma-go v0.0.0-20241025122940-1b771d3d57a9 h1:YavusWZ+svpybfVg8cKk9MuSyeI479a0EGJ07VGpSm8= -github.com/Velocidex/sigma-go v0.0.0-20241025122940-1b771d3d57a9/go.mod h1:ukLFs2t1+ud7MC4oN+zImhtTRP/eQHaDL3TwLs58uUA= github.com/Velocidex/sigma-go v0.0.0-20241113062227-c1c5ea4b5250 h1:GhiTVVoHNhb0mzUDgieUwjfJeEaUHCHIVvV/mHzLQOI= github.com/Velocidex/sigma-go v0.0.0-20241113062227-c1c5ea4b5250/go.mod h1:ukLFs2t1+ud7MC4oN+zImhtTRP/eQHaDL3TwLs58uUA= @@ -113,6 +109,8 @@ github.com/Velocidex/yaml/v2 v2.2.8 h1:GUrSy4SBJ6RjGt43k6MeBKtw2z/27gh4A3hfFmFY3No= github.com/Velocidex/yaml/v2 v2.2.8/go.mod h1:PlXIg/Pxmoja48C1vMHo7C5pauAZvLq/UEPOQ3DsjS4= -github.com/Velocidex/zip v0.0.0-20250102162034-1a0ec0ec569c h1:+/E/0rL46fcD0ykUWrY66JBxpjjksxN+ZnC596XgHIQ= -github.com/Velocidex/zip v0.0.0-20250102162034-1a0ec0ec569c/go.mod h1:1p8CU2cp64BG4334sKzhuyH/vm3k1OXEdeBCwYTssAs= +github.com/Velocidex/yara-x-go v0.0.0-20251010010632-d8eaad9c539c h1:3X4jyfzsTuOhiGaDXPu+WOrwRxDx2gk1akUdnpb4NHE= +github.com/Velocidex/yara-x-go v0.0.0-20251010010632-d8eaad9c539c/go.mod h1:nCopKG7AZZpc0mVgW2+z2i+CVYK1yIEl6YFJKkYNg4I= +github.com/Velocidex/zip v0.0.0-20251027040802-582e676739bd h1:l92KJwgIHiEVKTLgCk1nwvvAxNEMo8sbH+wa6WFhuqw= +github.com/Velocidex/zip v0.0.0-20251027040802-582e676739bd/go.mod h1:1p8CU2cp64BG4334sKzhuyH/vm3k1OXEdeBCwYTssAs= github.com/VirusTotal/gyp v0.9.1-0.20231202132633-bb35dbf177a6 h1:GmGcpAb8o8VL5tZS+TSZL2V/jbBVVdsx4SFyG+S/7nY= github.com/VirusTotal/gyp v0.9.1-0.20231202132633-bb35dbf177a6/go.mod h1:nmcW15dQ1657PmMcG9X/EZmp6rTQsyo9g8r6Cz1/AHc= @@ -135,6 +133,6 @@ github.com/alecthomas/repr v0.1.1/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/alecthomas/repr v0.3.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= -github.com/alecthomas/repr v0.5.1 h1:E3G4t2QbHTSNpPKBgMTln5KLkZHLOcU7r37J4pXBuIg= -github.com/alecthomas/repr v0.5.1/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= +github.com/alecthomas/repr v0.5.2 h1:SU73FTI9D1P5UNtvseffFSGmdNci/O6RsqzeXJtP0Qs= +github.com/alecthomas/repr v0.5.2/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -240,4 +238,8 @@ github.com/clbanning/mxj v1.8.4/go.mod h1:BVjHeAH+rl9rs6f+QIpeRl0tfu10SXn1pUSa5PVGJng= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs= +github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA= +github.com/clipperhouse/uax29/v2 v2.3.0 h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4= +github.com/clipperhouse/uax29/v2 v2.3.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/coreos/go-oidc/v3 v3.11.0 h1:Ia3MxdwpSw702YW0xgfmP1GVCMA9aEFWu12XUZ3/OtI= @@ -301,4 +303,6 @@ github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE= github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA= +github.com/go-json-experiment/json v0.0.0-20250910080747-cc2cfa0554c3 h1:02WINGfSX5w0Mn+F28UyRoSt9uvMhKguwWMlOAh6U/0= +github.com/go-json-experiment/json v0.0.0-20250910080747-cc2cfa0554c3/go.mod h1:uNVvRXArCGbZ508SxYYTC5v1JWoz2voff5pm25jU1Ok= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= @@ -313,4 +317,6 @@ github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/go-stack/stack v1.6.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= +github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= github.com/godzie44/go-uring v0.0.0-20220926161041-69611e8b13d5 h1:5zELAgnSz0gqmr4Q5DWCoOzNHoeBAxVUXB7LS1eG+sw= github.com/godzie44/go-uring v0.0.0-20220926161041-69611e8b13d5/go.mod h1:ermjEDUoT/fS+3Ona5Vd6t6mZkw1eHp99ILO5jGRBkM= @@ -365,6 +371,7 @@ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -441,5 +448,4 @@ github.com/jackwakefield/gopac v1.0.2 h1:TdHTGtC/kMc5kyYw7PEO5kqAHxcpuU4RFY4ztfg4nAM= github.com/jackwakefield/gopac v1.0.2/go.mod h1:yR1sfJXcndScUFYPx7Xqxj7bkNlCWw9AMmuJFMHLXm8= -github.com/jawher/mow.cli v1.1.0/go.mod h1:aNaQlc7ozF3vw6IJ2dHjp2ZFiA4ozMIYY6PyuRJwlUg= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= @@ -456,4 +462,10 @@ github.com/juju/ratelimit v1.0.1 h1:+7AIFJVQ0EQgq/K9+0Krm7m530Du7tIz0METWzN0RgY= github.com/juju/ratelimit v1.0.1/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk= +github.com/kaptinlin/go-i18n v0.2.0 h1:8iwjAERQbCVF78c3HxC4MxUDxDRFvQVQlMDvlsO43hU= +github.com/kaptinlin/go-i18n v0.2.0/go.mod h1:gRHEMrTHtQLsAFwulPbJG71TwHjXxkagn88O8FI8FuA= +github.com/kaptinlin/jsonschema v0.5.2 h1:ipUBEv1/RnT+ErwdqXZ3Xtwkwp6uqp/Q9lFILrwhUfc= +github.com/kaptinlin/jsonschema v0.5.2/go.mod h1:HuWb90460GwFxRe0i9Ni3Z7YXwkjpqjeccWTB9gTZZE= +github.com/kaptinlin/messageformat-go v0.4.6 h1:57DUC9en40mGZR7MvqOS+5EYogAl465fjo+loAA1KPg= +github.com/kaptinlin/messageformat-go v0.4.6/go.mod h1:r0PH7FsxJX8jS/n6LAYZon5w3X+yfCLUrquqYd2H7ks= github.com/karrick/godirwalk v1.17.0 h1:b4kY7nqDdioR/6qnbHQyDvmA17u5G1cZ6J+CZXwSWoI= github.com/karrick/godirwalk v1.17.0/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= @@ -529,6 +541,7 @@ github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= -github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw= +github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM= github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= @@ -587,5 +600,8 @@ github.com/paulmach/orb v0.10.0/go.mod h1:5mULz1xQfs3bmQm63QEJA6lNGujuRafwA5S/EnuLaLU= github.com/paulmach/protoscan v0.2.1/go.mod h1:SpcSwydNLrxUGSDvXvO0P7g7AuhJ7lcKfDlhJCDw2gY= +github.com/pelletier/go-toml v1.0.1-0.20170904195809-1d6b12b7cb29 h1:6P7XZEBu/ZWizC/liUX4UYm4nEAACofmSkOzY39RBxM= github.com/pelletier/go-toml v1.0.1-0.20170904195809-1d6b12b7cb29/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= +github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw= github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0= @@ -645,5 +661,4 @@ github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= @@ -657,5 +672,4 @@ github.com/spf13/viper v1.0.0/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -675,6 +689,6 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= @@ -688,6 +702,6 @@ github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= -github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= -github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/ulikunitz/xz v0.5.15 h1:9DNdB5s+SgV3bQ2ApL10xRc35ck0DuIX/isZvIk+ubY= +github.com/ulikunitz/xz v0.5.15/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= @@ -782,6 +796,6 @@ golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg= -golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ= +golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U= +golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -827,6 +841,6 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= -golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -843,9 +857,7 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200413165638-669c56c373c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200720211630-cb9d2d5c5666/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -864,7 +876,6 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= -golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= +golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -886,6 +897,6 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= +golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= golang.org/x/time v0.0.0-20170424234030-8be79e1e0910/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= @@ -952,6 +963,6 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.36.7 h1:IgrO7UwFQGJdRNXH/sQux4R1Dj1WAKcLElzeeRaXV2A= -google.golang.org/protobuf v1.36.7/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= +google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -998,5 +1009,4 @@ software.sslmate.com/src/go-pkcs12 v0.2.0 h1:nlFkj7bTysH6VkC4fGphtjXRbezREPgrHuJG20hBGPE= software.sslmate.com/src/go-pkcs12 v0.2.0/go.mod h1:23rNcYsMabIc1otwLpTkCCPwUq6kQsTyowttG/as0kQ= -www.velocidex.com/golang/binparsergen v0.1.0/go.mod h1:UC43Ecj0mjsidlClTYZ3H4dXdyv7CVI0HsYi4yY3qtc= www.velocidex.com/golang/binparsergen v0.1.1-0.20220107080050-ae6122c5ed14/go.mod h1:Q/J/huOyH6IlY2aShigY1CnZnw5EO0+FZJgnGEBrT5Q= www.velocidex.com/golang/binparsergen v0.1.1-0.20240404114946-8f66c7cf586e h1:uf1AsYiIzUMJMIdFsVdrIw/BjrGzZbrsnz9xmeZmlYU= @@ -1008,14 +1018,14 @@ www.velocidex.com/golang/go-ntfs v0.2.1-0.20250322152626-3c09d909d740 h1:MV9imIM3SmpegCd8G3JSM18fVzS7g7JZQXpJ9EKqo7s= www.velocidex.com/golang/go-ntfs v0.2.1-0.20250322152626-3c09d909d740/go.mod h1:4MSO8W9iNMXyBpjSpxApWfMjJUb9IWFD2Yis5JPZaSY= -www.velocidex.com/golang/go-pe v0.1.1-0.20250101153735-7a925ba8334b h1:hOxQYDyETh4wdnCbM9Il4X+6LwonGdLnsoznqvzw48A= -www.velocidex.com/golang/go-pe v0.1.1-0.20250101153735-7a925ba8334b/go.mod h1:agYwYzeeytVtdwkRrvxZAjgIA8SCeM/Tg7Ym2/jBwmA= -www.velocidex.com/golang/go-prefetch v0.0.0-20250529114725-e36ea8a283e2 h1:a7Jyt6sgBXAySUCYOZw4yiczvPDaK6WaWwqs6GjOBeg= -www.velocidex.com/golang/go-prefetch v0.0.0-20250529114725-e36ea8a283e2/go.mod h1:UNIUmQhflpSTt7TH4o/6O/GiMCjSzIALXe9/zzTKFCw= +www.velocidex.com/golang/go-pe v0.1.1-0.20251015235828-0a2958753ebf h1:eIn54VdPmWJ7Nlz62MbNOVZI+tmW9Se1YeOa56slmVA= +www.velocidex.com/golang/go-pe v0.1.1-0.20251015235828-0a2958753ebf/go.mod h1:agYwYzeeytVtdwkRrvxZAjgIA8SCeM/Tg7Ym2/jBwmA= +www.velocidex.com/golang/go-prefetch v0.0.0-20251027080408-85407689d0cb h1:GW6agTdjRKf0mO5ZAivSo09TwqHb2sPoBCXLGSoEUE4= +www.velocidex.com/golang/go-prefetch v0.0.0-20251027080408-85407689d0cb/go.mod h1:eAhul/F2+kIBGGEsf8xVq68O5kKwg85x2Rg2I65uVwU= www.velocidex.com/golang/oleparse v0.0.0-20250312121321-f7c2b4ec0959 h1:qJlm0T616aOJtwD3dWUcYz3cldYyO3/tWB9EGv32ibU= www.velocidex.com/golang/oleparse v0.0.0-20250312121321-f7c2b4ec0959/go.mod h1:wjOPwI3Vy6TP0AhF6NjjXV/to93E5A1tjA04liHvf5E= www.velocidex.com/golang/regparser v0.0.0-20250203141505-31e704a67ef7 h1:BMX/37sYwX+8JhHt+YNbPfbx7dXG1w1L1mXonNBtjt0= www.velocidex.com/golang/regparser v0.0.0-20250203141505-31e704a67ef7/go.mod h1:pxSECT5mWM3goJ4sxB4HCJNKnKqiAlpyT8XnvBwkLGU= -www.velocidex.com/golang/vfilter v0.0.0-20250822163628-cf253ab459bc h1:RyosmyItclBcNYoB30lqSpkF4c9gsZpb8T8LWkauVRo= -www.velocidex.com/golang/vfilter v0.0.0-20250822163628-cf253ab459bc/go.mod h1:5g1ExLSKP3TpT1cAF6bLzVWL8opGzTifzVjmMAdDnFE= +www.velocidex.com/golang/vfilter v0.0.0-20250915140904-eb07b966bcef h1:KDspJFRFZXr46txPO/ZPNlHolu4J2/Ngbrxe9F1lz9I= +www.velocidex.com/golang/vfilter v0.0.0-20250915140904-eb07b966bcef/go.mod h1:5g1ExLSKP3TpT1cAF6bLzVWL8opGzTifzVjmMAdDnFE= www.velocidex.com/golang/vtypes v0.0.0-20250802153006-821cec8fd392 h1:+FrLvUI9WPVcVsIvsZMtmPVwOcutLbbO1WWXxRFm2es= www.velocidex.com/golang/vtypes v0.0.0-20250802153006-821cec8fd392/go.mod h1:tjaJNlBWbvH4cEMrEu678CFR2hrtcdyPINIpRxrOh4U= Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor: ab0x.go diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/package-lock.json /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/package-lock.json --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/package-lock.json 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/package-lock.json 2025-11-01 15:52:20.000000000 +0000 @@ -10,23 +10,23 @@ "hasInstallScript": true, "dependencies": { - "@babel/runtime": "^7.28.2", + "@babel/runtime": "^7.28.4", "@fortawesome/fontawesome-svg-core": "6.7.2", "@fortawesome/free-regular-svg-icons": "6.7.2", "@fortawesome/free-solid-svg-icons": "^6.7.2", - "@fortawesome/react-fontawesome": "^0.2.3", + "@fortawesome/react-fontawesome": "0.2.6", "@popperjs/core": "^2.11.8", - "ace-builds": "1.43.2", - "axios": ">=1.11.0", + "ace-builds": "1.43.3", + "axios": ">=1.12.2", "axios-retry": "3.9.1", - "bootstrap": "5.3.7", + "bootstrap": "5.3.8", "classnames": "^2.5.1", "csv-parse": "4.16.3", "csv-stringify": "5.6.5", - "dompurify": "3.2.6", + "dompurify": "3.2.7", "env-cmd": "^10.1.0", "hosted-git-info": "^2.8.9", "html-react-parser": "^0.14.3", "http-proxy-middleware": "^2.0.9", - "humanize-duration": "^3.33.0", + "humanize-duration": "^3.33.1", "lodash": "^4.17.21", "markdown-it": "14.1.0", @@ -34,5 +34,5 @@ "moment-timezone": "0.6.0", "npm-watch": "^0.13.0", - "patch-package": "8.0.0", + "patch-package": "^8.0.1", "path-browserify": "1.0.1", "prop-types": "^15.8.1", @@ -55,5 +55,5 @@ "sprintf-js": "1.1.3", "url-parse": "^1.5.10", - "webpack": "5.100.2" + "webpack": "^5.102.0" }, "devDependencies": { @@ -64,5 +64,5 @@ "@babel/preset-react": "^7.18.6", "@testing-library/react": "12", - "@vitejs/plugin-react": "^3.0.0", + "@vitejs/plugin-react": "^5.0.2", "babel-jest": "30.0.0-beta.3", "dotenv": "^8.6.0", @@ -74,22 +74,9 @@ "jest": "29.7.0", "jest-environment-jsdom": "30.0.0-beta.3", - "vite": "^4.5.14", + "vite": "^7.1.11", "vite-plugin-compression": "^0.5.1", "vite-plugin-eslint": "1.8.1" } }, - "node_modules/@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.1.0", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@asamuzakjp/css-color": { "version": "3.2.0", @@ -112,11 +99,11 @@ }, "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", - "license": "MIT", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", "dependencies": { - "@babel/highlight": "^7.24.7", - "picocolors": "^1.0.0" + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" }, "engines": { @@ -125,9 +112,8 @@ }, "node_modules/@babel/compat-data": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.2.tgz", - "integrity": "sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.4.tgz", + "integrity": "sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" @@ -135,20 +121,19 @@ }, "node_modules/@babel/core": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", - "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.4.tgz", + "integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==", "dev": true, - "license": "MIT", "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.0", - "@babel/helper-compilation-targets": "^7.25.2", - "@babel/helper-module-transforms": "^7.25.2", - "@babel/helpers": "^7.25.0", - "@babel/parser": "^7.25.0", - "@babel/template": "^7.25.0", - "@babel/traverse": "^7.25.2", - "@babel/types": "^7.25.2", + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.4", + "@babel/parser": "^7.28.4", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.4", + "@babel/types": "^7.28.4", + "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", @@ -190,12 +175,13 @@ }, "node_modules/@babel/generator": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.0.tgz", - "integrity": "sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==", - "dependencies": { - "@babel/types": "^7.25.0", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz", + "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==", + "dependencies": { + "@babel/parser": "^7.28.3", + "@babel/types": "^7.28.2", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" }, "engines": { @@ -203,17 +189,4 @@ } }, - "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@babel/helper-annotate-as-pure": { "version": "7.24.7", @@ -243,13 +216,12 @@ }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz", - "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==", + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.25.2", - "@babel/helper-validator-option": "^7.24.8", - "browserslist": "^4.23.1", + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" @@ -313,4 +285,12 @@ } }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-member-expression-to-functions": { "version": "7.24.8", @@ -327,11 +307,10 @@ }, "node_modules/@babel/helper-module-imports": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", - "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", - "license": "MIT", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" }, "engines": { @@ -340,13 +319,12 @@ }, "node_modules/@babel/helper-module-transforms": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz", - "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", + "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", "dev": true, "dependencies": { - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7", - "@babel/traverse": "^7.25.2" + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.28.3" }, "engines": { @@ -370,7 +348,7 @@ }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", - "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", "dev": true, "engines": { @@ -440,8 +418,7 @@ }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", - "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", - "license": "MIT", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "engines": { "node": ">=6.9.0" @@ -449,8 +426,7 @@ }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", - "license": "MIT", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", "engines": { "node": ">=6.9.0" @@ -458,9 +434,8 @@ }, "node_modules/@babel/helper-validator-option": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", - "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" @@ -482,27 +457,11 @@ }, "node_modules/@babel/helpers": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.0.tgz", - "integrity": "sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/template": "^7.25.0", - "@babel/types": "^7.25.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" }, "engines": { @@ -511,9 +470,9 @@ }, "node_modules/@babel/parser": { - "version": "7.25.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.3.tgz", - "integrity": "sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz", + "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==", "dependencies": { - "@babel/types": "^7.25.2" + "@babel/types": "^7.28.4" }, "bin": { @@ -1709,10 +1668,10 @@ }, "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.21.0.tgz", - "integrity": "sha512-f/Eq+79JEu+KUANFks9UZCcvydOOGMgF7jBrcwjHa5jTZD8JivnhCJYvmlhR/WTXBWonDExPoW0eO/CR4QJirA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { @@ -1724,10 +1683,10 @@ }, "node_modules/@babel/plugin-transform-react-jsx-source": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.19.6.tgz", - "integrity": "sha512-RpAi004QyMNisst/pvSanoRdJ4q+jMCWyk9zdw/CyLB9j8RXEahodR6l2GyttDRyEVWZtbN+TpLiHJ3t34LbsQ==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { @@ -2120,7 +2079,7 @@ }, "node_modules/@babel/runtime": { - "version": "7.28.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.2.tgz", - "integrity": "sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", + "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", "license": "MIT", "engines": { @@ -2129,11 +2088,11 @@ }, "node_modules/@babel/template": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", - "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.25.0", - "@babel/types": "^7.25.0" + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" }, "engines": { @@ -2142,15 +2101,15 @@ }, "node_modules/@babel/traverse": { - "version": "7.25.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.3.tgz", - "integrity": "sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==", - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.0", - "@babel/parser": "^7.25.3", - "@babel/template": "^7.25.0", - "@babel/types": "^7.25.2", - "debug": "^4.3.1", - "globals": "^11.1.0" + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.4.tgz", + "integrity": "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.3", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.4", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4", + "debug": "^4.3.1" }, "engines": { @@ -2159,11 +2118,10 @@ }, "node_modules/@babel/types": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.2.tgz", - "integrity": "sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz", + "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", "dependencies": { - "@babel/helper-string-parser": "^7.24.8", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" }, "engines": { @@ -2376,8 +2334,24 @@ "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==" }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.9.tgz", + "integrity": "sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@esbuild/android-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", - "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.9.tgz", + "integrity": "sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==", "cpu": [ "arm" @@ -2389,11 +2363,11 @@ ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", - "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.9.tgz", + "integrity": "sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==", "cpu": [ "arm64" @@ -2405,11 +2379,11 @@ ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", - "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.9.tgz", + "integrity": "sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==", "cpu": [ "x64" @@ -2421,11 +2395,11 @@ ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", - "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.9.tgz", + "integrity": "sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==", "cpu": [ "arm64" @@ -2437,11 +2411,11 @@ ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", - "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.9.tgz", + "integrity": "sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==", "cpu": [ "x64" @@ -2453,11 +2427,11 @@ ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", - "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.9.tgz", + "integrity": "sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==", "cpu": [ "arm64" @@ -2469,11 +2443,11 @@ ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", - "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.9.tgz", + "integrity": "sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==", "cpu": [ "x64" @@ -2485,11 +2459,11 @@ ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", - "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.9.tgz", + "integrity": "sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==", "cpu": [ "arm" @@ -2501,11 +2475,11 @@ ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", - "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.9.tgz", + "integrity": "sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==", "cpu": [ "arm64" @@ -2517,11 +2491,11 @@ ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", - "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.9.tgz", + "integrity": "sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==", "cpu": [ "ia32" @@ -2533,11 +2507,11 @@ ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", - "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.9.tgz", + "integrity": "sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==", "cpu": [ "loong64" @@ -2549,11 +2523,11 @@ ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", - "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.9.tgz", + "integrity": "sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==", "cpu": [ "mips64el" @@ -2565,11 +2539,11 @@ ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", - "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.9.tgz", + "integrity": "sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==", "cpu": [ "ppc64" @@ -2581,11 +2555,11 @@ ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", - "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.9.tgz", + "integrity": "sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==", "cpu": [ "riscv64" @@ -2597,11 +2571,11 @@ ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", - "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.9.tgz", + "integrity": "sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==", "cpu": [ "s390x" @@ -2613,11 +2587,11 @@ ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", - "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.9.tgz", + "integrity": "sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==", "cpu": [ "x64" @@ -2629,11 +2603,27 @@ ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.9.tgz", + "integrity": "sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", - "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.9.tgz", + "integrity": "sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==", "cpu": [ "x64" @@ -2645,11 +2635,27 @@ ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.9.tgz", + "integrity": "sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", - "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.9.tgz", + "integrity": "sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==", "cpu": [ "x64" @@ -2661,11 +2667,27 @@ ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.9.tgz", + "integrity": "sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", - "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.9.tgz", + "integrity": "sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==", "cpu": [ "x64" @@ -2677,11 +2699,11 @@ ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", - "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.9.tgz", + "integrity": "sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==", "cpu": [ "arm64" @@ -2693,11 +2715,11 @@ ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", - "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.9.tgz", + "integrity": "sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==", "cpu": [ "ia32" @@ -2709,11 +2731,11 @@ ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", - "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.9.tgz", + "integrity": "sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==", "cpu": [ "x64" @@ -2725,5 +2747,5 @@ ], "engines": { - "node": ">=12" + "node": ">=18" } }, @@ -2875,7 +2897,7 @@ }, "node_modules/@fortawesome/react-fontawesome": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.3.tgz", - "integrity": "sha512-HlJco8RDY8NrzFVjy23b/7mNS4g9NegcrBG3n7jinwpc2x/AmSVk53IhWniLYM4szYLxRAFTAGwGn0EIlclDeQ==", + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.6.tgz", + "integrity": "sha512-mtBFIi1UsYQo7rYonYFkjgYKGoL8T+fEH6NGUpvuqtY3ytMsAoDaPo5rk25KuMtKDipY4bGYM/CkmCHA1N3FUg==", "license": "MIT", "dependencies": { @@ -4031,14 +4053,20 @@ }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", "dev": true, "dependencies": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" - }, - "engines": { - "node": ">=6.0.0" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" } }, @@ -4051,12 +4079,4 @@ } }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@jridgewell/source-map": { "version": "0.3.6", @@ -4068,26 +4088,13 @@ } }, - "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "version": "0.3.30", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.30.tgz", + "integrity": "sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -4216,4 +4223,10 @@ } }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.34", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.34.tgz", + "integrity": "sha512-LyAREkZHP5pMom7c24meKmJCdhf2hEyvam2q0unr3or9ydwDL+DJ8chTF6Av/RFPb3rH8UFBdMzO5MxTZW97oA==", + "dev": true + }, "node_modules/@rollup/pluginutils": { "version": "4.2.1", @@ -4229,4 +4242,277 @@ } }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.50.1.tgz", + "integrity": "sha512-HJXwzoZN4eYTdD8bVV22DN8gsPCAj3V20NHKOs8ezfXanGpmVPR7kalUHd+Y31IJp9stdB87VKPFbsGY3H/2ag==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.50.1.tgz", + "integrity": "sha512-PZlsJVcjHfcH53mOImyt3bc97Ep3FJDXRpk9sMdGX0qgLmY0EIWxCag6EigerGhLVuL8lDVYNnSo8qnTElO4xw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.50.1.tgz", + "integrity": "sha512-xc6i2AuWh++oGi4ylOFPmzJOEeAa2lJeGUGb4MudOtgfyyjr4UPNK+eEWTPLvmPJIY/pgw6ssFIox23SyrkkJw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.50.1.tgz", + "integrity": "sha512-2ofU89lEpDYhdLAbRdeyz/kX3Y2lpYc6ShRnDjY35bZhd2ipuDMDi6ZTQ9NIag94K28nFMofdnKeHR7BT0CATw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.50.1.tgz", + "integrity": "sha512-wOsE6H2u6PxsHY/BeFHA4VGQN3KUJFZp7QJBmDYI983fgxq5Th8FDkVuERb2l9vDMs1D5XhOrhBrnqcEY6l8ZA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.50.1.tgz", + "integrity": "sha512-A/xeqaHTlKbQggxCqispFAcNjycpUEHP52mwMQZUNqDUJFFYtPHCXS1VAG29uMlDzIVr+i00tSFWFLivMcoIBQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.50.1.tgz", + "integrity": "sha512-54v4okehwl5TaSIkpp97rAHGp7t3ghinRd/vyC1iXqXMfjYUTm7TfYmCzXDoHUPTTf36L8pr0E7YsD3CfB3ZDg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.50.1.tgz", + "integrity": "sha512-p/LaFyajPN/0PUHjv8TNyxLiA7RwmDoVY3flXHPSzqrGcIp/c2FjwPPP5++u87DGHtw+5kSH5bCJz0mvXngYxw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.50.1.tgz", + "integrity": "sha512-2AbMhFFkTo6Ptna1zO7kAXXDLi7H9fGTbVaIq2AAYO7yzcAsuTNWPHhb2aTA6GPiP+JXh85Y8CiS54iZoj4opw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.50.1.tgz", + "integrity": "sha512-Cgef+5aZwuvesQNw9eX7g19FfKX5/pQRIyhoXLCiBOrWopjo7ycfB292TX9MDcDijiuIJlx1IzJz3IoCPfqs9w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.50.1.tgz", + "integrity": "sha512-RPhTwWMzpYYrHrJAS7CmpdtHNKtt2Ueo+BlLBjfZEhYBhK00OsEqM08/7f+eohiF6poe0YRDDd8nAvwtE/Y62Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.50.1.tgz", + "integrity": "sha512-eSGMVQw9iekut62O7eBdbiccRguuDgiPMsw++BVUg+1K7WjZXHOg/YOT9SWMzPZA+w98G+Fa1VqJgHZOHHnY0Q==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.50.1.tgz", + "integrity": "sha512-S208ojx8a4ciIPrLgazF6AgdcNJzQE4+S9rsmOmDJkusvctii+ZvEuIC4v/xFqzbuP8yDjn73oBlNDgF6YGSXQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.50.1.tgz", + "integrity": "sha512-3Ag8Ls1ggqkGUvSZWYcdgFwriy2lWo+0QlYgEFra/5JGtAd6C5Hw59oojx1DeqcA2Wds2ayRgvJ4qxVTzCHgzg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.50.1.tgz", + "integrity": "sha512-t9YrKfaxCYe7l7ldFERE1BRg/4TATxIg+YieHQ966jwvo7ddHJxPj9cNFWLAzhkVsbBvNA4qTbPVNsZKBO4NSg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.50.1.tgz", + "integrity": "sha512-MCgtFB2+SVNuQmmjHf+wfI4CMxy3Tk8XjA5Z//A0AKD7QXUYFMQcns91K6dEHBvZPCnhJSyDWLApk40Iq/H3tA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.50.1.tgz", + "integrity": "sha512-nEvqG+0jeRmqaUMuwzlfMKwcIVffy/9KGbAGyoa26iu6eSngAYQ512bMXuqqPrlTyfqdlB9FVINs93j534UJrg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.50.1.tgz", + "integrity": "sha512-RDsLm+phmT3MJd9SNxA9MNuEAO/J2fhW8GXk62G/B4G7sLVumNFbRwDL6v5NrESb48k+QMqdGbHgEtfU0LCpbA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.50.1.tgz", + "integrity": "sha512-hpZB/TImk2FlAFAIsoElM3tLzq57uxnGYwplg6WDyAxbYczSi8O2eQ+H2Lx74504rwKtZ3N2g4bCUkiamzS6TQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.50.1.tgz", + "integrity": "sha512-SXjv8JlbzKM0fTJidX4eVsH+Wmnp0/WcD8gJxIZyR6Gay5Qcsmdbi9zVtnbkGPG8v2vMR1AD06lGWy5FLMcG7A==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.50.1.tgz", + "integrity": "sha512-StxAO/8ts62KZVRAm4JZYq9+NqNsV7RvimNK+YM7ry//zebEH6meuugqW/P5OFUCjyQgui+9fUxT6d5NShvMvA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@rushstack/eslint-patch": { "version": "1.10.4", @@ -4588,7 +4874,10 @@ }, "node_modules/@types/node": { - "version": "18.14.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.2.tgz", - "integrity": "sha512-1uEQxww3DaghA0RxqHx0O0ppVlo43pJhepY51OxuQIKHpjbnYLA7vcdwioNPzIqmC2u3I/dmylcqjlh0e7AyUA==" + "version": "24.3.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.3.1.tgz", + "integrity": "sha512-3vXmQDXy+woz+gnrTvuvNrPzekOi+Ds0ReMxw0LzBiK3a+1k0kQn9f2NWk+lgD4rJehFUmYy2gMhJ2ZI+7YP9g==", + "dependencies": { + "undici-types": "~7.10.0" + } }, "node_modules/@types/parse-json": { @@ -4943,20 +5232,21 @@ }, "node_modules/@vitejs/plugin-react": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-3.1.0.tgz", - "integrity": "sha512-AfgcRL8ZBhAlc3BFdigClmTUMISmmzHn7sB2h9U1odvc5U/MjWXsAaz18b/WoppUTDBzxOJwo2VdClfUcItu9g==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.0.2.tgz", + "integrity": "sha512-tmyFgixPZCx2+e6VO9TNITWcCQl8+Nl/E8YbAyPVv85QCc7/A3JrdfG2A8gIzvVhWuzMOVrFW1aReaNxrI6tbw==", "dev": true, "dependencies": { - "@babel/core": "^7.20.12", - "@babel/plugin-transform-react-jsx-self": "^7.18.6", - "@babel/plugin-transform-react-jsx-source": "^7.19.6", - "magic-string": "^0.27.0", - "react-refresh": "^0.14.0" + "@babel/core": "^7.28.3", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.34", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" }, "engines": { - "node": "^14.18.0 || >=16.0.0" + "node": "^20.19.0 || >=22.12.0" }, "peerDependencies": { - "vite": "^4.1.0-beta.0" + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, @@ -5130,7 +5420,7 @@ }, "node_modules/ace-builds": { - "version": "1.43.2", - "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.43.2.tgz", - "integrity": "sha512-3wzJUJX0RpMc03jo0V8Q3bSb/cKPnS7Nqqw8fVHsCCHweKMiTIxT3fP46EhjmVy6MCuxwP801ere+RW245phGw==", + "version": "1.43.3", + "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.43.3.tgz", + "integrity": "sha512-MCl9rALmXwIty/4Qboijo/yNysx1r6hBTzG+6n/TiOm5LFhZpEvEIcIITPFiEOEFDfgBOEmxu+a4f54LEFM6Sg==", "license": "BSD-3-Clause" }, @@ -5268,16 +5558,4 @@ } }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/anymatch": { "version": "3.1.3", @@ -5394,12 +5672,4 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/available-typed-arrays": { "version": "1.0.5", @@ -5424,7 +5694,8 @@ }, "node_modules/axios": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.11.0.tgz", - "integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz", + "integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==", + "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", @@ -5979,4 +6250,13 @@ } }, + "node_modules/babel-preset-react-app/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/balanced-match": { "version": "1.0.2", @@ -5984,4 +6264,13 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "node_modules/baseline-browser-mapping": { + "version": "2.8.20", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.20.tgz", + "integrity": "sha512-JMWsdF+O8Orq3EMukbUN1QfbLK9mX2CkUmQBcW2T0s8OmdAUL5LLM/6wFwSrqXzlXB13yhyK9gTKS1rIizOduQ==", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, "node_modules/batch-processor": { "version": "1.0.0", @@ -5998,7 +6287,7 @@ }, "node_modules/bootstrap": { - "version": "5.3.7", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.7.tgz", - "integrity": "sha512-7KgiD8UHjfcPBHEpDNg+zGz8L3LqR3GVwqZiBRFX04a1BCArZOz1r2kjly2HQ0WokqTO0v1nF+QAt8dsW4lKlw==", + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.8.tgz", + "integrity": "sha512-HP1SZDqaLDPwsNiqRqi5NcP0SSXciX2s9E+RyqJIIqGo+vJeN5AJVM98CXmW/Wux0nQ5L7jeWUdplCEf0Ee+tg==", "funding": [ { @@ -6038,7 +6327,7 @@ }, "node_modules/browserslist": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", - "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", + "version": "4.27.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.27.0.tgz", + "integrity": "sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw==", "funding": [ { @@ -6057,8 +6346,9 @@ "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001669", - "electron-to-chromium": "^1.5.41", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.1" + "baseline-browser-mapping": "^2.8.19", + "caniuse-lite": "^1.0.30001751", + "electron-to-chromium": "^1.5.238", + "node-releases": "^2.0.26", + "update-browserslist-db": "^1.1.4" }, "bin": { @@ -6131,7 +6421,7 @@ }, "node_modules/caniuse-lite": { - "version": "1.0.30001721", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001721.tgz", - "integrity": "sha512-cOuvmUVtKrtEaoKiO0rSc29jcjwMwX5tOHDy4MgVFEWiUXj4uBMJkwI8MDySkgXidpMiHUcviogAvFi4pA2hDQ==", + "version": "1.0.30001751", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001751.tgz", + "integrity": "sha512-A0QJhug0Ly64Ii3eIqHu5X51ebln3k4yTUkY1j8drqpWHVreg/VLijN48cZ1bYPiqOQuqpkIKnzr/Ul8V+p6Cw==", "funding": [ { @@ -6147,19 +6437,6 @@ "url": "https://github.com/sponsors/ai" } - ] - }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } + ], + "license": "CC-BY-4.0" }, "node_modules/char-regex": { @@ -6280,19 +6557,4 @@ "dev": true }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "license": "MIT" - }, "node_modules/combined-stream": { "version": "1.0.8", @@ -6358,4 +6620,12 @@ } }, + "node_modules/cosmiconfig/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + }, "node_modules/create-jest": { "version": "29.7.0", @@ -6854,7 +7124,7 @@ }, "node_modules/dompurify": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.6.tgz", - "integrity": "sha512-/2GogDQlohXPZe6D6NOgQvXLPSYBqIWMnZ8zzOhn09REE4eyAzb+Hed3jhoM9OkuaJ8P6ZGTTVWQKAi8ieIzfQ==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.7.tgz", + "integrity": "sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==", "license": "(MPL-2.0 OR Apache-2.0)", "optionalDependencies": { @@ -6894,7 +7164,7 @@ }, "node_modules/electron-to-chromium": { - "version": "1.5.71", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.71.tgz", - "integrity": "sha512-dB68l59BI75W1BUGVTAEJy45CEVuEGy9qPVVQ8pnHyHMn36PLPPoE1mjLH+lo9rKulO3HC2OhbACI/8tCqJBcA==", + "version": "1.5.240", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.240.tgz", + "integrity": "sha512-OBwbZjWgrCOH+g6uJsA2/7Twpas2OlepS9uvByJjR2datRDuKGYeD+nP8lBBks2qnB7bGJNHDUx7c/YLaT3QMQ==", "license": "ISC" }, @@ -7111,7 +7381,7 @@ }, "node_modules/esbuild": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", - "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz", + "integrity": "sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==", "dev": true, "hasInstallScript": true, @@ -7120,29 +7390,33 @@ }, "engines": { - "node": ">=12" + "node": ">=18" }, "optionalDependencies": { - "@esbuild/android-arm": "0.18.20", - "@esbuild/android-arm64": "0.18.20", - "@esbuild/android-x64": "0.18.20", - "@esbuild/darwin-arm64": "0.18.20", - "@esbuild/darwin-x64": "0.18.20", - "@esbuild/freebsd-arm64": "0.18.20", - "@esbuild/freebsd-x64": "0.18.20", - "@esbuild/linux-arm": "0.18.20", - "@esbuild/linux-arm64": "0.18.20", - "@esbuild/linux-ia32": "0.18.20", - "@esbuild/linux-loong64": "0.18.20", - "@esbuild/linux-mips64el": "0.18.20", - "@esbuild/linux-ppc64": "0.18.20", - "@esbuild/linux-riscv64": "0.18.20", - "@esbuild/linux-s390x": "0.18.20", - "@esbuild/linux-x64": "0.18.20", - "@esbuild/netbsd-x64": "0.18.20", - "@esbuild/openbsd-x64": "0.18.20", - "@esbuild/sunos-x64": "0.18.20", - "@esbuild/win32-arm64": "0.18.20", - "@esbuild/win32-ia32": "0.18.20", - "@esbuild/win32-x64": "0.18.20" + "@esbuild/aix-ppc64": "0.25.9", + "@esbuild/android-arm": "0.25.9", + "@esbuild/android-arm64": "0.25.9", + "@esbuild/android-x64": "0.25.9", + "@esbuild/darwin-arm64": "0.25.9", + "@esbuild/darwin-x64": "0.25.9", + "@esbuild/freebsd-arm64": "0.25.9", + "@esbuild/freebsd-x64": "0.25.9", + "@esbuild/linux-arm": "0.25.9", + "@esbuild/linux-arm64": "0.25.9", + "@esbuild/linux-ia32": "0.25.9", + "@esbuild/linux-loong64": "0.25.9", + "@esbuild/linux-mips64el": "0.25.9", + "@esbuild/linux-ppc64": "0.25.9", + "@esbuild/linux-riscv64": "0.25.9", + "@esbuild/linux-s390x": "0.25.9", + "@esbuild/linux-x64": "0.25.9", + "@esbuild/netbsd-arm64": "0.25.9", + "@esbuild/netbsd-x64": "0.25.9", + "@esbuild/openbsd-arm64": "0.25.9", + "@esbuild/openbsd-x64": "0.25.9", + "@esbuild/openharmony-arm64": "0.25.9", + "@esbuild/sunos-x64": "0.25.9", + "@esbuild/win32-arm64": "0.25.9", + "@esbuild/win32-ia32": "0.25.9", + "@esbuild/win32-x64": "0.25.9" } }, @@ -8048,5 +8322,4 @@ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, "dependencies": { "graceful-fs": "^4.2.0", @@ -8061,10 +8334,11 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "hasInstallScript": true, "optional": true, @@ -8205,4 +8479,5 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, "dependencies": { "fs.realpath": "^1.0.0", @@ -8235,5 +8510,6 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "license": "BSD-2-Clause" }, "node_modules/globals": { @@ -8241,4 +8517,5 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, "engines": { "node": ">=4" @@ -8559,8 +8836,11 @@ }, "node_modules/humanize-duration": { - "version": "3.33.0", - "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.33.0.tgz", - "integrity": "sha512-vYJX7BSzn7EQ4SaP2lPYVy+icHDppB6k7myNeI3wrSRfwMS5+BHyGgzpHR0ptqJ2AQ6UuIKrclSg5ve6Ci4IAQ==", - "license": "Unlicense" + "version": "3.33.1", + "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.33.1.tgz", + "integrity": "sha512-hwzSCymnRdFx9YdRkQQ0OYequXiVAV6ZGQA2uzocwB0F4309Ke6pO8dg0P8LHhRQJyVjGteRTAA/zNfEcpXn8A==", + "license": "Unlicense", + "funding": { + "url": "https://github.com/sponsors/EvanHahn" + } }, "node_modules/iconv-lite": { @@ -8637,4 +8917,5 @@ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, "dependencies": { "once": "^1.3.0", @@ -9412,4 +9693,15 @@ } }, + "node_modules/jest-circus/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/jest-cli": { "version": "29.7.0", @@ -11525,12 +11817,12 @@ }, "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "bin": { "jsesc": "bin/jsesc" }, "engines": { - "node": ">=4" + "node": ">=6" } }, @@ -11759,16 +12051,4 @@ } }, - "node_modules/magic-string": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", - "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.13" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/make-dir": { "version": "4.0.0", @@ -11952,7 +12232,7 @@ }, "node_modules/nanoid": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "dev": true, "funding": [ @@ -11993,7 +12273,7 @@ }, "node_modules/node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "version": "2.0.26", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.26.tgz", + "integrity": "sha512-S2M9YimhSjBSvYnlr5/+umAnPHE++ODwt5e2Ij6FoX45HA/s4vHdkDx1eax2pAPeAOqu4s9b7ppahsyEFdVqQA==", "license": "MIT" }, @@ -12231,4 +12511,5 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, "dependencies": { "wrappy": "1" @@ -12282,12 +12563,4 @@ } }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/p-limit": { "version": "3.1.0", @@ -12382,7 +12655,8 @@ }, "node_modules/patch-package": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-8.0.0.tgz", - "integrity": "sha512-da8BVIhzjtgScwDJ2TtKsfT5JFWz1hYoBl9rUQ1f38MC2HwnEIkK8VN3dKMKcP7P7bvvgzNDbfNHtx3MsQb5vA==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-8.0.1.tgz", + "integrity": "sha512-VsKRIA8f5uqHQ7NGhwIna6Bx6D9s/1iXlA1hthBVBEbkq+t4kXD0HHt+rJhf/Z+Ci0F/HCB2hvn0qLdLG+Qxlw==", + "license": "MIT", "dependencies": { "@yarnpkg/lockfile": "^1.1.0", @@ -12391,13 +12665,12 @@ "cross-spawn": "^7.0.3", "find-yarn-workspace-root": "^2.0.0", - "fs-extra": "^9.0.0", + "fs-extra": "^10.0.0", "json-stable-stringify": "^1.0.2", "klaw-sync": "^6.0.0", "minimist": "^1.2.6", "open": "^7.4.2", - "rimraf": "^2.6.3", "semver": "^7.5.3", "slash": "^2.0.0", - "tmp": "^0.0.33", + "tmp": "^0.2.4", "yaml": "^2.2.2" }, @@ -12455,18 +12728,4 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "node_modules/patch-package/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/patch-package/node_modules/has-flag": { "version": "4.0.0", @@ -12477,16 +12736,4 @@ } }, - "node_modules/patch-package/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, "node_modules/patch-package/node_modules/semver": { "version": "7.6.3", @@ -12519,15 +12766,4 @@ } }, - "node_modules/patch-package/node_modules/yaml": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz", - "integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/path-browserify": { "version": "1.0.1", @@ -12548,4 +12784,5 @@ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, "engines": { "node": ">=0.10.0" @@ -12677,7 +12914,7 @@ }, "node_modules/postcss": { - "version": "8.4.31", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", - "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", "dev": true, "funding": [ @@ -12696,7 +12933,7 @@ ], "dependencies": { - "nanoid": "^3.3.6", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, "engines": { @@ -13063,7 +13300,7 @@ }, "node_modules/react-refresh": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz", - "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==", + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", "dev": true, "engines": { @@ -13485,16 +13722,40 @@ }, "node_modules/rollup": { - "version": "3.29.5", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.5.tgz", - "integrity": "sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==", + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.50.1.tgz", + "integrity": "sha512-78E9voJHwnXQMiQdiqswVLZwJIzdBKJ1GdI5Zx6XwoFKUIk09/sSrr+05QFzvYb8q6Y9pPV45zzDuYa3907TZA==", "dev": true, + "dependencies": { + "@types/estree": "1.0.8" + }, "bin": { "rollup": "dist/bin/rollup" }, "engines": { - "node": ">=14.18.0", + "node": ">=18.0.0", "npm": ">=8.0.0" }, "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.50.1", + "@rollup/rollup-android-arm64": "4.50.1", + "@rollup/rollup-darwin-arm64": "4.50.1", + "@rollup/rollup-darwin-x64": "4.50.1", + "@rollup/rollup-freebsd-arm64": "4.50.1", + "@rollup/rollup-freebsd-x64": "4.50.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.50.1", + "@rollup/rollup-linux-arm-musleabihf": "4.50.1", + "@rollup/rollup-linux-arm64-gnu": "4.50.1", + "@rollup/rollup-linux-arm64-musl": "4.50.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.50.1", + "@rollup/rollup-linux-ppc64-gnu": "4.50.1", + "@rollup/rollup-linux-riscv64-gnu": "4.50.1", + "@rollup/rollup-linux-riscv64-musl": "4.50.1", + "@rollup/rollup-linux-s390x-gnu": "4.50.1", + "@rollup/rollup-linux-x64-gnu": "4.50.1", + "@rollup/rollup-linux-x64-musl": "4.50.1", + "@rollup/rollup-openharmony-arm64": "4.50.1", + "@rollup/rollup-win32-arm64-msvc": "4.50.1", + "@rollup/rollup-win32-ia32-msvc": "4.50.1", + "@rollup/rollup-win32-x64-msvc": "4.50.1", "fsevents": "~2.3.2" } @@ -13793,7 +14054,7 @@ }, "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, "engines": { @@ -14037,10 +14298,14 @@ }, "node_modules/tapable": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", - "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", "license": "MIT", "engines": { "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, @@ -14139,4 +14404,49 @@ "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/tldts": { "version": "6.1.86", @@ -14158,12 +14468,10 @@ }, "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dependencies": { - "os-tmpdir": "~1.0.2" - }, + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", + "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", + "license": "MIT", "engines": { - "node": ">=0.6.0" + "node": ">=14.14" } }, @@ -14174,12 +14482,4 @@ "dev": true }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "engines": { - "node": ">=4" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", @@ -14379,4 +14679,9 @@ "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==" }, + "node_modules/undici-types": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz", + "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==" + }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.0", @@ -14428,7 +14733,7 @@ }, "node_modules/update-browserslist-db": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", - "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", + "integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==", "funding": [ { @@ -14448,5 +14753,5 @@ "dependencies": { "escalade": "^3.2.0", - "picocolors": "^1.1.0" + "picocolors": "^1.1.1" }, "bin": { @@ -14527,13 +14832,15 @@ }, "node_modules/vite": { - "version": "4.5.14", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.14.tgz", - "integrity": "sha512-+v57oAaoYNnO3hIu5Z/tJRZjq5aHM2zDve9YZ8HngVHbhk66RStobhb1sqPMIPEleV6cNKYK4eGrAbE9Ulbl2g==", + "version": "7.1.11", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.11.tgz", + "integrity": "sha512-uzcxnSDVjAopEUjljkWh8EIrg6tlzrjFUfMcR1EVsRDGwf/ccef0qQPRyOrROwhrTDaApueq+ja+KLPlzR/zdg==", "dev": true, - "license": "MIT", "dependencies": { - "esbuild": "^0.18.10", - "postcss": "^8.4.27", - "rollup": "^3.27.1" + "esbuild": "^0.25.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" }, "bin": { @@ -14541,5 +14848,5 @@ }, "engines": { - "node": "^14.18.0 || >=16.0.0" + "node": "^20.19.0 || >=22.12.0" }, "funding": { @@ -14547,14 +14854,18 @@ }, "optionalDependencies": { - "fsevents": "~2.3.2" + "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": ">= 14", - "less": "*", + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", "lightningcss": "^1.21.0", - "sass": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" }, "peerDependenciesMeta": { @@ -14562,4 +14873,7 @@ "optional": true }, + "jiti": { + "optional": true + }, "less": { "optional": true @@ -14571,4 +14885,7 @@ "optional": true }, + "sass-embedded": { + "optional": true + }, "stylus": { "optional": true @@ -14579,4 +14896,10 @@ "terser": { "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true } } @@ -14696,4 +15019,33 @@ } }, + "node_modules/vite/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/w3c-xmlserializer": { "version": "5.0.0", @@ -14726,7 +15078,8 @@ }, "node_modules/watchpack": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", - "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", + "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", + "license": "MIT", "dependencies": { "glob-to-regexp": "^0.4.1", @@ -14747,7 +15100,7 @@ }, "node_modules/webpack": { - "version": "5.100.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.100.2.tgz", - "integrity": "sha512-QaNKAvGCDRh3wW1dsDjeMdDXwZm2vqq3zn6Pvq4rHOEOGSaUMgOOjG2Y9ZbIGzpfkJk9ZYTHpDqgDfeBDcnLaw==", + "version": "5.102.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.102.0.tgz", + "integrity": "sha512-hUtqAR3ZLVEYDEABdBioQCIqSoguHbFn1K7WlPPWSuXmx0031BD73PSE35jKyftdSh4YLDoQNgK4pqBt5Q82MA==", "license": "MIT", "dependencies": { @@ -14760,7 +15113,7 @@ "acorn": "^8.15.0", "acorn-import-phases": "^1.0.3", - "browserslist": "^4.24.0", + "browserslist": "^4.24.5", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.2", + "enhanced-resolve": "^5.17.3", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", @@ -14773,7 +15126,7 @@ "neo-async": "^2.6.2", "schema-utils": "^4.3.2", - "tapable": "^2.1.1", + "tapable": "^2.2.3", "terser-webpack-plugin": "^5.3.11", - "watchpack": "^2.4.1", + "watchpack": "^2.4.4", "webpack-sources": "^3.3.3" }, @@ -14964,5 +15317,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true }, "node_modules/write-file-atomic": { @@ -15031,9 +15385,12 @@ }, "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz", + "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", + "bin": { + "yaml": "bin.mjs" + }, "engines": { - "node": ">= 6" + "node": ">= 14.6" } }, @@ -15079,14 +15436,4 @@ }, "dependencies": { - "@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", - "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.1.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, "@asamuzakjp/css-color": { "version": "3.2.0", @@ -15111,34 +15458,35 @@ }, "@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", "requires": { - "@babel/highlight": "^7.24.7", - "picocolors": "^1.0.0" + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" } }, "@babel/compat-data": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.2.tgz", - "integrity": "sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.4.tgz", + "integrity": "sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==", "dev": true }, "@babel/core": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", - "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.4.tgz", + "integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==", "dev": true, "requires": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.0", - "@babel/helper-compilation-targets": "^7.25.2", - "@babel/helper-module-transforms": "^7.25.2", - "@babel/helpers": "^7.25.0", - "@babel/parser": "^7.25.0", - "@babel/template": "^7.25.0", - "@babel/traverse": "^7.25.2", - "@babel/types": "^7.25.2", + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.4", + "@babel/parser": "^7.28.4", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.4", + "@babel/types": "^7.28.4", + "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", @@ -15168,24 +15516,13 @@ }, "@babel/generator": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.0.tgz", - "integrity": "sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==", - "requires": { - "@babel/types": "^7.25.0", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" - }, - "dependencies": { - "@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "requires": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - } - } + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz", + "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==", + "requires": { + "@babel/parser": "^7.28.3", + "@babel/types": "^7.28.2", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" } }, @@ -15210,12 +15547,12 @@ }, "@babel/helper-compilation-targets": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz", - "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==", + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", "dev": true, "requires": { - "@babel/compat-data": "^7.25.2", - "@babel/helper-validator-option": "^7.24.8", - "browserslist": "^4.23.1", + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" @@ -15261,4 +15598,9 @@ } }, + "@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==" + }, "@babel/helper-member-expression-to-functions": { "version": "7.24.8", @@ -15272,22 +15614,21 @@ }, "@babel/helper-module-imports": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", - "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", "requires": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" } }, "@babel/helper-module-transforms": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz", - "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", + "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7", - "@babel/traverse": "^7.25.2" + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.28.3" } }, @@ -15302,7 +15643,7 @@ }, "@babel/helper-plugin-utils": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", - "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", "dev": true }, @@ -15350,17 +15691,17 @@ }, "@babel/helper-string-parser": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", - "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==" + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==" }, "@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==" + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==" }, "@babel/helper-validator-option": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", - "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", "dev": true }, @@ -15377,30 +15718,19 @@ }, "@babel/helpers": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.0.tgz", - "integrity": "sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", "dev": true, "requires": { - "@babel/template": "^7.25.0", - "@babel/types": "^7.25.0" - } - }, - "@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "requires": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" } }, "@babel/parser": { - "version": "7.25.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.3.tgz", - "integrity": "sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz", + "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==", "requires": { - "@babel/types": "^7.25.2" + "@babel/types": "^7.28.4" } }, @@ -16160,19 +16490,19 @@ }, "@babel/plugin-transform-react-jsx-self": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.21.0.tgz", - "integrity": "sha512-f/Eq+79JEu+KUANFks9UZCcvydOOGMgF7jBrcwjHa5jTZD8JivnhCJYvmlhR/WTXBWonDExPoW0eO/CR4QJirA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.27.1" } }, "@babel/plugin-transform-react-jsx-source": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.19.6.tgz", - "integrity": "sha512-RpAi004QyMNisst/pvSanoRdJ4q+jMCWyk9zdw/CyLB9j8RXEahodR6l2GyttDRyEVWZtbN+TpLiHJ3t34LbsQ==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.27.1" } }, @@ -16454,40 +16784,39 @@ }, "@babel/runtime": { - "version": "7.28.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.2.tgz", - "integrity": "sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA==" + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", + "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==" }, "@babel/template": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", - "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", - "requires": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.25.0", - "@babel/types": "^7.25.0" + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "requires": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" } }, "@babel/traverse": { - "version": "7.25.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.3.tgz", - "integrity": "sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==", - "requires": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.0", - "@babel/parser": "^7.25.3", - "@babel/template": "^7.25.0", - "@babel/types": "^7.25.2", - "debug": "^4.3.1", - "globals": "^11.1.0" + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.4.tgz", + "integrity": "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==", + "requires": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.3", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.4", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4", + "debug": "^4.3.1" } }, "@babel/types": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.2.tgz", - "integrity": "sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz", + "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", "requires": { - "@babel/helper-string-parser": "^7.24.8", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" } }, @@ -16622,155 +16951,183 @@ "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==" }, + "@esbuild/aix-ppc64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.9.tgz", + "integrity": "sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==", + "dev": true, + "optional": true + }, "@esbuild/android-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", - "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.9.tgz", + "integrity": "sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==", "dev": true, "optional": true }, "@esbuild/android-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", - "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.9.tgz", + "integrity": "sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==", "dev": true, "optional": true }, "@esbuild/android-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", - "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.9.tgz", + "integrity": "sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==", "dev": true, "optional": true }, "@esbuild/darwin-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", - "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.9.tgz", + "integrity": "sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==", "dev": true, "optional": true }, "@esbuild/darwin-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", - "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.9.tgz", + "integrity": "sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==", "dev": true, "optional": true }, "@esbuild/freebsd-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", - "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.9.tgz", + "integrity": "sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==", "dev": true, "optional": true }, "@esbuild/freebsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", - "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.9.tgz", + "integrity": "sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==", "dev": true, "optional": true }, "@esbuild/linux-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", - "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.9.tgz", + "integrity": "sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==", "dev": true, "optional": true }, "@esbuild/linux-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", - "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.9.tgz", + "integrity": "sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==", "dev": true, "optional": true }, "@esbuild/linux-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", - "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.9.tgz", + "integrity": "sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==", "dev": true, "optional": true }, "@esbuild/linux-loong64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", - "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.9.tgz", + "integrity": "sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==", "dev": true, "optional": true }, "@esbuild/linux-mips64el": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", - "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.9.tgz", + "integrity": "sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==", "dev": true, "optional": true }, "@esbuild/linux-ppc64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", - "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.9.tgz", + "integrity": "sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==", "dev": true, "optional": true }, "@esbuild/linux-riscv64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", - "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.9.tgz", + "integrity": "sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==", "dev": true, "optional": true }, "@esbuild/linux-s390x": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", - "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.9.tgz", + "integrity": "sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==", "dev": true, "optional": true }, "@esbuild/linux-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", - "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.9.tgz", + "integrity": "sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.9.tgz", + "integrity": "sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==", "dev": true, "optional": true }, "@esbuild/netbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", - "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.9.tgz", + "integrity": "sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.9.tgz", + "integrity": "sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==", "dev": true, "optional": true }, "@esbuild/openbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", - "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.9.tgz", + "integrity": "sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==", + "dev": true, + "optional": true + }, + "@esbuild/openharmony-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.9.tgz", + "integrity": "sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==", "dev": true, "optional": true }, "@esbuild/sunos-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", - "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.9.tgz", + "integrity": "sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==", "dev": true, "optional": true }, "@esbuild/win32-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", - "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.9.tgz", + "integrity": "sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==", "dev": true, "optional": true }, "@esbuild/win32-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", - "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.9.tgz", + "integrity": "sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==", "dev": true, "optional": true }, "@esbuild/win32-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", - "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.9.tgz", + "integrity": "sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==", "dev": true, "optional": true @@ -16879,7 +17236,7 @@ }, "@fortawesome/react-fontawesome": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.3.tgz", - "integrity": "sha512-HlJco8RDY8NrzFVjy23b/7mNS4g9NegcrBG3n7jinwpc2x/AmSVk53IhWniLYM4szYLxRAFTAGwGn0EIlclDeQ==", + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.6.tgz", + "integrity": "sha512-mtBFIi1UsYQo7rYonYFkjgYKGoL8T+fEH6NGUpvuqtY3ytMsAoDaPo5rk25KuMtKDipY4bGYM/CkmCHA1N3FUg==", "requires": { "prop-types": "^15.8.1" @@ -17750,11 +18107,20 @@ }, "@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "requires": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", "dev": true, "requires": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" } }, @@ -17764,9 +18130,4 @@ "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" }, - "@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==" - }, "@jridgewell/source-map": { "version": "0.3.6", @@ -17776,27 +18137,15 @@ "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25" - }, - "dependencies": { - "@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "requires": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - } - } } }, "@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==" }, "@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "version": "0.3.30", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.30.tgz", + "integrity": "sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==", "requires": { "@jridgewell/resolve-uri": "^3.1.0", @@ -17892,4 +18241,10 @@ } }, + "@rolldown/pluginutils": { + "version": "1.0.0-beta.34", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.34.tgz", + "integrity": "sha512-LyAREkZHP5pMom7c24meKmJCdhf2hEyvam2q0unr3or9ydwDL+DJ8chTF6Av/RFPb3rH8UFBdMzO5MxTZW97oA==", + "dev": true + }, "@rollup/pluginutils": { "version": "4.2.1", @@ -17902,4 +18257,151 @@ } }, + "@rollup/rollup-android-arm-eabi": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.50.1.tgz", + "integrity": "sha512-HJXwzoZN4eYTdD8bVV22DN8gsPCAj3V20NHKOs8ezfXanGpmVPR7kalUHd+Y31IJp9stdB87VKPFbsGY3H/2ag==", + "dev": true, + "optional": true + }, + "@rollup/rollup-android-arm64": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.50.1.tgz", + "integrity": "sha512-PZlsJVcjHfcH53mOImyt3bc97Ep3FJDXRpk9sMdGX0qgLmY0EIWxCag6EigerGhLVuL8lDVYNnSo8qnTElO4xw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-darwin-arm64": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.50.1.tgz", + "integrity": "sha512-xc6i2AuWh++oGi4ylOFPmzJOEeAa2lJeGUGb4MudOtgfyyjr4UPNK+eEWTPLvmPJIY/pgw6ssFIox23SyrkkJw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-darwin-x64": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.50.1.tgz", + "integrity": "sha512-2ofU89lEpDYhdLAbRdeyz/kX3Y2lpYc6ShRnDjY35bZhd2ipuDMDi6ZTQ9NIag94K28nFMofdnKeHR7BT0CATw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-freebsd-arm64": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.50.1.tgz", + "integrity": "sha512-wOsE6H2u6PxsHY/BeFHA4VGQN3KUJFZp7QJBmDYI983fgxq5Th8FDkVuERb2l9vDMs1D5XhOrhBrnqcEY6l8ZA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-freebsd-x64": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.50.1.tgz", + "integrity": "sha512-A/xeqaHTlKbQggxCqispFAcNjycpUEHP52mwMQZUNqDUJFFYtPHCXS1VAG29uMlDzIVr+i00tSFWFLivMcoIBQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.50.1.tgz", + "integrity": "sha512-54v4okehwl5TaSIkpp97rAHGp7t3ghinRd/vyC1iXqXMfjYUTm7TfYmCzXDoHUPTTf36L8pr0E7YsD3CfB3ZDg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm-musleabihf": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.50.1.tgz", + "integrity": "sha512-p/LaFyajPN/0PUHjv8TNyxLiA7RwmDoVY3flXHPSzqrGcIp/c2FjwPPP5++u87DGHtw+5kSH5bCJz0mvXngYxw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm64-gnu": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.50.1.tgz", + "integrity": "sha512-2AbMhFFkTo6Ptna1zO7kAXXDLi7H9fGTbVaIq2AAYO7yzcAsuTNWPHhb2aTA6GPiP+JXh85Y8CiS54iZoj4opw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm64-musl": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.50.1.tgz", + "integrity": "sha512-Cgef+5aZwuvesQNw9eX7g19FfKX5/pQRIyhoXLCiBOrWopjo7ycfB292TX9MDcDijiuIJlx1IzJz3IoCPfqs9w==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.50.1.tgz", + "integrity": "sha512-RPhTwWMzpYYrHrJAS7CmpdtHNKtt2Ueo+BlLBjfZEhYBhK00OsEqM08/7f+eohiF6poe0YRDDd8nAvwtE/Y62Q==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-ppc64-gnu": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.50.1.tgz", + "integrity": "sha512-eSGMVQw9iekut62O7eBdbiccRguuDgiPMsw++BVUg+1K7WjZXHOg/YOT9SWMzPZA+w98G+Fa1VqJgHZOHHnY0Q==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-riscv64-gnu": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.50.1.tgz", + "integrity": "sha512-S208ojx8a4ciIPrLgazF6AgdcNJzQE4+S9rsmOmDJkusvctii+ZvEuIC4v/xFqzbuP8yDjn73oBlNDgF6YGSXQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-riscv64-musl": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.50.1.tgz", + "integrity": "sha512-3Ag8Ls1ggqkGUvSZWYcdgFwriy2lWo+0QlYgEFra/5JGtAd6C5Hw59oojx1DeqcA2Wds2ayRgvJ4qxVTzCHgzg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-s390x-gnu": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.50.1.tgz", + "integrity": "sha512-t9YrKfaxCYe7l7ldFERE1BRg/4TATxIg+YieHQ966jwvo7ddHJxPj9cNFWLAzhkVsbBvNA4qTbPVNsZKBO4NSg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-x64-gnu": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.50.1.tgz", + "integrity": "sha512-MCgtFB2+SVNuQmmjHf+wfI4CMxy3Tk8XjA5Z//A0AKD7QXUYFMQcns91K6dEHBvZPCnhJSyDWLApk40Iq/H3tA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-x64-musl": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.50.1.tgz", + "integrity": "sha512-nEvqG+0jeRmqaUMuwzlfMKwcIVffy/9KGbAGyoa26iu6eSngAYQ512bMXuqqPrlTyfqdlB9FVINs93j534UJrg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-openharmony-arm64": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.50.1.tgz", + "integrity": "sha512-RDsLm+phmT3MJd9SNxA9MNuEAO/J2fhW8GXk62G/B4G7sLVumNFbRwDL6v5NrESb48k+QMqdGbHgEtfU0LCpbA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-arm64-msvc": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.50.1.tgz", + "integrity": "sha512-hpZB/TImk2FlAFAIsoElM3tLzq57uxnGYwplg6WDyAxbYczSi8O2eQ+H2Lx74504rwKtZ3N2g4bCUkiamzS6TQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-ia32-msvc": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.50.1.tgz", + "integrity": "sha512-SXjv8JlbzKM0fTJidX4eVsH+Wmnp0/WcD8gJxIZyR6Gay5Qcsmdbi9zVtnbkGPG8v2vMR1AD06lGWy5FLMcG7A==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-x64-msvc": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.50.1.tgz", + "integrity": "sha512-StxAO/8ts62KZVRAm4JZYq9+NqNsV7RvimNK+YM7ry//zebEH6meuugqW/P5OFUCjyQgui+9fUxT6d5NShvMvA==", + "dev": true, + "optional": true + }, "@rushstack/eslint-patch": { "version": "1.10.4", @@ -18229,7 +18731,10 @@ }, "@types/node": { - "version": "18.14.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.2.tgz", - "integrity": "sha512-1uEQxww3DaghA0RxqHx0O0ppVlo43pJhepY51OxuQIKHpjbnYLA7vcdwioNPzIqmC2u3I/dmylcqjlh0e7AyUA==" + "version": "24.3.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.3.1.tgz", + "integrity": "sha512-3vXmQDXy+woz+gnrTvuvNrPzekOi+Ds0ReMxw0LzBiK3a+1k0kQn9f2NWk+lgD4rJehFUmYy2gMhJ2ZI+7YP9g==", + "requires": { + "undici-types": "~7.10.0" + } }, "@types/parse-json": { @@ -18466,14 +18971,15 @@ }, "@vitejs/plugin-react": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-3.1.0.tgz", - "integrity": "sha512-AfgcRL8ZBhAlc3BFdigClmTUMISmmzHn7sB2h9U1odvc5U/MjWXsAaz18b/WoppUTDBzxOJwo2VdClfUcItu9g==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.0.2.tgz", + "integrity": "sha512-tmyFgixPZCx2+e6VO9TNITWcCQl8+Nl/E8YbAyPVv85QCc7/A3JrdfG2A8gIzvVhWuzMOVrFW1aReaNxrI6tbw==", "dev": true, "requires": { - "@babel/core": "^7.20.12", - "@babel/plugin-transform-react-jsx-self": "^7.18.6", - "@babel/plugin-transform-react-jsx-source": "^7.19.6", - "magic-string": "^0.27.0", - "react-refresh": "^0.14.0" + "@babel/core": "^7.28.3", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.34", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" } }, @@ -18630,7 +19136,7 @@ }, "ace-builds": { - "version": "1.43.2", - "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.43.2.tgz", - "integrity": "sha512-3wzJUJX0RpMc03jo0V8Q3bSb/cKPnS7Nqqw8fVHsCCHweKMiTIxT3fP46EhjmVy6MCuxwP801ere+RW245phGw==" + "version": "1.43.3", + "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.43.3.tgz", + "integrity": "sha512-MCl9rALmXwIty/4Qboijo/yNysx1r6hBTzG+6n/TiOm5LFhZpEvEIcIITPFiEOEFDfgBOEmxu+a4f54LEFM6Sg==" }, "acorn": { @@ -18719,12 +19225,4 @@ "dev": true }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, "anymatch": { "version": "3.1.3", @@ -18817,9 +19315,4 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" - }, "available-typed-arrays": { "version": "1.0.5", @@ -18835,7 +19328,7 @@ }, "axios": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.11.0.tgz", - "integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz", + "integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==", "requires": { "follow-redirects": "^1.15.6", @@ -19278,4 +19771,10 @@ "yaml": "^1.10.0" } + }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true } } @@ -19286,4 +19785,9 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "baseline-browser-mapping": { + "version": "2.8.20", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.20.tgz", + "integrity": "sha512-JMWsdF+O8Orq3EMukbUN1QfbLK9mX2CkUmQBcW2T0s8OmdAUL5LLM/6wFwSrqXzlXB13yhyK9gTKS1rIizOduQ==" + }, "batch-processor": { "version": "1.0.0", @@ -19297,7 +19801,7 @@ }, "bootstrap": { - "version": "5.3.7", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.7.tgz", - "integrity": "sha512-7KgiD8UHjfcPBHEpDNg+zGz8L3LqR3GVwqZiBRFX04a1BCArZOz1r2kjly2HQ0WokqTO0v1nF+QAt8dsW4lKlw==", + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.8.tgz", + "integrity": "sha512-HP1SZDqaLDPwsNiqRqi5NcP0SSXciX2s9E+RyqJIIqGo+vJeN5AJVM98CXmW/Wux0nQ5L7jeWUdplCEf0Ee+tg==", "requires": {} }, @@ -19320,12 +19824,13 @@ }, "browserslist": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", - "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", - "requires": { - "caniuse-lite": "^1.0.30001669", - "electron-to-chromium": "^1.5.41", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.1" + "version": "4.27.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.27.0.tgz", + "integrity": "sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw==", + "requires": { + "baseline-browser-mapping": "^2.8.19", + "caniuse-lite": "^1.0.30001751", + "electron-to-chromium": "^1.5.238", + "node-releases": "^2.0.26", + "update-browserslist-db": "^1.1.4" } }, @@ -19377,17 +19882,7 @@ }, "caniuse-lite": { - "version": "1.0.30001721", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001721.tgz", - "integrity": "sha512-cOuvmUVtKrtEaoKiO0rSc29jcjwMwX5tOHDy4MgVFEWiUXj4uBMJkwI8MDySkgXidpMiHUcviogAvFi4pA2hDQ==" - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } + "version": "1.0.30001751", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001751.tgz", + "integrity": "sha512-A0QJhug0Ly64Ii3eIqHu5X51ebln3k4yTUkY1j8drqpWHVreg/VLijN48cZ1bYPiqOQuqpkIKnzr/Ul8V+p6Cw==" }, "char-regex": { @@ -19471,17 +19966,4 @@ "dev": true }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, "combined-stream": { "version": "1.0.8", @@ -19532,4 +20014,11 @@ "path-type": "^4.0.0", "yaml": "^1.7.2" + }, + "dependencies": { + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" + } } }, @@ -19908,7 +20397,7 @@ }, "dompurify": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.6.tgz", - "integrity": "sha512-/2GogDQlohXPZe6D6NOgQvXLPSYBqIWMnZ8zzOhn09REE4eyAzb+Hed3jhoM9OkuaJ8P6ZGTTVWQKAi8ieIzfQ==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.7.tgz", + "integrity": "sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==", "requires": { "@types/trusted-types": "^2.0.7" @@ -19941,7 +20430,7 @@ }, "electron-to-chromium": { - "version": "1.5.71", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.71.tgz", - "integrity": "sha512-dB68l59BI75W1BUGVTAEJy45CEVuEGy9qPVVQ8pnHyHMn36PLPPoE1mjLH+lo9rKulO3HC2OhbACI/8tCqJBcA==" + "version": "1.5.240", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.240.tgz", + "integrity": "sha512-OBwbZjWgrCOH+g6uJsA2/7Twpas2OlepS9uvByJjR2datRDuKGYeD+nP8lBBks2qnB7bGJNHDUx7c/YLaT3QMQ==" }, "element-resize-detector": { @@ -20114,31 +20603,35 @@ }, "esbuild": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", - "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", - "dev": true, - "requires": { - "@esbuild/android-arm": "0.18.20", - "@esbuild/android-arm64": "0.18.20", - "@esbuild/android-x64": "0.18.20", - "@esbuild/darwin-arm64": "0.18.20", - "@esbuild/darwin-x64": "0.18.20", - "@esbuild/freebsd-arm64": "0.18.20", - "@esbuild/freebsd-x64": "0.18.20", - "@esbuild/linux-arm": "0.18.20", - "@esbuild/linux-arm64": "0.18.20", - "@esbuild/linux-ia32": "0.18.20", - "@esbuild/linux-loong64": "0.18.20", - "@esbuild/linux-mips64el": "0.18.20", - "@esbuild/linux-ppc64": "0.18.20", - "@esbuild/linux-riscv64": "0.18.20", - "@esbuild/linux-s390x": "0.18.20", - "@esbuild/linux-x64": "0.18.20", - "@esbuild/netbsd-x64": "0.18.20", - "@esbuild/openbsd-x64": "0.18.20", - "@esbuild/sunos-x64": "0.18.20", - "@esbuild/win32-arm64": "0.18.20", - "@esbuild/win32-ia32": "0.18.20", - "@esbuild/win32-x64": "0.18.20" + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz", + "integrity": "sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==", + "dev": true, + "requires": { + "@esbuild/aix-ppc64": "0.25.9", + "@esbuild/android-arm": "0.25.9", + "@esbuild/android-arm64": "0.25.9", + "@esbuild/android-x64": "0.25.9", + "@esbuild/darwin-arm64": "0.25.9", + "@esbuild/darwin-x64": "0.25.9", + "@esbuild/freebsd-arm64": "0.25.9", + "@esbuild/freebsd-x64": "0.25.9", + "@esbuild/linux-arm": "0.25.9", + "@esbuild/linux-arm64": "0.25.9", + "@esbuild/linux-ia32": "0.25.9", + "@esbuild/linux-loong64": "0.25.9", + "@esbuild/linux-mips64el": "0.25.9", + "@esbuild/linux-ppc64": "0.25.9", + "@esbuild/linux-riscv64": "0.25.9", + "@esbuild/linux-s390x": "0.25.9", + "@esbuild/linux-x64": "0.25.9", + "@esbuild/netbsd-arm64": "0.25.9", + "@esbuild/netbsd-x64": "0.25.9", + "@esbuild/openbsd-arm64": "0.25.9", + "@esbuild/openbsd-x64": "0.25.9", + "@esbuild/openharmony-arm64": "0.25.9", + "@esbuild/sunos-x64": "0.25.9", + "@esbuild/win32-arm64": "0.25.9", + "@esbuild/win32-ia32": "0.25.9", + "@esbuild/win32-x64": "0.25.9" } }, @@ -20805,5 +21298,4 @@ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, "requires": { "graceful-fs": "^4.2.0", @@ -20815,10 +21307,11 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true }, "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "optional": true }, @@ -20910,4 +21403,5 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -20936,5 +21430,6 @@ "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true }, "globalthis": { @@ -21173,7 +21668,7 @@ }, "humanize-duration": { - "version": "3.33.0", - "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.33.0.tgz", - "integrity": "sha512-vYJX7BSzn7EQ4SaP2lPYVy+icHDppB6k7myNeI3wrSRfwMS5+BHyGgzpHR0ptqJ2AQ6UuIKrclSg5ve6Ci4IAQ==" + "version": "3.33.1", + "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.33.1.tgz", + "integrity": "sha512-hwzSCymnRdFx9YdRkQQ0OYequXiVAV6ZGQA2uzocwB0F4309Ke6pO8dg0P8LHhRQJyVjGteRTAA/zNfEcpXn8A==" }, "iconv-lite": { @@ -21226,4 +21721,5 @@ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, "requires": { "once": "^1.3.0", @@ -21770,4 +22266,12 @@ "has-flag": "^4.0.0" } + }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "optional": true, + "peer": true } } @@ -23331,7 +23835,7 @@ }, "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==" }, "json-parse-even-better-errors": { @@ -23515,13 +24019,4 @@ "dev": true }, - "magic-string": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", - "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", - "dev": true, - "requires": { - "@jridgewell/sourcemap-codec": "^1.4.13" - } - }, "make-dir": { "version": "4.0.0", @@ -23656,7 +24151,7 @@ }, "nanoid": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "dev": true }, @@ -23685,7 +24180,7 @@ }, "node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==" + "version": "2.0.26", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.26.tgz", + "integrity": "sha512-S2M9YimhSjBSvYnlr5/+umAnPHE++ODwt5e2Ij6FoX45HA/s4vHdkDx1eax2pAPeAOqu4s9b7ppahsyEFdVqQA==" }, "nodemon": { @@ -23850,4 +24345,5 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, "requires": { "wrappy": "1" @@ -23886,9 +24382,4 @@ } }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==" - }, "p-limit": { "version": "3.1.0", @@ -23952,7 +24443,7 @@ }, "patch-package": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-8.0.0.tgz", - "integrity": "sha512-da8BVIhzjtgScwDJ2TtKsfT5JFWz1hYoBl9rUQ1f38MC2HwnEIkK8VN3dKMKcP7P7bvvgzNDbfNHtx3MsQb5vA==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-8.0.1.tgz", + "integrity": "sha512-VsKRIA8f5uqHQ7NGhwIna6Bx6D9s/1iXlA1hthBVBEbkq+t4kXD0HHt+rJhf/Z+Ci0F/HCB2hvn0qLdLG+Qxlw==", "requires": { "@yarnpkg/lockfile": "^1.1.0", @@ -23961,13 +24452,12 @@ "cross-spawn": "^7.0.3", "find-yarn-workspace-root": "^2.0.0", - "fs-extra": "^9.0.0", + "fs-extra": "^10.0.0", "json-stable-stringify": "^1.0.2", "klaw-sync": "^6.0.0", "minimist": "^1.2.6", "open": "^7.4.2", - "rimraf": "^2.6.3", "semver": "^7.5.3", "slash": "^2.0.0", - "tmp": "^0.0.33", + "tmp": "^0.2.4", "yaml": "^2.2.2" }, @@ -24003,15 +24493,4 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, "has-flag": { "version": "4.0.0", @@ -24019,12 +24498,4 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "requires": { - "glob": "^7.1.3" - } - }, "semver": { "version": "7.6.3", @@ -24044,9 +24515,4 @@ "has-flag": "^4.0.0" } - }, - "yaml": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz", - "integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==" } } @@ -24066,5 +24532,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true }, "path-key": { @@ -24163,12 +24630,12 @@ }, "postcss": { - "version": "8.4.31", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", - "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", "dev": true, "requires": { - "nanoid": "^3.3.6", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" } }, @@ -24433,7 +24900,7 @@ }, "react-refresh": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz", - "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==", + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", "dev": true }, @@ -24754,9 +25221,31 @@ }, "rollup": { - "version": "3.29.5", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.5.tgz", - "integrity": "sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==", - "dev": true, - "requires": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.50.1.tgz", + "integrity": "sha512-78E9voJHwnXQMiQdiqswVLZwJIzdBKJ1GdI5Zx6XwoFKUIk09/sSrr+05QFzvYb8q6Y9pPV45zzDuYa3907TZA==", + "dev": true, + "requires": { + "@rollup/rollup-android-arm-eabi": "4.50.1", + "@rollup/rollup-android-arm64": "4.50.1", + "@rollup/rollup-darwin-arm64": "4.50.1", + "@rollup/rollup-darwin-x64": "4.50.1", + "@rollup/rollup-freebsd-arm64": "4.50.1", + "@rollup/rollup-freebsd-x64": "4.50.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.50.1", + "@rollup/rollup-linux-arm-musleabihf": "4.50.1", + "@rollup/rollup-linux-arm64-gnu": "4.50.1", + "@rollup/rollup-linux-arm64-musl": "4.50.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.50.1", + "@rollup/rollup-linux-ppc64-gnu": "4.50.1", + "@rollup/rollup-linux-riscv64-gnu": "4.50.1", + "@rollup/rollup-linux-riscv64-musl": "4.50.1", + "@rollup/rollup-linux-s390x-gnu": "4.50.1", + "@rollup/rollup-linux-x64-gnu": "4.50.1", + "@rollup/rollup-linux-x64-musl": "4.50.1", + "@rollup/rollup-openharmony-arm64": "4.50.1", + "@rollup/rollup-win32-arm64-msvc": "4.50.1", + "@rollup/rollup-win32-ia32-msvc": "4.50.1", + "@rollup/rollup-win32-x64-msvc": "4.50.1", + "@types/estree": "1.0.8", "fsevents": "~2.3.2" } @@ -24970,7 +25459,7 @@ }, "source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true }, @@ -25166,7 +25655,7 @@ }, "tapable": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", - "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==" + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==" }, "terser": { @@ -25235,4 +25724,29 @@ "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" }, + "tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "requires": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "dependencies": { + "fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "requires": {} + }, + "picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true + } + } + }, "tldts": { "version": "6.1.86", @@ -25251,10 +25765,7 @@ }, "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "requires": { - "os-tmpdir": "~1.0.2" - } + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", + "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==" }, "tmpl": { @@ -25264,9 +25775,4 @@ "dev": true }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" - }, "to-regex-range": { "version": "5.0.1", @@ -25420,4 +25926,9 @@ "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==" }, + "undici-types": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz", + "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==" + }, "unicode-canonical-property-names-ecmascript": { "version": "2.0.0", @@ -25454,10 +25965,10 @@ }, "update-browserslist-db": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", - "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", + "integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==", "requires": { "escalade": "^3.2.0", - "picocolors": "^1.1.0" + "picocolors": "^1.1.1" } }, @@ -25531,13 +26042,31 @@ }, "vite": { - "version": "4.5.14", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.14.tgz", - "integrity": "sha512-+v57oAaoYNnO3hIu5Z/tJRZjq5aHM2zDve9YZ8HngVHbhk66RStobhb1sqPMIPEleV6cNKYK4eGrAbE9Ulbl2g==", - "dev": true, - "requires": { - "esbuild": "^0.18.10", - "fsevents": "~2.3.2", - "postcss": "^8.4.27", - "rollup": "^3.27.1" + "version": "7.1.11", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.11.tgz", + "integrity": "sha512-uzcxnSDVjAopEUjljkWh8EIrg6tlzrjFUfMcR1EVsRDGwf/ccef0qQPRyOrROwhrTDaApueq+ja+KLPlzR/zdg==", + "dev": true, + "requires": { + "esbuild": "^0.25.0", + "fdir": "^6.5.0", + "fsevents": "~2.3.3", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "dependencies": { + "fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "requires": {} + }, + "picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true + } } }, @@ -25653,7 +26182,7 @@ }, "watchpack": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", - "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", + "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", "requires": { "glob-to-regexp": "^0.4.1", @@ -25668,7 +26197,7 @@ }, "webpack": { - "version": "5.100.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.100.2.tgz", - "integrity": "sha512-QaNKAvGCDRh3wW1dsDjeMdDXwZm2vqq3zn6Pvq4rHOEOGSaUMgOOjG2Y9ZbIGzpfkJk9ZYTHpDqgDfeBDcnLaw==", + "version": "5.102.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.102.0.tgz", + "integrity": "sha512-hUtqAR3ZLVEYDEABdBioQCIqSoguHbFn1K7WlPPWSuXmx0031BD73PSE35jKyftdSh4YLDoQNgK4pqBt5Q82MA==", "requires": { "@types/eslint-scope": "^3.7.7", @@ -25680,7 +26209,7 @@ "acorn": "^8.15.0", "acorn-import-phases": "^1.0.3", - "browserslist": "^4.24.0", + "browserslist": "^4.24.5", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.2", + "enhanced-resolve": "^5.17.3", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", @@ -25693,7 +26222,7 @@ "neo-async": "^2.6.2", "schema-utils": "^4.3.2", - "tapable": "^2.1.1", + "tapable": "^2.2.3", "terser-webpack-plugin": "^5.3.11", - "watchpack": "^2.4.1", + "watchpack": "^2.4.4", "webpack-sources": "^3.3.3" } @@ -25822,5 +26351,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true }, "write-file-atomic": { @@ -25866,7 +26396,7 @@ }, "yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz", + "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==" }, "yargs": { diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/package.json /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/package.json --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/package.json 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/package.json 2025-11-01 15:52:20.000000000 +0000 @@ -5,23 +5,23 @@ "type": "module", "dependencies": { - "@babel/runtime": "^7.28.2", + "@babel/runtime": "^7.28.4", "@fortawesome/fontawesome-svg-core": "6.7.2", "@fortawesome/free-regular-svg-icons": "6.7.2", "@fortawesome/free-solid-svg-icons": "^6.7.2", - "@fortawesome/react-fontawesome": "0.2.3", + "@fortawesome/react-fontawesome": "0.2.6", "@popperjs/core": "^2.11.8", - "ace-builds": "1.43.2", - "axios": ">=1.11.0", + "ace-builds": "1.43.3", + "axios": ">=1.12.2", "axios-retry": "3.9.1", - "bootstrap": "5.3.7", + "bootstrap": "5.3.8", "classnames": "^2.5.1", "csv-parse": "4.16.3", "csv-stringify": "5.6.5", - "dompurify": "3.2.6", + "dompurify": "3.2.7", "env-cmd": "^10.1.0", "hosted-git-info": "^2.8.9", "html-react-parser": "^0.14.3", "http-proxy-middleware": "^2.0.9", - "humanize-duration": "^3.33.0", + "humanize-duration": "^3.33.1", "lodash": "^4.17.21", "markdown-it": "14.1.0", @@ -29,5 +29,5 @@ "moment-timezone": "0.6.0", "npm-watch": "^0.13.0", - "patch-package": "8.0.0", + "patch-package": "8.0.1", "path-browserify": "1.0.1", "prop-types": "^15.8.1", @@ -50,5 +50,5 @@ "sprintf-js": "1.1.3", "url-parse": "^1.5.10", - "webpack": "5.100.2" + "webpack": "5.102.0" }, "homepage": ".", @@ -98,5 +98,5 @@ "@babel/preset-react": "^7.18.6", "@testing-library/react": "12", - "@vitejs/plugin-react": "^3.0.0", + "@vitejs/plugin-react": "^5.0.2", "babel-jest": "30.0.0-beta.3", "dotenv": "^8.6.0", @@ -108,5 +108,5 @@ "jest": "29.7.0", "jest-environment-jsdom": "30.0.0-beta.3", - "vite": "^4.5.14", + "vite": "^7.1.11", "vite-plugin-compression": "^0.5.1", "vite-plugin-eslint": "1.8.1" diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/App.jsx /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/App.jsx --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/App.jsx 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/App.jsx 2025-11-01 15:52:20.000000000 +0000 @@ -16,4 +16,5 @@ import ServerFlowsView from './components/flows/server-flows-view.jsx'; import Notebook from './components/notebooks/notebook.jsx'; +import FullScreenTable from './components/notebooks/table_view.jsx'; import FullScreenNotebook from './components/notebooks/full_notebook.jsx'; import FullScreenHuntNotebook from './components/hunts/hunt-full-notebook.jsx'; @@ -145,5 +146,7 @@ setClient={this.setClient} client={this.state.client}/> - +
@@ -165,5 +168,5 @@ - + @@ -185,5 +188,6 @@ - + + + + { this.renderApp() } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/artifacts/artifacts-upload.jsx /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/artifacts/artifacts-upload.jsx --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/artifacts/artifacts-upload.jsx 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/artifacts/artifacts-upload.jsx 2025-11-01 15:52:20.000000000 +0000 @@ -29,4 +29,5 @@ pack_file: null, prefix: "", + tags: "", loading: false, uploaded: [], @@ -40,4 +41,6 @@ componentDidMount() { this.source = CancelToken.source(); + this.setState({id: crypto.randomUUID()}); + } @@ -49,4 +52,5 @@ if(!_.isEqual(prevState.filter, this.state.filter) || !_.isEqual(prevState.prefix, this.state.prefix) || + !_.isEqual(prevState.tags, this.state.tags) || !_.isEqual(prevState.vfs_path, this.state.vfs_path)) { this.updateFile(); @@ -59,42 +63,27 @@ // filestore path uploadFile = () => { - if (!this.state.pack_file) { + if (!this.state.pack_file.name) { return; } - var reader = new FileReader(); - reader.onload = (event) => { - var request = { - prefix: this.state.prefix, - filter: this.state.filter, - data: reader.result.split(",")[1], - }; - - this.setState({loading: true}); - api.post("v1/LoadArtifactPack", request, - this.source.token).then(response => { - if (response.data.cancel) { - return ; - } - - let uploaded = _.map( - response.data.successful_artifacts, - (x, idx)=>{ - return {name: x, id: idx}; - }); - this.setState({loading:false, - current_error: undefined, - errors: response.data.errors || [], - vfs_path: response.data.vfs_path, - uploaded: uploaded}); - }).catch(err=>{ - let data = err.response && - err.response.data && err.response.data.message; - this.setState({current_error: data, - loading:false, - pack_file: undefined}); - }); - }; - reader.readAsDataURL(this.state.pack_file); + this.setState({loading: true}); + api.upload("v1/UploadFormFile", + {file: this.state.pack_file}, + {name: "ArtifactPack", type: "upload_file"}).then( + response=>{ + let url = response.data.url; + this.setState({ + loading: false, + upload_info: response.data, + }, this.updateFile); + + }).catch(response=>{ + return this.setState({ + loading:false, upload_info: {}}); + }); + } + + tags = ()=>{ + return _.filter(_.map(this.state.tags.split(" "), x=>x.trim())); } @@ -104,8 +93,10 @@ } + this.setState({loading: true}); var request = { prefix: this.state.prefix, + tags: this.tags(), filter: this.state.filter, - vfs_path: this.state.vfs_path, + vfs_path: this.state.upload_info.VfsPath, }; api.post("v1/LoadArtifactPack", request, @@ -126,7 +117,9 @@ }; + // Called when the user really wants the import. importFile = () => { var request = { prefix: this.state.prefix, + tags: this.tags(), filter: this.state.filter, vfs_path: this.state.vfs_path, @@ -161,5 +154,7 @@ - { if (!_.isEmpty(e.currentTarget.files)) { - this.setState({pack_file: e.currentTarget.files[0]}); + this.setState({ + upload_info: {}, + pack_file: e.currentTarget.files[0]}); } }} @@ -209,4 +206,17 @@ + {T("Tags")} + + { + this.setState({tags: e.target.value}); + }} + /> + + + {T("Filter")} diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/artifacts/artifacts.css /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/artifacts/artifacts.css --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/artifacts/artifacts.css 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/artifacts/artifacts.css 2025-11-01 15:52:20.000000000 +0000 @@ -108,2 +108,8 @@ padding-right: 5px; } + +.deleting-artifacts { + height: 60vh; + overflow: auto; + display: block; +} diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/artifacts/artifacts.jsx /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/artifacts/artifacts.jsx --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/artifacts/artifacts.jsx 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/artifacts/artifacts.jsx 2025-11-01 15:52:20.000000000 +0000 @@ -62,5 +62,5 @@ {T("You are about to delete the following artifacts")} - +
{_.map(this.props.names, (name, idx)=>{ @@ -134,4 +134,5 @@ return; } + // If we get here the url contains the artifact name, we // therefore have to allow all types of artifacts because we @@ -142,4 +143,9 @@ this.updateSearch(artifact_name); this.getArtifactDescription(artifact_name); + + if (this.props.match && this.props.match.params && + this.props.match.params.action === "edit") { + this.setState({showEditedArtifactDialog: true}); + } } @@ -212,5 +218,5 @@ }; let multi_selection = []; - for (let i=first;i { + makeColumn = (specs, colnum) => { return
@@ -93,5 +94,5 @@ { _.map(desc, (x, i)=>{ - return + return diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/core/paged-table.css /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/core/paged-table.css --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/core/paged-table.css 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/core/paged-table.css 2025-11-01 15:52:20.000000000 +0000 @@ -69,4 +69,9 @@ } +input.hidden-edit { + display: none; +} + + td.column-resizer { width: 0px; @@ -129,2 +134,6 @@ cursor: grabbing; } + +.transform-viewer { + margin-left: 5px; +} diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/core/paged-table.jsx /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/core/paged-table.jsx --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/core/paged-table.jsx 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/core/paged-table.jsx 2025-11-01 15:52:20.000000000 +0000 @@ -7,5 +7,5 @@ import {CancelToken} from 'axios'; -import { HotKeys, ObserveKeys } from "react-hotkeys"; +import { HotKeys } from "react-hotkeys"; import React, { Component } from 'react'; import PropTypes from 'prop-types'; @@ -23,5 +23,6 @@ import ColumnResizer from "./column-resizer.jsx"; import InputGroup from 'react-bootstrap/InputGroup'; - +import { serializeJSON } from '../utils/json_parse.jsx'; +import { Link } from "react-router-dom"; import T from '../i8n/i8n.jsx'; @@ -34,8 +35,16 @@ } from './table.jsx'; +let guid = 1; + +const getID = ()=>{ + guid++; + return "ID" + guid; +} + export class ColumnFilter extends Component { static propTypes = { column: PropTypes.string, + table_id: PropTypes.string, transform: PropTypes.object, setTransform: PropTypes.func, @@ -57,4 +66,9 @@ } + // The GUID should be unique for this column and table. + guid = ()=>{ + return this.props.table_id + this.props.column; + } + updateFiltersFromTransform = () => { let transform = this.props.transform || {}; @@ -90,45 +104,23 @@ render() { let classname = "hidden-edit"; - + let tooltip = T("Filter"); if(this.state.edit_visible) { - return ( - -
{ - e.preventDefault(); - this.submitSearch(); - return false; - }}> - - - { - this.setState({edit_filter: e.currentTarget.value}); - }}/> - - -
- ); + tooltip = this.props.column; + classname = "visible"; } return ( - +
{ e.preventDefault(); + e.stopPropagation(); + + if(this.state.edit_visible) { + this.submitSearch(); + } return false; }}> + + { + this.setState({edit_filter: e.currentTarget.value}); + }}/> +
@@ -408,5 +423,5 @@ return ( - <> +
+ { !this.props.is_fullscreen && + + + + {T("Fullscreen")} + + } - { this.renderPaginator() } - - - { this.getTransformedRenderer(transformed) } - + { this.renderPaginator() } + + { this.getTransformedRenderer(transformed) } + { this.props.toolbar || <> } @@ -1056,4 +1104,5 @@ - this.setState({start_row: row_offset})} - onPageSizeChange={size=>this.setState({page_size: size})} - direction={direction} - /> - ); + + this.setState({start_row: row_offset})} + onPageSizeChange={size=>this.setState({page_size: size})} + direction={direction} + /> + + + ); } @@ -1459,17 +1511,15 @@ return ( <> - - -
{this.renderKey(x[0])} : @@ -143,8 +144,8 @@
- { this.makeColumn(helpTextCol1)} + { this.makeColumn(helpTextCol1, 0)} - { this.makeColumn(helpTextCol2)} + { this.makeColumn(helpTextCol2, 1)}
- - - {_.map(this.activeColumns(), this.renderHeader)} - - - - {_.map(this.state.rows, this.renderRow)} - -
- + + + + + {_.map(this.activeColumns(), this.renderHeader)} + + + + {_.map(this.state.rows, this.renderRow)} + +
@@ -1540,18 +1590,20 @@ if (transform.filter_column) { result.push( - - - +
+ + + +
); } @@ -1559,21 +1611,23 @@ if (transform.sort_column) { result.push( - - - +
+ + + +
); } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/core/table.jsx /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/core/table.jsx --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/core/table.jsx 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/core/table.jsx 2025-11-01 15:52:20.000000000 +0000 @@ -16,4 +16,5 @@ import { NavLink } from "react-router-dom"; import ClientLink from '../clients/client-link.jsx'; +import FlowLink from '../flows/flow-link.jsx'; import { HexViewPopup } from '../utils/hex.jsx'; import ToolTip from '../widgets/tooltip.jsx'; @@ -28,4 +29,6 @@ import Table from 'react-bootstrap/Table'; import { TablePaginationControl, ColumnToggle } from './paged-table.jsx'; +import NumberFormatter from '../utils/number.jsx'; +import LogLevel from '../utils/log_level.jsx'; // Shows the InspectRawJson modal dialog UI. @@ -149,7 +152,4 @@ export function getFormatter(column_type, text) { switch(column_type) { - case "number": - return (cell, row) => {cell}; - case "mb": return (cell, row) => { @@ -224,4 +224,5 @@ case "flow": + case "flow_id": return (cell, row) => { let client_id = row["ClientId"]; @@ -229,9 +230,5 @@ return cell; }; - return {cell} - ; + return ; }; @@ -335,4 +332,32 @@ ; + case "number": + return (cell, row) => { + return ; + }; + + // A json object which is completely collapsed at all levels. + case "json/0": + return (cell, row) => ; + + // A json object which is completely collapsed at all levels + // except for the first level which is expanded. + case "json/1": + return (cell, row) => ; + + case "json/2": + return (cell, row) => ; + + case "json/3": + return (cell, row) => ; + case "hidden": return (cell, row) =><>; @@ -341,4 +366,10 @@ return (cell, row) =>; + case "log_level": + return (cell, row) =>; + + case "translated": + return (cell, row) => { return T(cell); }; + default: console.log("Unsupported column type " + column_type); diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/events/utils.jsx /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/events/utils.jsx --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/events/utils.jsx 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/events/utils.jsx 2025-11-01 15:52:20.000000000 +0000 @@ -32,4 +32,8 @@ param_dict.max_batch_rows = spec.max_batch_rows; } + + if(spec.timeout) { + param_dict.timeout = spec.timeout; + } }); @@ -150,4 +154,9 @@ return; } + + if(k==="timeout") { + spec.timeout = parseInt(v); + return; + } parameters.env.push({key: k, value: v}); diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/flows/client-flows-view.jsx /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/flows/client-flows-view.jsx --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/flows/client-flows-view.jsx 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/flows/client-flows-view.jsx 2025-11-01 15:52:20.000000000 +0000 @@ -83,11 +83,11 @@ GOTO_RESULTS: { name: "Display server dashboard", - sequence: "r", + sequence: "alt+r", }, - GOTO_LOGS: "l", - GOTO_OVERVIEW: "o", - GOTO_UPLOADS: "u", - COLLECT: "c", - NOTEBOOK: "b", + GOTO_LOGS: "alt+l", + GOTO_OVERVIEW: "alt+o", + GOTO_UPLOADS: "alt+u", + COLLECT: "alt+c", + NOTEBOOK: "alt+b", }; diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/flows/flow-logs.jsx /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/flows/flow-logs.jsx --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/flows/flow-logs.jsx 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/flows/flow-logs.jsx 2025-11-01 15:52:20.000000000 +0000 @@ -3,10 +3,7 @@ import VeloPagedTable from '../core/paged-table.jsx'; -import VeloTimestamp from "../utils/time.jsx"; -import LogLevel from '../utils/log_level.jsx'; import ButtonGroup from 'react-bootstrap/ButtonGroup'; import Form from 'react-bootstrap/Form'; import T from '../i8n/i8n.jsx'; -import VeloLog from "../widgets/logs.jsx"; function getFlowState(flow) { @@ -49,27 +46,10 @@ render() { let flow_id = this.props.flow && this.props.flow.session_id; - - let renderers = { - client_time: (cell, row, rowIndex) => { - return ( - - ); - }, - _ts: (cell, row, rowIndex) => { - return ( - - ); - }, - level: (cell, row, rowIndex) => { - return ; - }, - Timestamp: (cell, row, rowIndex) => { - return ( - - ); - }, - message: (cell, row, rowIndex) => { - return ; - }, + let formatters = { + client_time: "timestamp", + _ts: "timestamp", + level: "log_level", + Timestamp: "timestamp", + message: "log", }; @@ -93,5 +73,5 @@ { + return ; + }, + Preview: (cell, row, rowIndex) => { let client_id = this.props.flow && this.props.flow.client_id; diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/flows/flows-list.jsx /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/flows/flows-list.jsx --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/flows/flows-list.jsx 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/flows/flows-list.jsx 2025-11-01 15:52:20.000000000 +0000 @@ -98,18 +98,20 @@ - +
+ +
@@ -259,4 +261,10 @@ if (action === "new") { + // Special handling for the offline collector builder. + if (name==="Server.Utils.CreateCollector") { + this.setState({showOfflineWizard: true}); + return; + } + let specs = {}; specs[name] = {}; diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/flows/flows.css /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/flows/flows.css --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/flows/flows.css 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/flows/flows.css 2025-11-01 15:52:20.000000000 +0000 @@ -40,2 +40,7 @@ padding-right: 5px; } + +.delete-flow-table { + overflow-y: auto; + max-height: 60vh; +} diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/flows/new-collection.jsx /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/flows/new-collection.jsx --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/flows/new-collection.jsx 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/flows/new-collection.jsx 2025-11-01 15:52:20.000000000 +0000 @@ -969,4 +969,8 @@ return; } + if (k==="timeout") { + spec.timeout = v; + return; + } // If the value is cleared just let the artifact use diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/flows/new-collections-parameters.jsx /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/flows/new-collections-parameters.jsx --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/flows/new-collections-parameters.jsx 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/flows/new-collections-parameters.jsx 2025-11-01 15:52:20.000000000 +0000 @@ -43,4 +43,6 @@ let max_batch_rows = params.max_batch_rows; let cpu_limit = params.cpu_limit; + let timeout = params.timeout; + let params_batch_wait = {validating_regex: "\\d+", description: "Default", @@ -50,6 +52,9 @@ name: "max_batch_rows"}; let params_cpu_limit = {validating_regex: "\\d+", - description: "100%", - name: "cpu_limit"}; + description: "100%", + name: "cpu_limit"}; + let params_timeout = {validating_regex: "\\d+", + description: "100%", + name: "timeout"}; return ( @@ -73,4 +78,9 @@ setValue={x=>this.props.setValue("max_batch_rows", x)} /> + this.props.setValue("timeout", x)} + /> +
diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/flows/offline-collector.jsx /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/flows/offline-collector.jsx --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/flows/offline-collector.jsx 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/flows/offline-collector.jsx 2025-11-01 15:52:20.000000000 +0000 @@ -962,28 +962,29 @@ let params = this.state.collector_parameters; + let setter = (field, value)=>{ + if(!_.isUndefined(value)) { + env.push({key: field, value: str(value)}); + } + }; - env.push({key: "OS", value: str(params.target_os)}); - env.push({key: "artifacts", value: str( - _.map(this.state.artifacts, (item) => item.name))}); - env.push({key: "parameters", value: str(this.state.parameters)}); - env.push({key: "target", value: str(params.target)}); - env.push({key: "target_args", value: str(params.target_args)}); - env.push({key: "encryption_scheme", value: str(params.encryption_scheme)}); - env.push({key: "encryption_args", value: str(params.encryption_args)}); - env.push({key: "opt_verbose", value: "Y"}); - env.push({key: "opt_banner", value: "Y"}); - env.push({key: "opt_prompt", value: str(params.opt_prompt)}); - env.push({key: "opt_admin", value: "Y"}); - env.push({key: "opt_tempdir", value: str(params.opt_tempdir)}); - env.push({key: "opt_level", value: str(params.opt_level)}); - env.push({key: "opt_concurrency", value: str(params.opt_concurrency)}); - env.push({key: "opt_output_directory", value: str(params.opt_output_directory)}); - env.push({key: "opt_filename_template", value: str(params.opt_filename_template)}); - env.push({key: "opt_collector_filename", value: str(params.opt_collector_filename)}); - env.push({key: "opt_delete_at_exit", value: str(params.opt_delete_at_exit)}); - env.push({key: "opt_progress_timeout", value: str(this.state.resources.progress_timeout)}); - env.push({key: "opt_timeout", value: str(this.state.resources.timeout)}); - env.push({key: "opt_cpu_limit", value: str( this.state.resources.cpu_limit)}); - env.push({key: "opt_format", value: str(params.opt_format)}); + setter("OS", params.target_os); + setter("artifacts", _.map(this.state.artifacts, (item) => item.name)); + setter("parameters", this.state.parameters); + setter("target", params.target); + setter("target_args", params.target_args); + setter("encryption_scheme", params.encryption_scheme); + setter("encryption_args", params.encryption_args); + setter("opt_prompt", params.opt_prompt); + setter("opt_tempdir", params.opt_tempdir); + setter("opt_level", params.opt_level); + setter("opt_concurrency", params.opt_concurrency); + setter("opt_output_directory", params.opt_output_directory); + setter("opt_filename_template", params.opt_filename_template); + setter("opt_collector_filename", params.opt_collector_filename); + setter("opt_delete_at_exit", params.opt_delete_at_exit); + setter("opt_progress_timeout", this.state.resources.progress_timeout); + setter("opt_timeout", this.state.resources.timeout); + setter("opt_cpu_limit", this.state.resources.cpu_limit); + setter("opt_format", params.opt_format); return request; diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/flows/server-flows-view.jsx /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/flows/server-flows-view.jsx --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/flows/server-flows-view.jsx 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/flows/server-flows-view.jsx 2025-11-01 15:52:20.000000000 +0000 @@ -6,4 +6,5 @@ import FlowInspector from "./flows-inspector.jsx"; import { withRouter } from "react-router-dom"; +import { HotKeys, ObserveKeys } from "react-hotkeys"; import {CancelToken} from 'axios'; @@ -66,20 +67,52 @@ } + gotoTab = (tab) => { + let selected_flow = this.state.currentFlow && this.state.currentFlow.session_id; + this.props.history.push( + "/collected/server/" + selected_flow + "/" + tab); + } + + render() { + let KeyMap = { + GOTO_RESULTS: { + name: "Display server dashboard", + sequence: "alt+r", + }, + GOTO_LOGS: "alt+l", + GOTO_OVERVIEW: "alt+o", + GOTO_UPLOADS: "alt+u", + COLLECT: "alt+c", + NOTEBOOK: "alt+b", + }; + + let keyHandlers={ + GOTO_RESULTS: (e)=>this.gotoTab("results"), + GOTO_LOGS: (e)=>this.gotoTab("logs"), + GOTO_UPLOADS: (e)=>this.gotoTab("uploads"), + GOTO_OVERVIEW: (e)=>this.gotoTab("overview"), + NOTEBOOK: (e)=>this.gotoTab("notebook"), + COLLECT: ()=>this.setState({showWizard: true}), + }; + return ( <> - this.collapse("50%")} - defaultSize="30%"> - - - + + + this.collapse("50%")} + defaultSize="30%"> + + + + + ); diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/flows/utils.jsx /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/flows/utils.jsx --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/flows/utils.jsx 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/flows/utils.jsx 2025-11-01 15:52:20.000000000 +0000 @@ -25,4 +25,7 @@ artifact_parameters["cpu_limit"] = spec.cpu_limit; } + if (spec.timeout) { + artifact_parameters["timeout"] = spec.timeout; + } parameters[spec.artifact] = artifact_parameters; diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/forms/form.jsx /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/forms/form.jsx --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/forms/form.jsx 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/forms/form.jsx 2025-11-01 15:52:20.000000000 +0000 @@ -20,4 +20,8 @@ import { JSONparse } from '../utils/json_parse.jsx'; import { parseCSV, serializeCSV } from '../utils/csv.jsx'; +import Button from 'react-bootstrap/Button'; +import ButtonGroup from 'react-bootstrap/ButtonGroup'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; + import "./validated.css"; import "./forms.css"; @@ -204,5 +208,5 @@ this.setState({invalid: invalid}); } catch(e){ - console.log(e); + console.log("setValueWithValidator", e); } } @@ -363,17 +367,27 @@ - { + let data = _.map(e, x=>x.value); + this.props.setValue(JSON.stringify(data)); + }} + options={options} + /> + diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/forms/forms.css /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/forms/forms.css --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/forms/forms.css 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/forms/forms.css 2025-11-01 15:52:20.000000000 +0000 @@ -28,2 +28,20 @@ opacity: 0.5; } + +.multichoice-select .btn, +.left-joined-btn { + max-width: 30.5px; + padding-left: 9px; + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.multichoice-select .velo { + width: 100%; +} + +.multichoice-select .velo__control, +.regex-form .velo-ace-editor { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/forms/regex_array.jsx /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/forms/regex_array.jsx --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/forms/regex_array.jsx 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/forms/regex_array.jsx 2025-11-01 15:52:20.000000000 +0000 @@ -54,4 +54,5 @@ return
Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/notebooks: table_view.css Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/notebooks: table_view.jsx diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/sidebar/user-dashboard.jsx /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/sidebar/user-dashboard.jsx --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/sidebar/user-dashboard.jsx 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/sidebar/user-dashboard.jsx 2025-11-01 15:52:20.000000000 +0000 @@ -95,5 +95,5 @@ onClick={() => { this.props.history.push( - "/artifacts/Server.Monitor.Health"); + "/artifacts/Server.Monitor.Health/edit"); }} > diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/users/user-label.jsx /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/users/user-label.jsx --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/users/user-label.jsx 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/users/user-label.jsx 2025-11-01 15:52:20.000000000 +0000 @@ -127,10 +127,10 @@ export const PasswordChangeForm = withRouter(_PasswordChangeForm); -class UserSettings extends React.PureComponent { +class UserSettingsDialog extends React.PureComponent { static contextType = UserConfig; static propTypes = { onClose: PropTypes.func.isRequired, setSetting: PropTypes.func.isRequired, - + setClient: PropTypes.func.isRequired, history: PropTypes.object, } @@ -219,4 +219,5 @@ org_changed: true, previous_org: previous_org}); + this.props.setClient({client_id: null}); this.props.onClose(); } @@ -417,10 +418,10 @@ } -const UserSettingsWithRouter = withRouter(UserSettings); +const UserSettingsDialogWithRouter = withRouter(UserSettingsDialog); export default class UserLabel extends React.Component { static contextType = UserConfig; static propTypes = { - + setClient: PropTypes.func.isRequired, }; @@ -527,5 +528,6 @@ <> { this.state.showUserSettings && - this.setState({showUserSettings: false})} /> diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/utils/json.jsx /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/utils/json.jsx --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/utils/json.jsx 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/utils/json.jsx 2025-11-01 15:52:20.000000000 +0000 @@ -18,5 +18,6 @@ static propTypes = { value: PropTypes.any, - collapsed: PropTypes.bool, + expand_map: PropTypes.object, + depth: PropTypes.number, }; @@ -109,5 +110,6 @@ key_item: PropTypes.string, value: PropTypes.any, - collapsed: PropTypes.bool, + expand_map: PropTypes.object, + depth: PropTypes.number, indent: PropTypes.number, trailingComponents: PropTypes.array, @@ -115,5 +117,7 @@ componentDidMount = () => { - this.setState({expanded: !this.props.collapsed}); + // Set the intiial expanded state. + let depth = this.props.depth || 0; + this.setState({expanded: this.props.expand_map[depth]}); } @@ -155,5 +159,6 @@ value={v} key_item={k} - collapsed={this.props.collapsed} + expand_map={this.props.expand_map} + depth={this.props.depth + 1} indent={indent + 3 * scale}/>
); @@ -164,5 +169,6 @@ value={v} key_item={k} - collapsed={this.props.collapsed} + expand_map={this.props.expand_map} + depth={this.props.depth + 1} indent={indent + 3 * scale}/> ); @@ -179,5 +185,6 @@ { k }: + expand_map={this.props.expand_map} + depth={this.props.depth + 1} /> ); } @@ -324,5 +331,6 @@ key_item={this.props.key_item} indent={this.props.indent} - collapsed={this.props.collapsed} + expand_map={this.props.expand_map} + depth={this.props.depth + 1} trailingComponents={buttons} /> @@ -346,9 +354,11 @@ static propTypes = { value: PropTypes.any, - collapsed: PropTypes.bool, + expand_map: PropTypes.object, indent: PropTypes.number, }; render() { + let expand_map = this.props.expand_map || {}; + let depth = 0; let res = []; let pad = ; + expand_map={expand_map} + depth={depth} />; } else if (_.isObject(this.props.value)) { res = ; + expand_map={expand_map} + depth={depth} />; } else if (_.isString(this.props.value)) { diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/utils/value.jsx /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/utils/value.jsx --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/utils/value.jsx 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/utils/value.jsx 2025-11-01 15:52:20.000000000 +0000 @@ -15,7 +15,12 @@ const maxSizeDialog = 50; +// By default expand 4 levels for JSON objects. +const defaultExpanded = {0:1,1:1}; +const fullExpanded = {0:1,1:1,2:1,3:1,4:1}; + + class ValueModal extends React.PureComponent { static propTypes = { - value: PropTypes.object, + value: PropTypes.any, onClose: PropTypes.func.isRequired, }; @@ -29,5 +34,6 @@ onHide={this.props.onClose}> - + ; @@ -42,5 +48,5 @@ value: PropTypes.any, row: PropTypes.object, - collapsed: PropTypes.bool, + expand_map: PropTypes.object, }; @@ -93,12 +99,20 @@ } + // By default expand all levels. + let expand_map = defaultExpanded; + if(_.isObject(this.props.expand_map)) { + expand_map = this.props.expand_map; + } + return {button &&
{ button }
} - + { this.state.showDialog && this.setState({showDialog:false})} - value={this.props.value}/> } + value={this.props.value} /> }
; } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/widgets/preview_uploads.jsx /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/widgets/preview_uploads.jsx --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/components/widgets/preview_uploads.jsx 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/components/widgets/preview_uploads.jsx 2025-11-01 15:52:20.000000000 +0000 @@ -107,4 +107,6 @@ api.get_blob(this.props.url, params, this.source.token).then( response=>{ + if (response.cancel) return; + let content_range = response.blob && response.blob.headers && response.blob.headers["content-range"]; @@ -270,4 +272,6 @@ api.get_blob(this.props.url, params, this.source.token).then( response=>{ + if (response.cancel) return; + const view = new Uint8Array(response.data); this.setState({ @@ -527,4 +531,5 @@ api.get_blob(url, params, this.source.token).then( response=>{ + if (response.cancel) return; if(response.data && response.data.error) { this.setState({error: true}); diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/css/App.css /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/css/App.css --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/css/App.css 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/css/App.css 2025-11-01 15:52:20.000000000 +0000 @@ -66,13 +66,4 @@ } -grr-navigator .nav-pills li.active .nav-link:hover { - background-color: var(--color-sidebar-foreground); -} - -grr-navigator .nav-pills li.active .nav-link { - width: 200px; - background-color: var(--color-sidebar-foreground); -} - button a.nav-link { padding: 0px; diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/index.jsx /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/index.jsx --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/gui/velociraptor/src/index.jsx 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/gui/velociraptor/src/index.jsx 2025-11-01 15:52:20.000000000 +0000 @@ -29,5 +29,5 @@ faChevronRight, faEllipsis, faLayerGroup, faBullseye, faPersonRunning, faQuestion, faCalendarPlus, faForwardFast, faBackwardFast, faSliders, - faRepeat + faRepeat, faBorderAll, } from '@fortawesome/free-solid-svg-icons'; @@ -54,5 +54,5 @@ faEllipsis, faLayerGroup, faBullseye, faPersonRunning, faQuestion, faCalendarPlus, faForwardFast, faBackwardFast, faSquareCheck, faSquare, - faSquareMinus, faSliders, faRepeat + faSquareMinus, faSliders, faRepeat, faBorderAll, ); diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/http_comms/comms.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/http_comms/comms.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/http_comms/comms.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/http_comms/comms.go 2025-11-01 15:52:20.000000000 +0000 @@ -23,6 +23,4 @@ "fmt" "io" - "io/ioutil" - "math/rand" "net/http" "net/http/httptrace" @@ -33,4 +31,6 @@ "time" + "www.velocidex.com/golang/velociraptor/utils/rand" + "github.com/go-errors/errors" "github.com/sirupsen/logrus" @@ -59,7 +59,5 @@ EnrolError = errors.New("EnrolError") - mu sync.Mutex - Rand func(int) int = rand.Intn - + mu sync.Mutex proxyHandler = http.ProxyFromEnvironment @@ -211,5 +209,5 @@ // preconfigured URLs. This should distribute clients // randomly to all frontends. - current_url_idx: GetRand()(len(urls)), + current_url_idx: rand.Intn(len(urls)), minPoll: time.Duration(1) * time.Second, @@ -280,7 +278,22 @@ logger := logging.GetLogger(self.config_obj, &logging.ClientComponent) + + // Retry a limited number of times immediately. After this many + // immediate tries, this function will return the error and the + // limiter will be engaged before the next attempt. count := 0 for { + // Exit if the retry count is exceeded. Our caller will retry + // after rate limiting. + if count > MaxRetryCount { + logger.Debug("%v: Exceeded retry times for %v", + name, handler) + if resp != nil { + resp.Body.Close() + } + break + } + req, err := self.prepareRequest(ctx, name, handler, data, urgent) if err != nil { @@ -289,4 +302,5 @@ resp, err = self.client.Do(req) + // Represents a retryable error in websockets. if resp != nil { @@ -301,4 +315,5 @@ resp.Body.Close() } + count++ continue @@ -332,13 +347,4 @@ } - if count > MaxRetryCount { - logger.Debug("%v: Exceeded retry times for %v", - name, handler) - if resp != nil { - resp.Body.Close() - } - break - } - logger.Debug("%v: Retrying connection to %v for %v time", name, handler, count) @@ -432,5 +438,5 @@ // in a redirect loop. wait := self.maxPoll + time.Duration( - GetRand()(int(self.maxPollDev)))*time.Second + rand.Intn(int(self.maxPollDev)))*time.Second self.logger.Info("Waiting after redirect: %v", wait) <-self.clock.After(wait) @@ -460,6 +466,5 @@ encrypted := &bytes.Buffer{} - // We need to be able to cancel the read here so we do not use - // ioutil.ReadAll() + // We need to be able to cancel the read here. n, err := utils.Copy(ctx, encrypted, resp.Body) if err != nil { @@ -508,5 +513,5 @@ if self.current_url_idx == self.last_success_idx { wait := self.maxPoll + time.Duration( - GetRand()(int(self.maxPollDev)))*time.Second + rand.Intn(int(self.maxPollDev)))*time.Second self.logger.Info( @@ -536,11 +541,4 @@ } -func GetRand() func(int) int { - mu.Lock() - defer mu.Unlock() - - return Rand -} - func (self *HTTPConnector) String() string { return fmt.Sprintf("HTTP Connector to %v", self.urls) @@ -637,5 +635,5 @@ } - pem, err := ioutil.ReadAll(io.LimitReader(resp.Body, constants.MAX_MEMORY)) + pem, err := utils.ReadAllWithLimit(resp.Body, constants.MAX_MEMORY) if err != nil { self.server_name = "" @@ -683,4 +681,6 @@ // Manages reading jobs from the reader notification channel. type NotificationReader struct { + id uint64 + // Pause the PumpRingBufferToSendMessage loop - stops transmitting // data to the server temporarily. New data will still be queued @@ -722,4 +722,7 @@ last_update_time time.Time last_update_period time.Duration + + // Cancellation can be called to restart the main loop. + cancel func() } @@ -757,5 +760,6 @@ } - return &NotificationReader{ + self := &NotificationReader{ + id: utils.GetId(), config_obj: config_obj, connector: connector, @@ -775,4 +779,11 @@ last_update_period: last_update_period, } + + executor.Nanny().RegisterOnWarnings(self.id, func() { + self.logger.Info("%s: Nanny issued first warning! Restarting Receiver comms", + self.name) + self.Restart() + }) + return self } @@ -794,5 +805,4 @@ // If we are being redirected do not wait - // just retry again. - if errors.Is(err, RedirectError) { continue @@ -812,5 +822,5 @@ // synchronization of endpoints. wait := self.maxPoll + time.Duration( - GetRand()(int(self.maxPollDev)))*time.Second + rand.Intn(int(self.maxPollDev)))*time.Second self.logger.Info("Sleeping for %v", wait) @@ -908,4 +918,5 @@ self.on_exit() } + self.executor.Nanny().RegisterOnWarnings(self.id, nil) } @@ -922,10 +933,4 @@ ctx context.Context, wg *sync.WaitGroup) { - // Decide if we should compress the outer envelope. - compression := crypto_proto.PackedMessageList_ZCOMPRESSION - if self.config_obj.Client.DisableCompression { - compression = crypto_proto.PackedMessageList_UNCOMPRESSED - } - wg.Add(1) go func() { @@ -934,37 +939,71 @@ defer utils.CheckForPanic("Panic in main loop") - // Periodically read from executor and push to ring buffer. for { - self.executor.Nanny().UpdateReadFromServer() + select { + case <-ctx.Done(): + return + default: + } - // The Reader does not send any server bound - // messages - it is blocked reading server - // responses. - message_list := self.GetMessageList() - serialized_message_list, err := proto.Marshal(message_list) - if err == nil { - if compression == crypto_proto.PackedMessageList_ZCOMPRESSION { - compressed, err := utils.Compress(serialized_message_list) - if err == nil { - self.sendMessageList( - ctx, [][]byte{compressed}, !URGENT, compression) - } + // Allow cancellation of the main loop. This will restart + // it as needed. + sub_ctx, cancel := context.WithCancel(ctx) + self.cancel = cancel + + self.mainLoop(sub_ctx) + cancel() + } + }() +} + +func (self *NotificationReader) Restart() { + self.mu.Lock() + defer self.mu.Unlock() + + if self.cancel != nil { + self.cancel() + } +} + +func (self *NotificationReader) mainLoop(ctx context.Context) { + + // Decide if we should compress the outer envelope. + compression := crypto_proto.PackedMessageList_ZCOMPRESSION + if self.config_obj.Client.DisableCompression { + compression = crypto_proto.PackedMessageList_UNCOMPRESSED + } + + // Periodically read from executor and push to ring buffer. + for { + self.executor.Nanny().UpdateReadFromServer() - } else { + // The Reader does not send any server bound + // messages - it is blocked reading server + // responses. + message_list := self.GetMessageList() + serialized_message_list, err := proto.Marshal(message_list) + if err == nil { + if compression == crypto_proto.PackedMessageList_ZCOMPRESSION { + compressed, err := utils.Compress(serialized_message_list) + if err == nil { self.sendMessageList( - ctx, [][]byte{serialized_message_list}, !URGENT, compression) + ctx, [][]byte{compressed}, !URGENT, compression) } + + } else { + self.sendMessageList( + ctx, [][]byte{serialized_message_list}, !URGENT, compression) } + } - select { - case <-ctx.Done(): - return + select { + case <-ctx.Done(): + return - // Reconnect quickly for low latency. - case <-self.clock.After(self.minPoll): - continue - } + // Reconnect quickly for low latency. + case <-self.clock.After(self.minPoll): + continue } - }() + } } @@ -1104,4 +1143,5 @@ on_exit() } + rb.Close() } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/http_comms/comms_test.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/http_comms/comms_test.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/http_comms/comms_test.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/http_comms/comms_test.go 2025-11-01 15:52:20.000000000 +0000 @@ -39,23 +39,53 @@ crypto_test "www.velocidex.com/golang/velociraptor/crypto/testing" "www.velocidex.com/golang/velociraptor/executor" - "www.velocidex.com/golang/velociraptor/json" "www.velocidex.com/golang/velociraptor/services/writeback" "www.velocidex.com/golang/velociraptor/utils" + "www.velocidex.com/golang/velociraptor/utils/rand" "www.velocidex.com/golang/velociraptor/vtesting" ) var ( - counter int + counter utils.Counter ) +type EventRecorder struct { + mu sync.Mutex + events []string +} + +func (self *EventRecorder) Add(msg string) { + self.mu.Lock() + defer self.mu.Unlock() + + self.events = append(self.events, msg) +} + +func (self *EventRecorder) Len() int { + self.mu.Lock() + defer self.mu.Unlock() + + return len(self.events) +} + +func (self *EventRecorder) Get() []string { + self.mu.Lock() + defer self.mu.Unlock() + + return append([]string{}, self.events...) +} + type FakeClock struct { *utils.MockClock - events *[]string + mu sync.Mutex + events *EventRecorder } func (self *FakeClock) After(d time.Duration) <-chan time.Time { - *self.events = append(*self.events, fmt.Sprintf("%d sleep: %v\n", counter, d)) - counter++ + self.mu.Lock() + defer self.mu.Unlock() + + self.events.Add(fmt.Sprintf("%d sleep: %v\n", counter.Get(), d)) + counter.Inc() return time.After(0) } @@ -72,5 +102,7 @@ type FakeServer struct { - events []string + name string + + events *EventRecorder resp_idx int @@ -86,12 +118,15 @@ func (self *FakeServer) Log(fmtstring string, args ...interface{}) { - msg := fmt.Sprintf("%d ", counter) - counter++ + msg := fmt.Sprintf("%d ", counter.Get()) + counter.Inc() msg += fmt.Sprintf(fmtstring, args...) - self.events = append(self.events, msg) + self.events.Add(msg) } -func NewFakeServer() *FakeServer { - self := &FakeServer{} +func NewFakeServer(name string) *FakeServer { + self := &FakeServer{ + name: name, + events: &EventRecorder{}, + } self.server = httptest.NewServer(api_utils.HandlerFunc(nil, func(rw http.ResponseWriter, req *http.Request) { @@ -99,7 +134,7 @@ // Break out of a runaway condition. - if len(self.events) > 100 { + if self.events.Len() > 100 { fmt.Printf("Something went horribly wrong") - utils.Debug(self.events) + utils.Debug(self.events.Get()) os.Exit(-1) } @@ -141,4 +176,5 @@ empty_response []byte + closer func() writeback_path string @@ -146,7 +182,8 @@ func (self *CommsTestSuite) SetupTest() { - counter = 0 - self.frontend1 = NewFakeServer() - self.frontend2 = NewFakeServer() + counter = utils.Counter{} + + self.frontend1 = NewFakeServer("frontend1") + self.frontend2 = NewFakeServer("frontend2") config_obj, err := new(config.Loader).WithFileLoader( @@ -167,7 +204,5 @@ // Disable randomness for the test. - mu.Lock() - Rand = func(int) int { return 0 } - mu.Unlock() + self.closer = rand.DisableRand() // Initialize the writeback @@ -184,4 +219,5 @@ self.frontend1.Close() self.frontend2.Close() + self.closer() os.Remove(self.writeback_path) @@ -251,5 +287,6 @@ clock := &FakeClock{ MockClock: mock_clock, - events: &self.frontend1.events} + events: self.frontend1.events, + } ctx, cancel := context.WithCancel(context.Background()) @@ -272,7 +309,5 @@ crypto_proto.PackedMessageList_ZCOMPRESSION) - json.Dump(self.frontend1.events) - - checkResponses(self.T(), self.frontend1.events, []string{ + checkResponses(self.T(), self.frontend1.events.Get(), []string{ // First request looks for server.pem but fails on frontend1 "0 request: /server.pem", @@ -294,5 +329,6 @@ clock := &FakeClock{ MockClock: mock_clock, - events: &self.frontend1.events} + events: self.frontend1.events, + } ctx, cancel := context.WithCancel(context.Background()) @@ -315,5 +351,5 @@ crypto_proto.PackedMessageList_ZCOMPRESSION) - checkResponses(self.T(), self.frontend1.events, []string{ + checkResponses(self.T(), self.frontend1.events.Get(), []string{ // First request looks for server.pem "request: /server.pem", @@ -325,6 +361,6 @@ // Client will sleep to back off and try to rekey - "sleep: 10", - "sleep: 10", + "sleep: 10m0s\n", + "sleep: 10m0s\n", "request: /server.pem", "response: -----BEGIN CERTIFICATE-----", @@ -346,5 +382,6 @@ clock := &FakeClock{ MockClock: mock_clock, - events: &self.frontend1.events} + events: self.frontend1.events, + } ctx, cancel := context.WithCancel(context.Background()) @@ -352,5 +389,6 @@ crypto_manager := &crypto_test.NullCryptoManager{} - communicator, err := NewHTTPCommunicator(ctx, self.config_obj, crypto_manager, + communicator, err := NewHTTPCommunicator( + ctx, self.config_obj, crypto_manager, executor.NewTestExecutor(), urls, nil, clock) assert.NoError(self.T(), err) @@ -370,9 +408,11 @@ } + assert.Equal(self.T(), urls[0], self.frontend1.URL) + communicator.receiver.sendMessageList(context.Background(), nil, !URGENT, crypto_proto.PackedMessageList_ZCOMPRESSION) // Message ordering is important - checkResponses(self.T(), self.frontend1.events, []string{ + checkResponses(self.T(), self.frontend1.events.Get(), []string{ // First request looks for server.pem but fails on frontend1 "0 request: /server.pem", @@ -380,5 +420,5 @@ // After trying frontend2 immediately, we back off all frontends - "4 sleep: 10", + "4 sleep: 10m0s\n", // We try frontend1 again but again it fails @@ -387,5 +427,5 @@ }) - checkResponses(self.T(), self.frontend2.events, []string{ + checkResponses(self.T(), self.frontend2.events.Get(), []string{ // First request on FE 2 fails. "2 request: /server.pem", @@ -411,5 +451,6 @@ clock := &FakeClock{ MockClock: mock_clock, - events: &self.frontend1.events} + events: self.frontend1.events, + } ctx, cancel := context.WithCancel(context.Background()) @@ -439,8 +480,8 @@ !URGENT, crypto_proto.PackedMessageList_ZCOMPRESSION) - //utils.Debug(self.frontend1.events) - //utils.Debug(self.frontend2.events) + //utils.Debug(self.frontend1.events.Get()) + //utils.Debug(self.frontend2.events.Get()) - checkResponses(self.T(), self.frontend1.events, []string{ + checkResponses(self.T(), self.frontend1.events.Get(), []string{ // First request looks for server.pem but fails on frontend1 "0 request: /server.pem", @@ -448,5 +489,5 @@ // Must sleep now as both FE are down. - "4 sleep: 10", + "4 sleep: 10m0s\n", // Try FE1 again @@ -455,10 +496,10 @@ // Must sleep again - "9 sleep: 10", + "9 sleep: 10m0s\n", "10 request: /server.pem", "11 response: 500", }) - checkResponses(self.T(), self.frontend2.events, []string{ + checkResponses(self.T(), self.frontend2.events.Get(), []string{ // Immediately switch to FE2 but it is down as well. "2 request: /server.pem", @@ -489,5 +530,6 @@ clock := &FakeClock{ MockClock: mock_clock, - events: &self.frontend1.events} + events: self.frontend1.events, + } ctx, cancel := context.WithCancel(context.Background()) @@ -518,9 +560,9 @@ !URGENT, crypto_proto.PackedMessageList_ZCOMPRESSION) - //utils.Debug(self.frontend1.events) - //utils.Debug(self.frontend2.events) + //utils.Debug(self.frontend1.events.Get()) + //utils.Debug(self.frontend2.events.Get()) // Message ordering is important - checkResponses(self.T(), self.frontend1.events, []string{ + checkResponses(self.T(), self.frontend1.events.Get(), []string{ // First request looks for server.pem is ok. "0 request: /server.pem", @@ -530,8 +572,8 @@ "2 request: /reader", "3 response: 500", - "4 sleep: 10", + "4 sleep: 10m0s\n", }) - checkResponses(self.T(), self.frontend2.events, []string{ + checkResponses(self.T(), self.frontend2.events.Get(), []string{ "5 request: /server.pem", "6 response: -----BEGIN CERTIFICAT", @@ -553,5 +595,6 @@ clock := &FakeClock{ MockClock: mock_clock, - events: &self.frontend1.events} + events: self.frontend1.events, + } ctx, cancel := context.WithCancel(context.Background()) @@ -583,9 +626,9 @@ !URGENT, crypto_proto.PackedMessageList_ZCOMPRESSION) - //utils.Debug(self.frontend1.events) - //utils.Debug(self.frontend2.events) + //utils.Debug(self.frontend1.events.Get()) + //utils.Debug(self.frontend2.events.Get()) // Message ordering is important - checkResponses(self.T(), self.frontend1.events, []string{ + checkResponses(self.T(), self.frontend1.events.Get(), []string{ // First request looks for server.pem is ok. "0 request: /server.pem", @@ -597,7 +640,7 @@ "3 response: 500", - "4 sleep: 10", - "9 sleep: 10", - "10 sleep: 10", + "4 sleep: 10m0s\n", + "9 sleep: 10m0s\n", + "10 sleep: 10m0s\n", // Sleep after switching back from FE2 @@ -608,5 +651,5 @@ }) - checkResponses(self.T(), self.frontend2.events, []string{ + checkResponses(self.T(), self.frontend2.events.Get(), []string{ // Rekey FE2 "5 request: /server.pem", @@ -631,5 +674,6 @@ clock := &FakeClock{ MockClock: mock_clock, - events: &self.frontend1.events} + events: self.frontend1.events, + } ctx, cancel := context.WithCancel(context.Background()) @@ -663,9 +707,9 @@ !URGENT, crypto_proto.PackedMessageList_ZCOMPRESSION) - //utils.Debug(self.frontend1.events) - //utils.Debug(self.frontend2.events) + //utils.Debug(self.frontend1.events.Get()) + //utils.Debug(self.frontend2.events.Get()) // Message ordering is important - checkResponses(self.T(), self.frontend1.events, []string{ + checkResponses(self.T(), self.frontend1.events.Get(), []string{ // First request looks for server.pem is ok. "0 request: /server.pem", @@ -677,5 +721,5 @@ }) - checkResponses(self.T(), self.frontend2.events, []string{ + checkResponses(self.T(), self.frontend2.events.Get(), []string{ // Rekey this FE "4 request: /server.pem", @@ -703,5 +747,6 @@ clock := &FakeClock{ MockClock: mock_clock, - events: &self.frontend1.events} + events: self.frontend1.events, + } ctx, cancel := context.WithCancel(context.Background()) @@ -740,9 +785,9 @@ !URGENT, crypto_proto.PackedMessageList_ZCOMPRESSION) - //utils.Debug(self.frontend1.events) - //utils.Debug(self.frontend2.events) + //utils.Debug(self.frontend1.events.Get()) + //utils.Debug(self.frontend2.events.Get()) // Message ordering is important - checkResponses(self.T(), self.frontend1.events, []string{ + checkResponses(self.T(), self.frontend1.events.Get(), []string{ // First request looks for server.pem is ok. "0 request: /server.pem", @@ -754,5 +799,5 @@ // Immediately switch to FE1 (no sleep) - "10 sleep: 10", + "10 sleep: 10m0s\n", "11 request: /server.pem", "12 response: -----BEGIN CERTIFICATE-", @@ -765,9 +810,9 @@ // Now must sleep since we tried all endpoints and // they all failed. - "15 sleep: 10", - "16 sleep: 10", + "15 sleep: 10m0s\n", + "16 sleep: 10m0s\n", }) - checkResponses(self.T(), self.frontend2.events, []string{ + checkResponses(self.T(), self.frontend2.events.Get(), []string{ // Rekey FE2 "4 request: /server.pem", @@ -801,5 +846,6 @@ clock := &FakeClock{ MockClock: mock_clock, - events: &self.frontend1.events} + events: self.frontend1.events, + } ctx, cancel := context.WithCancel(context.Background()) @@ -831,6 +877,6 @@ !URGENT, crypto_proto.PackedMessageList_ZCOMPRESSION) - //utils.Debug(self.frontend1.events) - //utils.Debug(self.frontend2.events) + //utils.Debug(self.frontend1.events.Get()) + //utils.Debug(self.frontend2.events.Get()) // Multiple redirections should not add duplicates to the url list. @@ -839,5 +885,5 @@ // Message ordering is important - checkResponses(self.T(), self.frontend1.events, []string{ + checkResponses(self.T(), self.frontend1.events.Get(), []string{ // First request looks for server.pem is ok. "0 request: /server.pem", @@ -848,5 +894,5 @@ "3 response: 301", - "8 sleep: 10", + "8 sleep: 10m0s\n", // Immediately switch to FE1 (no sleep) @@ -858,5 +904,5 @@ }) - checkResponses(self.T(), self.frontend2.events, []string{ + checkResponses(self.T(), self.frontend2.events.Get(), []string{ // Rekey FE2 "4 request: /server.pem", @@ -869,7 +915,7 @@ } -func checkResponses(t *testing.T, expected []string, seen []string) { +func checkResponses(t *testing.T, seen []string, expected []string) { for idx, seen_line := range seen { - assert.Contains(t, expected[idx], seen_line) + assert.Contains(t, seen_line, expected[idx]) } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/http_comms/ring_buffer.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/http_comms/ring_buffer.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/http_comms/ring_buffer.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/http_comms/ring_buffer.go 2025-11-01 15:52:20.000000000 +0000 @@ -9,4 +9,5 @@ "sync" + "github.com/Velocidex/ordereddict" "github.com/go-errors/errors" "github.com/sirupsen/logrus" @@ -19,4 +20,5 @@ "www.velocidex.com/golang/velociraptor/responder" "www.velocidex.com/golang/velociraptor/utils" + "www.velocidex.com/golang/vfilter" ) @@ -35,4 +37,7 @@ type IRingBuffer interface { + ProfileWriter(ctx context.Context, scope vfilter.Scope, + output_chan chan vfilter.Row) + Enqueue(item []byte) @@ -49,4 +54,7 @@ Commit() + Rollback() + + // Clear the buffer Reset() Close() @@ -102,5 +110,11 @@ } +type transaction struct { + LeasedPointer int64 + LeasedBytes int64 +} + type FileBasedRingBuffer struct { + id uint64 config_obj *config_proto.Config @@ -121,4 +135,20 @@ flow_manager *responder.FlowManager + + current_transaction transaction +} + +func (self *FileBasedRingBuffer) ProfileWriter( + ctx context.Context, scope vfilter.Scope, + output_chan chan vfilter.Row) { + self.mu.Lock() + defer self.mu.Unlock() + + output_chan <- ordereddict.NewDict(). + Set("Type", "FileBasedRingBuffer"). + Set("Filename", self.fd.Name()). + Set("Header", self.header). + Set("Closed", self.closed). + Set("Transaction", self.current_transaction) } @@ -134,10 +164,10 @@ _, err := self.fd.WriteAt(self.write_buf, int64(self.header.WritePointer)) if err != nil { - self.Reset() + self._Truncate() return } n, err := self.fd.WriteAt(item, int64(self.header.WritePointer+8)) if err != nil { - self.Reset() + self._Truncate() return } @@ -149,5 +179,5 @@ _, err = self.fd.WriteAt(serialized, 0) if err != nil { - self.Reset() + self._Truncate() return } @@ -226,4 +256,9 @@ result := []byte{} + // Take a snapshot of the current file state. + if self.current_transaction.LeasedPointer == 0 { + self.current_transaction.LeasedPointer = self.leased_pointer + } + for self.header.WritePointer > self.leased_pointer { n, err := self.fd.ReadAt(self.read_buf, self.leased_pointer) @@ -233,8 +268,10 @@ // File might be corrupt - just reset the entire file. if length > constants.MAX_MEMORY*2 || length <= 0 { - self.log_ctx.Error("Possible corruption detected - item length is too large.") + self.log_ctx.Error( + "Possible corruption detected - item length is too large.") self._Truncate() return nil } + item := make([]byte, length) n, err := self.fd.ReadAt(item, self.leased_pointer+8) @@ -258,4 +295,6 @@ self.header.AvailableBytes -= int64(n) + self.current_transaction.LeasedBytes += int64(n) + if uint64(len(result)) > size { break @@ -267,5 +306,4 @@ } } - return result } @@ -279,4 +317,6 @@ self.header.AvailableBytes = 0 self.header.LeasedBytes = 0 + self.current_transaction.LeasedBytes = 0 + self.current_transaction.LeasedPointer = 0 self.leased_pointer = FirstRecordOffset @@ -307,4 +347,21 @@ // closed. self.c.Broadcast() + + Tracker.Register(self.id, nil) +} + +// Undo the actions of Leased() and put the data back. +func (self *FileBasedRingBuffer) Rollback() { + self.mu.Lock() + defer self.mu.Unlock() + + self.log_ctx.Debug("FileBasedRingBuffer: Rollback %v bytes.", + self.current_transaction.LeasedBytes) + + self.leased_pointer = self.current_transaction.LeasedPointer + self.header.AvailableBytes += self.current_transaction.LeasedBytes + self.header.LeasedBytes -= self.current_transaction.LeasedBytes + self.current_transaction.LeasedBytes = 0 + self.current_transaction.LeasedPointer = 0 } @@ -323,4 +380,6 @@ self.header.ReadPointer = self.leased_pointer self.header.LeasedBytes = 0 + self.current_transaction.LeasedBytes = 0 + self.current_transaction.LeasedPointer = 0 serialized, _ := self.header.MarshalBinary() @@ -421,4 +480,5 @@ result := &FileBasedRingBuffer{ + id: utils.GetId(), config_obj: config_obj, fd: fd, @@ -438,8 +498,12 @@ }).Info("FileBasedRingBuffer: Creation") + Tracker.Register(result.id, result) + return result, nil } type RingBuffer struct { + id uint64 + name string config_obj *config_proto.Config @@ -469,4 +533,19 @@ } +func (self *RingBuffer) ProfileWriter( + ctx context.Context, scope vfilter.Scope, + output_chan chan vfilter.Row) { + self.mu.Lock() + defer self.mu.Unlock() + + output_chan <- ordereddict.NewDict(). + Set("Type", self.name). + Set("Messages", len(self.messages)). + Set("LeasedIdx", self.leased_idx). + Set("LeasedLength", self.leased_length). + Set("MaxSize", self.Size). + Set("CurrentSize", self.total_length) +} + func (self *RingBuffer) Reset() { self.mu.Lock() @@ -631,4 +710,5 @@ self.messages = nil self.c.Broadcast() + Tracker.Register(self.id, nil) } @@ -659,7 +739,12 @@ } -func NewRingBuffer(config_obj *config_proto.Config, - flow_manager *responder.FlowManager, size uint64) *RingBuffer { +func NewRingBuffer( + config_obj *config_proto.Config, + flow_manager *responder.FlowManager, + size uint64, + name string) *RingBuffer { result := &RingBuffer{ + id: utils.GetId(), + name: name, messages: make([][]byte, 0), Size: size, @@ -669,4 +754,6 @@ result.c = sync.NewCond(&result.mu) + Tracker.Register(result.id, result) + return result } @@ -709,4 +796,4 @@ } return NewRingBuffer(config_obj, flow_manager, - config_obj.Client.LocalBuffer.MemorySize) + config_obj.Client.LocalBuffer.MemorySize, "FlowBuffer") } Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/http_comms: ring_buffer_tracker.go diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/http_comms/sender.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/http_comms/sender.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/http_comms/sender.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/http_comms/sender.go 2025-11-01 15:52:20.000000000 +0000 @@ -86,4 +86,5 @@ return case <-self.clock.After(self.minPoll): + executor.Nanny.UpdatePumpToRb() continue } @@ -175,7 +176,4 @@ func (self *Sender) PumpRingBufferToSendMessage(ctx context.Context) { - // We should never exit from this. - defer self.maybeCallOnExit() - compression := crypto_proto.PackedMessageList_ZCOMPRESSION if self.config_obj.Client.DisableCompression { @@ -192,5 +190,9 @@ if len(compressed_messages) > 0 { self.sendMessageList(ctx, compressed_messages, URGENT, compression) - self.urgent_buffer.Commit() + if utils.IsCtxDone(ctx) { + self.ring_buffer.Rollback() + } else { + self.ring_buffer.Commit() + } } @@ -204,5 +206,9 @@ // from the ring buffer. self.sendMessageList(ctx, compressed_messages, !URGENT, compression) - self.ring_buffer.Commit() + if utils.IsCtxDone(ctx) { + self.ring_buffer.Rollback() + } else { + self.ring_buffer.Commit() + } } } @@ -246,5 +252,23 @@ go func() { defer wg.Done() - self.PumpRingBufferToSendMessage(ctx) + + // We should never exit from this. + defer self.maybeCallOnExit() + + for { + select { + case <-ctx.Done(): + return + default: + } + + // Allow cancellation of the main loop. This will restart + // it as needed. + sub_ctx, cancel := context.WithCancel(ctx) + self.cancel = cancel + + self.PumpRingBufferToSendMessage(sub_ctx) + cancel() + } }() @@ -285,9 +309,16 @@ // skip the buffer ahead of normal queries. urgent_buffer: NewRingBuffer(config_obj, executor.FlowManager(), - 2*config_obj.Client.MaxUploadSize), + 2*config_obj.Client.MaxUploadSize, "UrgentBuffer"), release: make(chan bool), clock: clock, } + executor.Nanny().RegisterOnWarnings(result.id, func() { + result.logger.Info( + "%s: Nanny issued first warning! Restarting Sender comms", + result.name) + result.Restart() + }) + return result, nil } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/http_comms/sender_test.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/http_comms/sender_test.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/http_comms/sender_test.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/http_comms/sender_test.go 2025-11-01 15:52:20.000000000 +0000 @@ -219,5 +219,5 @@ // message but no more. flow_manager := responder.NewFlowManager(ctx, config_obj, "") - rb := NewRingBuffer(config_obj, flow_manager, 10) + rb := NewRingBuffer(config_obj, flow_manager, 10, "Sender") testRingBuffer(ctx, rb, config_obj, "0123456789", t) } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/http_comms/service.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/http_comms/service.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/http_comms/service.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/http_comms/service.go 2025-11-01 15:52:20.000000000 +0000 @@ -44,5 +44,7 @@ exe, config_obj.Client.ServerUrls, - func() { on_error(ctx, config_obj) }, + func() { + on_error(ctx, config_obj) + }, utils.RealClock{}, ) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/http_comms/websocket.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/http_comms/websocket.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/http_comms/websocket.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/http_comms/websocket.go 2025-11-01 15:52:20.000000000 +0000 @@ -5,5 +5,4 @@ "context" "io" - "io/ioutil" "net" "net/http" @@ -17,4 +16,5 @@ "github.com/prometheus/client_golang/prometheus/promauto" 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/executor" @@ -22,4 +22,5 @@ "www.velocidex.com/golang/velociraptor/logging" "www.velocidex.com/golang/velociraptor/utils" + "www.velocidex.com/golang/velociraptor/utils/faults" ) @@ -109,5 +110,4 @@ conn, err := self.getConnection(req) if err != nil { - utils.DlvBreak() return nil, err } @@ -116,5 +116,6 @@ var data []byte if req.Body != nil { - data, _ = ioutil.ReadAll(req.Body) + data, _ = utils.ReadAllWithLimit(req.Body, constants.MAX_MEMORY) + faults.FaultInjector.BlockHTTPDo(req.Context()) } @@ -225,10 +226,5 @@ deadline := utils.Now().Add(PongPeriod(config_obj)) - err = ws.SetReadDeadline(deadline) - if err != nil { - return 0, nil, err - } - - messageType, r, err := ws.NextReader() + messageType, r, err := ws.NextReaderWithDeadline(deadline) if err != nil { return messageType, nil, err diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/http_comms/websocket_connection.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/http_comms/websocket_connection.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/http_comms/websocket_connection.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/http_comms/websocket_connection.go 2025-11-01 15:52:20.000000000 +0000 @@ -3,4 +3,5 @@ import ( "context" + "io" "net" "net/http" @@ -23,7 +24,143 @@ // synchronize it. type Conn struct { - *websocket.Conn + conn *websocket.Conn + key string - mu sync.Mutex + // report stats in lock free way for the profile tracker. + stats *ConnStats + + read_mu sync.Mutex + write_mu sync.Mutex +} + +func NewWS(key string, ws *websocket.Conn) *Conn { + res := &Conn{ + conn: ws, + key: key, + stats: &ConnStats{ + create_time: utils.GetTime().Now(), + id: utils.GetId(), + }, + } + + wsTracker.Register(key, res) + + return res +} + +func (self *Conn) SetPingHandler(h func(message string) error) { + self.conn.SetPingHandler(func(message string) error { + self.stats.SetLastPing(utils.GetTime().Now()) + + return h(message) + }) +} + +func (self *Conn) SetPongHandler(config_obj *config_proto.Config) { + self.conn.SetPongHandler(func(string) error { + + // On the server this is the best estimate of the last ping we + // sent. + self.stats.SetLastPing(utils.GetTime().Now()) + + // Called with read_mu already held + deadline := utils.Now().Add(PongPeriod(config_obj)) + return self._SetReadDeadline(deadline) + }) +} + +func (self *Conn) Close() { + // The Close and WriteControl methods can be called concurrently + // with all other methods. + self.conn.Close() + + wsTracker.Unregister(self.key) +} + +func (self *Conn) SetReadDeadline(deadline time.Time) error { + self.read_mu.Lock() + defer self.read_mu.Unlock() + + self.stats.SetReadLock(true) + defer self.stats.SetReadLock(false) + + return self._SetReadDeadline(deadline) +} + +func (self *Conn) _SetReadDeadline(deadline time.Time) error { + stats := self.stats.Get() + + if deadline.Before(stats.read_deadline) { + return nil + } + + self.stats.SetReadDeadline(deadline) + return self.conn.SetReadDeadline(deadline) +} + +func (self *Conn) GetStats() *ConnStats { + return self.stats.Get() +} + +func (self *Conn) SetWriteDeadline(deadline time.Time) error { + self.write_mu.Lock() + defer self.write_mu.Unlock() + + self.stats.SetWriteLock(true) + defer self.stats.SetWriteLock(false) + + return self._SetWriteDeadline(deadline) +} + +func (self *Conn) _SetWriteDeadline(deadline time.Time) error { + stats := self.stats.Get() + + if deadline.Before(stats.write_deadline) { + return nil + } + + self.stats.SetWriteDeadline(deadline) + return self.conn.SetWriteDeadline(deadline) +} + +func (self *Conn) ReadMessage() (messageType int, p []byte, err error) { + self.read_mu.Lock() + defer self.read_mu.Unlock() + + self.stats.SetReadLock(true) + defer self.stats.SetReadLock(false) + + return self.conn.ReadMessage() +} + +func (self *Conn) SetReadLimit(limit int64) { + self.read_mu.Lock() + defer self.read_mu.Unlock() + + self.stats.SetReadLock(true) + defer self.stats.SetReadLock(false) + + self.conn.SetReadLimit(limit) +} + +func (self *Conn) WriteControl(messageType int, data []byte, deadline time.Time) error { + // The Close and WriteControl methods can be called concurrently + // with all other methods. + return self.conn.WriteControl(messageType, data, deadline) +} + +func (self *Conn) NextReaderWithDeadline(deadline time.Time) (int, io.Reader, error) { + self.read_mu.Lock() + defer self.read_mu.Unlock() + + self.stats.SetReadLock(true) + defer self.stats.SetReadLock(false) + + err := self._SetReadDeadline(deadline) + if err != nil { + return 0, nil, err + } + + return self.conn.NextReader() } @@ -31,19 +168,25 @@ func (self *Conn) WriteMessageWithDeadline( message_type int, message []byte, deadline time.Time) error { - self.mu.Lock() - defer self.mu.Unlock() + self.write_mu.Lock() + defer self.write_mu.Unlock() - err := self.Conn.SetWriteDeadline(deadline) + self.stats.SetWriteLock(true) + defer self.stats.SetWriteLock(false) + + err := self._SetWriteDeadline(deadline) if err != nil { return err } - return self.Conn.WriteMessage(message_type, message) + return self.conn.WriteMessage(message_type, message) } func (self *Conn) WriteMessage(message_type int, message []byte) error { - self.mu.Lock() - defer self.mu.Unlock() + self.write_mu.Lock() + defer self.write_mu.Unlock() + + self.stats.SetWriteLock(true) + defer self.stats.SetWriteLock(false) - return self.Conn.WriteMessage(message_type, message) + return self.conn.WriteMessage(message_type, message) } @@ -116,8 +259,7 @@ func (self *WebSocketConnection) Close() { - self.mu.Lock() - defer self.mu.Unlock() - - self.cancel() + if self.cancel != nil { + self.cancel() + } self.ws.Close() } @@ -166,25 +308,4 @@ } - ws := &Conn{Conn: ws_} - - ctx, cancel := context.WithCancel(ctx) - - res := &WebSocketConnection{ - // Emulate regular HTTP responses from the server, but these - // are actually sent over the websocket connection. This - // allows the transport to work with or without websocket - // automatically. - from_server: make(chan *http.Response), - to_server: make(chan []byte), - cancel: cancel, - ctx: ctx, - config_obj: self.config_obj, - max_poll: time.Duration(max_poll) * time.Second, - transport: self.transport, - ws: ws, - key: key, - id: utils.GetId(), - } - // Log when ping messages arrive from the server. The server is // responsible for pinging the client periodically. If the @@ -193,6 +314,9 @@ // triggered to tear the connection down. logger := logging.GetLogger(self.config_obj, &logging.ClientComponent) + + ws := NewWS(key, ws_) + ws.SetPingHandler(func(message string) error { - logger.Debug("Socket %v: Received Ping", res.key) + logger.Debug("Socket %v: Received Ping", key) deadline := utils.GetTime().Now().Add(PongPeriod(self.config_obj)) @@ -200,15 +324,14 @@ // Extend the read and write timeouts when a ping arrives from // the server. - err := ws.SetReadDeadline(deadline) - if err != nil { - return err - } - err = ws.SetWriteDeadline(deadline) - if err != nil { - return err - } + // This ping handler is called from NextReaderWithDeadline and + // so it is already holding the read lock. + _ = ws._SetReadDeadline(deadline) + + // We must set the write deadline with a lock since we are + // called with the read lock. + _ = ws.SetWriteDeadline(deadline) - err = ws.WriteControl(websocket.PongMessage, + err = ws_.WriteControl(websocket.PongMessage, []byte(message), utils.GetTime().Now().Add(writeWait)) if err == websocket.ErrCloseSent { @@ -224,6 +347,26 @@ }) + ctx, cancel := context.WithCancel(ctx) + + res := &WebSocketConnection{ + // Emulate regular HTTP responses from the server, but these + // are actually sent over the websocket connection. This + // allows the transport to work with or without websocket + // automatically. + from_server: make(chan *http.Response), + to_server: make(chan []byte), + cancel: cancel, + ctx: ctx, + config_obj: self.config_obj, + max_poll: time.Duration(max_poll) * time.Second, + transport: self.transport, + ws: ws, + key: key, + id: utils.GetId(), + } + // Pump messages from the remote server to the channel. go func() { + defer ws.Close() defer self.removeConnection(req, res.Id()) @@ -233,4 +376,5 @@ // Pump messages from the channel to the remote server. go func() { + defer ws.Close() defer self.removeConnection(req, res.Id()) Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/http_comms: websocket_tracker.go diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/json/protobuf.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/json/protobuf.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/json/protobuf.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/json/protobuf.go 2025-11-01 15:52:20.000000000 +0000 @@ -104,5 +104,7 @@ case protoreflect.EnumKind: value_descriptor := field.Enum().Values().ByNumber(value.Enum()) - result.Set(field_name, string(value_descriptor.Name())) + if value_descriptor != nil { + result.Set(field_name, string(value_descriptor.Name())) + } case protoreflect.MessageKind: Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75: license-report.txt diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/logging/logging.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/logging/logging.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/logging/logging.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/logging/logging.go 2025-11-01 15:52:20.000000000 +0000 @@ -160,5 +160,5 @@ for _, msg := range lprelogs { - logger.Info(msg) + logger.Info("%s", msg) } prelogs = make([]string, 0) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/magefile.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/magefile.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/magefile.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/magefile.go 2025-11-01 15:52:20.000000000 +0000 @@ -26,4 +26,5 @@ "errors" "fmt" + "io" "io/ioutil" "os" @@ -66,4 +67,9 @@ ) +func ReadAllWithLimit( + fd io.Reader, limit int) ([]byte, error) { + return ioutil.ReadAll(io.LimitReader(fd, int64(limit))) +} + type Builder struct { goos string @@ -86,12 +92,12 @@ func (self *Builder) Name() string { - if self.filename != "" { - return self.filename - } - if self.goos == "windows" { self.extension = ".exe" } + if self.filename != "" { + return self.filename + self.extension + } + name := fmt.Sprintf("%s-%s-%s-%s%s", name, version, @@ -376,5 +382,5 @@ goos: "windows", extra_tags: " release yara ", - filename: "velociraptor.exe", + filename: "velociraptor", arch: "amd64"}.Run() } @@ -389,5 +395,5 @@ goos: "windows", extra_tags: " release yara ", - filename: "velociraptor.exe", + filename: "velociraptor", arch: "amd64", extra_flags: []string{"-race"}}.Run() @@ -445,5 +451,6 @@ func Clean() error { for _, target := range assets { - err := sh.Rm(target) + go_target := filepath.Join(filepath.Dir(target), "ab0x.go") + err := sh.Rm(go_target) if err != nil { return err @@ -613,5 +620,5 @@ defer fd.Close() - data, err := ioutil.ReadAll(fd) + data, err := ReadAllWithLimit(fd, constants.MAX_MEMORY) if err != nil { return err @@ -714,5 +721,5 @@ } - data, err := ioutil.ReadAll(fd) + data, err := ReadAllWithLimit(fd, constants.MAX_MEMORY) if err != nil { return err @@ -729,5 +736,8 @@ ignore_matches := regexp.MustCompile(strings.Join(ignore.IgnoreMatches, "|")) - out, err := sh.OutCmd("deadcode")("-tags", "server_vql extras", "-json", "./bin") + // go install golang.org/x/tools/cmd/deadcode@latest + out, err := sh.OutputWith(map[string]string{ + "GOOS": "windows", + }, "deadcode", "-tags", "server_vql extras", "-json", "./bin") if err != nil { return err diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/reporting/container.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/reporting/container.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/reporting/container.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/reporting/container.go 2025-11-01 15:52:20.000000000 +0000 @@ -43,4 +43,11 @@ ZipRootPath = accessors.MustNewZipFilePath("/") + + pool = sync.Pool{ + New: func() interface{} { + buffer := make([]byte, 1024*1024) + return &buffer + }, + } ) @@ -380,7 +387,20 @@ btime time.Time, mode os.FileMode, - reader io.ReadSeeker) (*uploads.UploadResponse, error) { + reader io.ReadSeeker) (res *uploads.UploadResponse, res_err error) { - result := &uploads.UploadResponse{ + // The filename to store the file inside the zip - due to escaping + // issues this may not be exactly the same as the file name we + // receive. + if store_as_name == nil { + store_as_name = filename + } + + result, closer := uploads.DeduplicateUploads(scope, store_as_name) + defer closer(result) + if result != nil { + return result, nil + } + + result = &uploads.UploadResponse{ Path: formatFilename(filename, accessor), Size: uint64(expected_size), @@ -394,17 +414,4 @@ } - // The filename to store the file inside the zip - due to escaping - // issues this may not be exactly the same as the file name we - // receive. - if store_as_name == nil { - store_as_name = filename - } - - cached, pres, closer := uploads.DeduplicateUploads(scope, store_as_name) - defer closer() - if pres { - return cached, nil - } - store_path, err := accessors.NewZipFilePath("uploads") if err != nil { @@ -434,6 +441,5 @@ self.uploads = append(self.uploads, result) self.mu.Unlock() - - uploads.CacheUploadResult(scope, store_as_name, result) + closer(result) return result, nil } @@ -443,5 +449,8 @@ return nil, err } - defer writer.Close() + + defer func() { + res_err = writer.Close() + }() files.Add(result.StoredName) @@ -462,8 +471,12 @@ defer cancel() - count, err := utils.Copy(ctx, tee_writer, reader) + buff := pool.Get().(*[]byte) + defer pool.Put(buff) + + count, err := utils.CopyWithBuffer(ctx, tee_writer, reader, *buff) if err != nil { result.StoredSize = uint64(count) result.Error = err.Error() + closer(result) return result, err } @@ -481,5 +494,5 @@ self.stats_mu.Unlock() - uploads.CacheUploadResult(scope, store_as_name, result) + closer(result) return result, nil } @@ -560,5 +573,5 @@ // so we pad with zeros. if int64(n) < rng.Length { - scope.Log("Unable to fully copy range %v in %v - padding %v bytes", + scope.Log("Unable to fully copy range %#v in %v - padding %v bytes", rng, result.StoredName, rng.Length-int64(n)) _, _ = utils.CopyN( @@ -723,5 +736,5 @@ res, err := NewContainerFromWriter(path, config_obj, - fd, password, level, metadata) + NewBufferedCloser(fd), password, level, metadata) if err != nil { return nil, err diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/reporting/tmpfiles.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/reporting/tmpfiles.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/reporting/tmpfiles.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/reporting/tmpfiles.go 2025-11-01 15:52:20.000000000 +0000 @@ -2,28 +2,114 @@ import ( + "bufio" + "bytes" + "io" + "io/ioutil" "os" - concurrent_zip "github.com/Velocidex/zip" - "www.velocidex.com/golang/velociraptor/utils/tempfile" + "github.com/Velocidex/zip" ) -type TmpfileFactory int +type BufferedCloser struct { + *bufio.Writer + fd *os.File +} + +func (self *BufferedCloser) Name() string { + return self.fd.Name() +} + +func (self *BufferedCloser) Close() error { + self.Writer.Flush() + return self.fd.Close() +} + +func NewBufferedCloser(fd *os.File) *BufferedCloser { + return &BufferedCloser{ + Writer: bufio.NewWriterSize(fd, 1024*1204), + fd: fd, + } +} + +// A tempfile that writes to memory until a certain zip, then switches +// to file based if the size is exceeded. This saves unnecessary IO +// for small files. +type BufferedTmpFile struct { + file zip.TempFile + buffer *bytes.Buffer + max_size int +} -func (self TmpfileFactory) TempFile() (*os.File, error) { - tmpfile, err := tempfile.TempFile("zip") - if err != nil { - return nil, err +func (self *BufferedTmpFile) Write(buff []byte) (int, error) { + if self.file != nil { + return self.file.Write(buff) } - tempfile.AddTmpFile(tmpfile.Name()) - return tmpfile, nil + // Switch to tmpfile backing if the write will exceed the buffer + // size. + if self.buffer.Len()+len(buff) > self.max_size { + new_tmpfile, err := zip.DefaultTmpfileProvider(0).TempFile() + if err != nil { + return 0, err + } + + self.file = new_tmpfile + _, err = new_tmpfile.Write(self.buffer.Bytes()) + if err != nil { + return 0, err + } + n, err := new_tmpfile.Write(buff) + if err != nil { + return 0, err + } + self.buffer = nil + + return n, err + } + + return self.buffer.Write(buff) } -func (self TmpfileFactory) RemoveTempFile(filename string) { - err := os.Remove(filename) - tempfile.RemoveTmpFile(filename, err) +func (self *BufferedTmpFile) Close() error { + self.buffer = nil + if self.file != nil { + return self.file.Close() + } + return nil +} + +// Returns a reader to the tmp file. +func (self *BufferedTmpFile) Open() (io.ReadCloser, error) { + if self.file != nil { + return self.file.Open() + } + return ioutil.NopCloser(self.buffer), nil +} + +func (self *BufferedTmpFile) Remove() { + if self.file != nil { + self.file.Remove() + } +} + +func (self *BufferedTmpFile) Name() string { + if self.file != nil { + return self.file.Name() + } + return "memory" +} + +type TmpfileProvider int + +func (self TmpfileProvider) TempFile() (zip.TempFile, error) { + res := &BufferedTmpFile{ + max_size: 1024 * 1204, + buffer: &bytes.Buffer{}, + } + res.buffer.Grow(res.max_size) + return res, nil } func init() { - concurrent_zip.SetTmpfileProvider(TmpfileFactory(0)) + zip.SetTmpfileProvider(TmpfileProvider(0)) } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/reporting/uploader.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/reporting/uploader.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/reporting/uploader.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/reporting/uploader.go 2025-11-01 15:52:20.000000000 +0000 @@ -45,8 +45,8 @@ } - cached, pres, closer := uploads.DeduplicateUploads(scope, store_as_name) - defer closer() - if pres { - return cached, nil + result, closer := uploads.DeduplicateUploads(scope, store_as_name) + defer closer(result) + if result != nil { + return result, nil } @@ -72,5 +72,5 @@ } - result := &uploads.UploadResponse{ + result = &uploads.UploadResponse{ Path: res.Path, StoredName: store_as_name.String(), @@ -82,6 +82,5 @@ Md5: res.Md5, } - - uploads.CacheUploadResult(scope, store_as_name, result) + closer(result) return result, nil } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/scripts/api_checker.py /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/scripts/api_checker.py --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/scripts/api_checker.py 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/scripts/api_checker.py 2025-11-01 15:52:20.000000000 +0000 @@ -55,4 +55,12 @@ allowed=re.compile("Use append()"), replaced="Use built in operations append and avoid slices package"), + + Check(re=re.compile("math/rand"), + allowed=re.compile("utils/rand"), + replaced="/utils/rand"), + + Check(re=re.compile("ioutil.ReadAll"), + allowed=re.compile("magefile.go|/utils/copy|_test.go$"), + replaced="utils.ReadAllWithCtx"), ] diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/server/comms.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/server/comms.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/server/comms.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/server/comms.go 2025-11-01 15:52:20.000000000 +0000 @@ -25,6 +25,4 @@ "html" "io" - "io/ioutil" - "math/rand" "net/http" "net/url" @@ -33,4 +31,6 @@ "time" + "www.velocidex.com/golang/velociraptor/utils/rand" + "www.velocidex.com/golang/velociraptor/crypto" "www.velocidex.com/golang/velociraptor/datastore" @@ -507,6 +507,5 @@ sendCounter.Inc() - body, err := ioutil.ReadAll( - io.LimitReader(req.Body, constants.MAX_MEMORY)) + body, err := utils.ReadAllWithLimit(req.Body, constants.MAX_MEMORY) if err != nil { server_obj.Error("Unable to read body: %v", err) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/server/server.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/server/server.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/server/server.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/server/server.go 2025-11-01 15:52:20.000000000 +0000 @@ -22,5 +22,4 @@ "context" "errors" - "fmt" "runtime" "sync" @@ -163,5 +162,5 @@ err = enroll(ctx, config_obj, self, message.CSR) if err != nil { - self.logger.Error(fmt.Sprintf("Enrol Error: %s", err)) + self.logger.Error("Enrol Error: %s", err) } return err diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/server/websocket.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/server/websocket.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/server/websocket.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/server/websocket.go 2025-11-01 15:52:20.000000000 +0000 @@ -5,4 +5,5 @@ "encoding/json" "errors" + "fmt" "net/http" "time" @@ -15,5 +16,4 @@ "www.velocidex.com/golang/velociraptor/crypto" "www.velocidex.com/golang/velociraptor/http_comms" - "www.velocidex.com/golang/velociraptor/logging" "www.velocidex.com/golang/velociraptor/services" "www.velocidex.com/golang/velociraptor/utils" @@ -33,5 +33,5 @@ "Only a single instance of the client is " + "allowed to connect at the same time.") - notConnectedError = errors.New("WS Socket is not conencted") + notConnectedError = errors.New("WS Socket is not connected") currentWSConnections = promauto.NewGauge(prometheus.GaugeOpts{ @@ -59,5 +59,7 @@ defer ws_.Close() - ws := &http_comms.Conn{Conn: ws_} + key := fmt.Sprintf("server_pem->%v", req.RemoteAddr) + ws := http_comms.NewWS(key, ws_) + defer ws.Close() for { @@ -88,11 +90,10 @@ defer ws_.Close() - ws := &http_comms.Conn{Conn: ws_} + // We are receiving messages from the endpoint + key := fmt.Sprintf("<-%v", req.RemoteAddr) + ws := http_comms.NewWS(key, ws_) + defer ws.Close() - ws.SetPongHandler(func(string) error { - deadline := utils.Now().Add( - http_comms.PongPeriod(config_obj)) - return ws.SetReadDeadline(deadline) - }) + ws.SetPongHandler(config_obj) ctx, cancel := context.WithCancel(req.Context()) @@ -106,5 +107,5 @@ return case <-utils.GetTime().After(http_comms.PingWait(config_obj)): - _ = send_ping(ws, config_obj) + send_ping(ws, config_obj) } } @@ -231,5 +232,8 @@ defer ws_.Close() - ws := &http_comms.Conn{Conn: ws_} + // Sending messages to the client + key := fmt.Sprintf("->%v", req.RemoteAddr) + ws := http_comms.NewWS(key, ws_) + defer ws.Close() // Keep track of currently connected clients. @@ -237,9 +241,5 @@ defer currentWSConnections.Dec() - ws.SetPongHandler(func(string) error { - deadline := utils.Now().Add(http_comms.PongPeriod(config_obj)) - _ = ws.SetReadDeadline(deadline) - return nil - }) + ws.SetPongHandler(config_obj) ctx, cancel := context.WithCancel(req.Context()) @@ -336,5 +336,4 @@ // Check for conflicting clients if notifier.IsClientDirectlyConnected(source) { - // Send a message that there is a client conflict. journal, err := services.GetJournal(org_config_obj) @@ -358,14 +357,10 @@ go func() { defer cancel() + defer ws.Close() for { deadline := utils.Now().Add(http_comms.PongPeriod(config_obj)) - err := ws.SetReadDeadline(deadline) - if err != nil { - logger := logging.GetLogger(config_obj, &logging.FrontendComponent) - logger.Error("ws_send_client_messages SetReadDeadline %v", err) - } - - _, _, err = ws.NextReader() + _, _, err = ws.NextReaderWithDeadline(deadline) + fmt.Printf("NextReaderWithDeadline %v\n", err) if err != nil { return diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/client_info/client_info.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/client_info/client_info.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/client_info/client_info.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/client_info/client_info.go 2025-11-01 15:52:20.000000000 +0000 @@ -541,5 +541,6 @@ record, err := self.storage.GetRecord(client_id) if err != nil { - return nil, err + return nil, fmt.Errorf("Client ID %v not known in this org: %w", + client_id, err) } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/client_info/storage.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/client_info/storage.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/client_info/storage.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/client_info/storage.go 2025-11-01 15:52:20.000000000 +0000 @@ -29,5 +29,4 @@ "errors" "fmt" - "os" "regexp" "strings" @@ -144,5 +143,5 @@ serialized, pres := self.data[client_id] if !pres { - return nil, os.ErrNotExist + return nil, utils.NotFoundError } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/client_monitoring/client_monitoring.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/client_monitoring/client_monitoring.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/client_monitoring/client_monitoring.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/client_monitoring/client_monitoring.go 2025-11-01 15:52:20.000000000 +0000 @@ -19,7 +19,8 @@ "context" "errors" - "math/rand" "sync" + "www.velocidex.com/golang/velociraptor/utils/rand" + "github.com/Velocidex/ordereddict" "github.com/google/uuid" @@ -352,7 +353,4 @@ } event.MaxWait += uint64(rand.Intn(int(jitter))) - - // Event queries never time out - event.Timeout = 99999999 } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/ddclient/cloudflare.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/ddclient/cloudflare.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/ddclient/cloudflare.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/ddclient/cloudflare.go 2025-11-01 15:52:20.000000000 +0000 @@ -40,5 +40,4 @@ "fmt" "io" - "io/ioutil" "net/http" "strings" @@ -48,4 +47,5 @@ "www.velocidex.com/golang/velociraptor/json" "www.velocidex.com/golang/velociraptor/logging" + "www.velocidex.com/golang/velociraptor/utils" "www.velocidex.com/golang/velociraptor/vql/networking" ) @@ -116,5 +116,5 @@ defer resp.Body.Close() - res_body, err := ioutil.ReadAll(resp.Body) + res_body, err := utils.ReadAllWithLimit(resp.Body, constants.MAX_MEMORY) if err != nil { return nil, err diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/ddclient/ddclient.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/ddclient/ddclient.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/ddclient/ddclient.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/ddclient/ddclient.go 2025-11-01 15:52:20.000000000 +0000 @@ -7,5 +7,4 @@ "errors" "io" - "io/ioutil" "net" "net/http" @@ -15,5 +14,7 @@ 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/utils" ) @@ -173,5 +174,5 @@ } defer resp.Body.Close() - ip, err := ioutil.ReadAll(resp.Body) + ip, err := utils.ReadAllWithLimit(resp.Body, constants.MAX_MEMORY) result := strings.TrimSpace(string(ip)) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/ddclient/noip.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/ddclient/noip.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/ddclient/noip.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/ddclient/noip.go 2025-11-01 15:52:20.000000000 +0000 @@ -33,5 +33,4 @@ "errors" "fmt" - "io/ioutil" "net/http" "strings" @@ -41,4 +40,5 @@ "www.velocidex.com/golang/velociraptor/constants" "www.velocidex.com/golang/velociraptor/logging" + "www.velocidex.com/golang/velociraptor/utils" "www.velocidex.com/golang/velociraptor/vql/networking" ) @@ -92,5 +92,5 @@ defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) + body, err := utils.ReadAllWithLimit(req.Body, constants.MAX_MEMORY) if err != nil { return err diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/frontend.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/frontend.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/frontend.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/frontend.go 2025-11-01 15:52:20.000000000 +0000 @@ -5,5 +5,4 @@ "fmt" "net/url" - "os" "sync/atomic" @@ -18,5 +17,5 @@ var ( - FrontendIsMaster = fmt.Errorf("FrontendIsMaster: %w", os.ErrNotExist) + FrontendIsMaster = fmt.Errorf("FrontendIsMaster: %w", utils.NotFoundError) NotRunningInFrontendError = utils.Wrap(utils.InvalidConfigError, "Command not available when running without a frontend service. To perform administrative tasks on the command line, connect to the server using the API https://docs.velociraptor.app/docs/server_automation/server_api/") diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/hunt_dispatcher/storage.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/hunt_dispatcher/storage.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/hunt_dispatcher/storage.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/hunt_dispatcher/storage.go 2025-11-01 15:52:20.000000000 +0000 @@ -7,5 +7,4 @@ "fmt" "io" - "os" "sort" "sync" @@ -28,8 +27,4 @@ ) -var ( - HuntNotFoundError = utils.Wrap(os.ErrNotExist, "Hunt not found") -) - type HuntIndexEntry struct { HuntId string `json:"HuntId"` diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/hunt_dispatcher.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/hunt_dispatcher.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/hunt_dispatcher.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/hunt_dispatcher.go 2025-11-01 15:52:20.000000000 +0000 @@ -25,5 +25,4 @@ import ( "context" - "os" api_proto "www.velocidex.com/golang/velociraptor/api/proto" @@ -36,5 +35,5 @@ var ( - HuntNotFoundError = utils.Wrap(os.ErrNotExist, "Hunt no found") + HuntNotFoundError = utils.Wrap(utils.NotFoundError, "Hunt no found") ) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/interrogation/interrogation.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/interrogation/interrogation.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/interrogation/interrogation.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/interrogation/interrogation.go 2025-11-01 15:52:20.000000000 +0000 @@ -123,6 +123,6 @@ // If we have a valid client record we do not need to - // interrogate. Interrogation happens automatically only once - // - the first time a client appears. + // interrogate. Interrogation happens automatically only once - + // the first time a client appears. if err == nil && client_info.LastInterrogateFlowId != "" { return nil @@ -154,4 +154,13 @@ } + // Create a placeholder client record for interrogation. + err = client_info_manager.Set(ctx, &services.ClientInfo{ + &actions_proto.ClientInfo{ + ClientId: client_id, + }}) + if err != nil { + return err + } + manager, err := services.GetRepositoryManager(config_obj) if err != nil { @@ -168,5 +177,6 @@ // Allow the user to override the basic interrogation // functionality. Check for any customized versions - definition, pres := repository.Get(ctx, config_obj, "Custom.Generic.Client.Info") + definition, pres := repository.Get(ctx, config_obj, + "Custom.Generic.Client.Info") if pres { interrogation_artifact = definition.Name diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/inventory/dummy.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/inventory/dummy.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/inventory/dummy.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/inventory/dummy.go 2025-11-01 15:52:20.000000000 +0000 @@ -7,5 +7,4 @@ "fmt" "io" - "io/ioutil" "net" "net/http" @@ -243,5 +242,5 @@ } - response, err := ioutil.ReadAll(res.Body) + response, err := utils.ReadAllWithLimit(res.Body, constants.MAX_MEMORY) if err != nil { return "", fmt.Errorf( diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/launcher/compiler.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/launcher/compiler.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/launcher/compiler.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/launcher/compiler.go 2025-11-01 15:52:20.000000000 +0000 @@ -403,4 +403,12 @@ dependency[artifact_name] = depth + if dep.Export != "" { + err := GetQueryDependencies(ctx, config_obj, repository, + dep.Export, 0, dependency) + if err != nil { + return err + } + } + // Add any artifact that this one imports as a dependency. for _, imp := range dep.Imports { diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/launcher/delete.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/launcher/delete.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/launcher/delete.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/launcher/delete.go 2025-11-01 15:52:20.000000000 +0000 @@ -287,13 +287,4 @@ } -func (self *reporter) emit_fs( - item_type string, target api.FSPathSpec) { - - self.emit(item_type, target.String(), func() error { - file_store_factory := file_store.GetFileStore(self.config_obj) - return file_store_factory.Delete(target) - }) -} - func (self *reporter) should_do_it() bool { self.mu.Lock() diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/launcher/launcher.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/launcher/launcher.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/launcher/launcher.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/launcher/launcher.go 2025-11-01 15:52:20.000000000 +0000 @@ -201,4 +201,5 @@ var max_batch_wait, max_batch_rows uint64 var max_batch_row_buffer uint64 + var local_timeout uint64 if config_obj != nil && config_obj.Defaults != nil { @@ -261,4 +262,8 @@ max_batch_row_buffer = artifact.Resources.MaxBatchRowsBuffer } + + if artifact.Resources.Timeout > local_timeout { + local_timeout = artifact.Resources.Timeout + } } @@ -281,4 +286,8 @@ } + if spec.Timeout > 0 { + local_timeout = spec.Timeout + } + for _, expanded_artifact := range expandArtifacts(artifact) { vql_collector_args, err := self.GetVQLCollectorArgs( @@ -293,4 +302,8 @@ } + if local_timeout > 0 { + vql_collector_args.Timeout = local_timeout + } + vql_collector_args.MaxRow = max_batch_rows vql_collector_args.MaxWait = max_batch_wait @@ -315,5 +328,6 @@ } - if collector_request.Timeout > 0 { + if vql_collector_args.Timeout == 0 && + collector_request.Timeout > 0 { vql_collector_args.Timeout = collector_request.Timeout } @@ -625,4 +639,11 @@ if err != nil { return "", err + } + + // If the client id is not known, refuse to schedule messages to + // it. + _, err = client_manager.Get(ctx, client_id) + if err != nil { + return "", err } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/launcher/launcher_test.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/launcher/launcher_test.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/launcher/launcher_test.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/launcher/launcher_test.go 2025-11-01 15:52:20.000000000 +0000 @@ -432,4 +432,19 @@ - query: | SELECT * FROM info() +`, ` +name: Test.ArtifactResources +resources: + timeout: 250 + cpu_limit: 20 + max_batch_rows: 256 + max_batch_wait: 101 + +parameters: + - name: Foo + default: Foo2 + +sources: +- query: | + SELECT * FROM info() `} @@ -484,4 +499,54 @@ } +func (self *LauncherTestSuite) TestCompilingMultipleLimitedArtifacts() { + repository := self.LoadArtifacts(CompilingMultipleArtifacts...) + + // The artifact compiler converts artifacts into a VQL request + // to be run by the clients. + request := &flows_proto.ArtifactCollectorArgs{ + Creator: "UserX", + ClientId: "C.1234", + Artifacts: []string{"Test.Artifact", "Test.ArtifactResources"}, + Specs: []*flows_proto.ArtifactSpec{ + { + // Here we specify limits in the artifact spec. + Artifact: "Test.Artifact", + Parameters: &flows_proto.ArtifactParameters{ + Env: []*actions_proto.VQLEnv{ + {Key: "Foo", Value: "Foo1"}, + }, + }, + CpuLimit: 12, + MaxBatchRows: 200, + MaxBatchRowsBuffer: 300, + MaxBatchWait: 400, + Timeout: 500, + }, + { + // This one specified limits in the artifact + // definition. + Artifact: "Test.ArtifactResources", + Parameters: &flows_proto.ArtifactParameters{ + Env: []*actions_proto.VQLEnv{ + {Key: "Foo", Value: "Foo2"}, + }, + }, + }, + }, + } + ctx := context.Background() + acl_manager := acl_managers.NullACLManager{} + + launcher, err := services.GetLauncher(self.ConfigObj) + assert.NoError(self.T(), err) + + compiled, err := launcher.CompileCollectorArgs( + ctx, self.ConfigObj, acl_manager, repository, + services.CompilerOptions{}, request) + assert.NoError(self.T(), err) + + json.Dump(compiled) +} + // Server events need to be compiled slighly differently - each source // needs to run in its own goroutine. @@ -1226,5 +1291,5 @@ assert.NoError(self.T(), err) assert.Equal(self.T(), getReqName(compiled[0]), "Test.Artifact.Timeout") - assert.Equal(self.T(), compiled[0].Timeout, uint64(20)) + assert.Equal(self.T(), compiled[0].Timeout, uint64(5)) assert.Equal(self.T(), getReqName(compiled[1]), "Test.Artifact.MaxRows") diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/launcher/verifier.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/launcher/verifier.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/launcher/verifier.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/launcher/verifier.go 2025-11-01 15:52:20.000000000 +0000 @@ -25,4 +25,7 @@ Errors []error Warnings []string + + // Keep track of existing definitions in LET queries. + Definitions map[string]vfilter.CallSite } @@ -76,5 +79,6 @@ func NewAnalysisState(artifact string) *AnalysisState { return &AnalysisState{ - Artifact: artifact, + Artifact: artifact, + Definitions: make(map[string]vfilter.CallSite), } } @@ -85,4 +89,6 @@ ArgsRequired map[string]Required Permissions []string + + FreeFormArgs bool } @@ -99,4 +105,5 @@ res := &CallDesciptor{ ArgsRequired: make(map[string]Required), + FreeFormArgs: api.FreeFormArgs, } @@ -130,7 +137,5 @@ desc.ArgsRequired[arg.Name] = Required(arg.Required) } - if !api.FreeFormArgs { - self.functions[api.Name] = desc - } + self.functions[api.Name] = desc } if api.Type == "Plugin" { @@ -142,7 +147,5 @@ desc.ArgsRequired[arg.Name] = Required(arg.Required) } - if !api.FreeFormArgs { - self.plugins[api.Name] = desc - } + self.plugins[api.Name] = desc } } @@ -199,7 +202,39 @@ } + // If the callsite contains a . we have no idea what it + // means. Assume this is not an error. It may be a startlark + // module for example. + if strings.Contains(callsite.Name, ".") { + return nil + } + if callsite.Type == "plugin" { desc, pres := self.plugins[callsite.Name] - if pres { + if !pres { + // Is this already defined? + desc, pres := state.Definitions[callsite.Name] + if !pres { + res = append(res, fmt.Errorf( + "Unknown plugin %v()", callsite.Name)) + } + + for _, arg := range callsite.Args { + if !utils.InString(desc.Args, arg) { + res = append(res, fmt.Errorf( + "Invalid arg %v for VQL definition %v", + arg, callsite.Name)) + } + } + + // Now check if any of the required args are missing + for _, arg := range desc.Args { + if !utils.InString(callsite.Args, arg) { + res = append(res, fmt.Errorf( + "While calling VQL definition %v(), required arg %v is not provided", + callsite.Name, arg)) + } + } + + } else if !desc.FreeFormArgs { state.AnalyseCall(callsite, desc) @@ -226,5 +261,30 @@ if callsite.Type == "function" { desc, pres := self.functions[callsite.Name] - if pres { + if !pres { + // Is this already defined? + desc, pres := state.Definitions[callsite.Name] + if !pres { + res = append(res, fmt.Errorf( + "Unknown function %v()", callsite.Name)) + } + + for _, arg := range callsite.Args { + if !utils.InString(desc.Args, arg) { + res = append(res, fmt.Errorf( + "Invalid arg %v for VQL definition %v", + arg, callsite.Name)) + } + } + + // Now check if any of the required args are missing + for _, arg := range desc.Args { + if !utils.InString(callsite.Args, arg) { + res = append(res, fmt.Errorf( + "While calling VQL definition %v(), required arg %v is not provided", + callsite.Name, arg)) + } + } + + } else if !desc.FreeFormArgs { state.AnalyseCall(callsite, desc) @@ -265,4 +325,19 @@ } + // In VQL sometimes it is possible to use definition defined after + // the place of use. We therefore make two passes - one to find + // the definition the second pass we check for use. We may not + // find callsite that will fail at runtime but we assume they are + // available. + for _, vql := range vqls { + // Visit the VQL looking for plugin callsites. + visitor := vfilter.NewVisitor(scope, vfilter.CollectCallSites) + visitor.Visit(vql) + + for _, def := range visitor.Definitions { + state.Definitions[def.Name] = def + } + } + for _, vql := range vqls { // Visit the VQL looking for plugin callsites. @@ -279,4 +354,11 @@ } +var VQLPaths = []string{ + "sources.[].query", + "export", + "precondition", + "sources.[].precondition", +} + func VerifyArtifact( ctx context.Context, config_obj *config_proto.Config, @@ -285,8 +367,27 @@ state *AnalysisState) { + preamble := "" + for _, imp := range artifact.Imports { + dep, pres := repository.Get(ctx, config_obj, imp) + if !pres { + state.SetError(fmt.Errorf( + "%v: invalid import: Artifact %v not found", artifact.Name, imp)) + } else { + if dep.Export == "" { + state.SetError(fmt.Errorf( + "%v: invalid import: Artifact %v does not export anything", + artifact.Name, imp)) + + } else { + preamble += dep.Export + } + } + } + if artifact.Precondition != "" { for _, err := range VerifyVQL(ctx, config_obj, artifact.Precondition, repository, state) { - state.SetError(err) + state.SetError(fmt.Errorf( + "%v: precondition: %w", artifact.Name, err)) } } @@ -294,17 +395,29 @@ if artifact.Export != "" { for _, err := range VerifyVQL(ctx, config_obj, - artifact.Export, repository, state) { - state.SetError(err) + preamble+artifact.Export, repository, state) { + state.SetError(fmt.Errorf( + "%v: export: %w", artifact.Name, err)) } + + preamble += artifact.Export } for _, s := range artifact.Sources { + name := artifact.Name + if s.Name != "" { + name += "/" + s.Name + } + if s.Query != "" { dependency := make(map[string]int) + query := preamble + s.Query + + // The export section if it exists is injection prior to + // any query. err := GetQueryDependencies(ctx, config_obj, - repository, s.Query, 0, dependency) + repository, query, 0, dependency) if err != nil { - state.SetError(err) + state.SetError(fmt.Errorf("%v: query: %w", name, err)) continue } @@ -312,12 +425,13 @@ // Now check for broken callsites for _, err := range VerifyVQL(ctx, config_obj, - s.Query, repository, state) { - state.SetError(err) + query, repository, state) { + state.SetError(fmt.Errorf("%v: query: %w", name, err)) } } + if s.Precondition != "" { for _, err := range VerifyVQL(ctx, config_obj, s.Precondition, repository, state) { - state.SetError(err) + state.SetError(fmt.Errorf("%v: precondition: %w", name, err)) } } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/launcher/verifier_test.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/launcher/verifier_test.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/launcher/verifier_test.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/launcher/verifier_test.go 2025-11-01 15:52:20.000000000 +0000 @@ -29,4 +29,22 @@ "Query calls Unknown artifact Generic.Unknown.Artifact"}, + // Handling VQL definitions + {"Calling unknown plugin", + "SELECT * FROM infoxxxx()", + "Unknown plugin infoxxxx()"}, + + {"Define VQL function and call it", + "LET infoxxx = SELECT * FROM info() SELECT * FROM infoxxx", ""}, + + // With some parameters + {"Define VQL function - Do not pass arg", + "LET infoxxx(X) = SELECT * FROM info() SELECT * FROM infoxxx()", + "While calling VQL definition infoxxx(), required arg X is not provided"}, + + // With some parameters + {"Define VQL function - Pass incorrect arg", + "LET infoxxx(X) = SELECT * FROM info() SELECT * FROM infoxxx(X=1, Y=2)", + "Invalid arg Y for VQL definition infoxxx"}, + // No errors - all good {"Function with args", @@ -60,5 +78,106 @@ } - assert.Regexp(self.T(), tc.error_regex, fmt.Sprintf("%v", errs)) + assert.Regexp(self.T(), fmt.Sprintf("%v", errs), tc.error_regex) + } + } +} + +var ( + verifier_test_cases_artifacts = []struct { + desc string + artifact string + error_regex string + }{ + {"Invalid artifact precondition", ` +name: Test +precondition: SELECT * FROM infox() +`, "Test: precondition: Unknown plugin infox()"}, + + {"Invalid source precondition", ` +name: Test +sources: +- name: Source + precondition: SELECT * FROM infox() +`, "Test/Source: precondition: Unknown plugin infox()"}, + + {"Invalid export", ` +name: TestExport +export: + SELECT * FROM infox() +`, "TestExport: export: Unknown plugin infox()"}, + + {"Invalid source query", ` +name: Test +sources: +- name: Source + query: SELECT * FROM infox() +`, "Test/Source: query: Unknown plugin infox()"}, + + {"Define in export, use in query", ` +name: TestExport +export: | + LET infox = SELECT * FROM info() + +sources: +- name: Source + query: SELECT * FROM infox() +`, ""}, + + {"Define in export, use in import", ` +name: TestImport +imports: + - TestExport + +sources: +- name: Source + query: SELECT * FROM infox() +`, ""}, + + {"Invalid import", ` +name: TestImport +imports: + - TestDoesNotExist + +sources: +- name: Source + query: SELECT * FROM infox() +`, "TestImport: invalid import: Artifact TestDoesNotExist not found"}, + + {"Import artifact that does not export anything", ` +name: TestImport +imports: + - Test + +sources: +- name: Source + query: SELECT * FROM infox() +`, "TestImport: invalid import: Artifact Test does not export anything"}, + } +) + +func (self *LauncherTestSuite) TestVerifyArtifact() { + manager, err := services.GetRepositoryManager(self.ConfigObj) + assert.NoError(self.T(), err) + + repository, err := manager.GetGlobalRepository(self.ConfigObj) + assert.NoError(self.T(), err) + + for _, tc := range verifier_test_cases_artifacts { + state := launcher.NewAnalysisState("") + + artifact, err := repository.LoadYaml(tc.artifact, services.ArtifactOptions{ + ValidateArtifact: true, + }) + assert.NoError(self.T(), err) + + launcher.VerifyArtifact(self.Ctx, self.ConfigObj, repository, artifact, state) + + if len(state.Errors) > 0 { + if tc.error_regex == "" { + self.T().Fatalf("%v: Expected no error but got %v", + tc.desc, state.Errors) + } + + assert.Regexp(self.T(), tc.error_regex, fmt.Sprintf("%v", state.Errors)) } } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/launcher.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/launcher.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/launcher.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/launcher.go 2025-11-01 15:52:20.000000000 +0000 @@ -44,5 +44,4 @@ import ( "context" - "os" "time" @@ -66,5 +65,5 @@ var ( - FlowNotFoundError = utils.Wrap(os.ErrNotExist, "Flow not found") + FlowNotFoundError = utils.Wrap(utils.NotFoundError, "Flow not found") DryRunOnly = DeleteFlowOptions{ ReallyDoIt: false, diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/notebook/calculate_test.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/notebook/calculate_test.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/notebook/calculate_test.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/notebook/calculate_test.go 2025-11-01 15:52:20.000000000 +0000 @@ -18,4 +18,5 @@ "www.velocidex.com/golang/velociraptor/services/scheduler" "www.velocidex.com/golang/velociraptor/utils" + "www.velocidex.com/golang/velociraptor/utils/rand" "www.velocidex.com/golang/velociraptor/vtesting" "www.velocidex.com/golang/velociraptor/vtesting/assert" @@ -73,4 +74,6 @@ test_utils.TestSuite closer func() + + client_id string } @@ -101,4 +104,12 @@ err := services.GrantRoles(self.ConfigObj, "admin", []string{"administrator"}) assert.NoError(self.T(), err) + + client_info_manager, err := services.GetClientInfoManager(self.ConfigObj) + assert.NoError(self.T(), err) + err = client_info_manager.Set(self.Ctx, &services.ClientInfo{ + &actions_proto.ClientInfo{ + ClientId: self.client_id, + }}) + assert.NoError(self.T(), err) } @@ -408,4 +419,7 @@ func TestNotebookManager(t *testing.T) { - suite.Run(t, &NotebookManagerTestSuite{}) + defer rand.DisableRand() + suite.Run(t, &NotebookManagerTestSuite{ + client_id: "C.1235", + }) } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/notebook/fixtures/TestNotebookManagerTimelineAnnotations.golden /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/notebook/fixtures/TestNotebookManagerTimelineAnnotations.golden --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/notebook/fixtures/TestNotebookManagerTimelineAnnotations.golden 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/notebook/fixtures/TestNotebookManagerTimelineAnnotations.golden 2025-11-01 15:52:20.000000000 +0000 @@ -106,15 +106,4 @@ "_AnnotationID": "TdAAAAAAAAA=", "_Source": "Annotation" - }, - { - "Timestamp": "2024-05-15T12:36:27Z", - "Message": "Original Event Message 2", - "Description": "", - "OriginalEventField": "Extra field 2", - "Foo": "Older Bar 2", - "Notes": "Updated First Annotation - all other fields remain", - "_AnnotatedBy": "admin", - "_AnnotationID": "TtAAAAAAAAA=", - "_Source": "Annotation" } ], @@ -157,17 +146,28 @@ } ], - "First Event Updated": { - "Timestamp": "2024-05-15T12:36:27Z", + "First Event to update": { + "Timestamp": "2024-03-30T05:13:07Z", "Message": "Original Event Message 2", "Description": "", "OriginalEventField": "Extra field 2", "Foo": "Older Bar 2", - "_Source": "Annotation", - "Notes": "Updated First Annotation - all other fields remain", - "_AnnotatedBy": "admin", - "_AnnotationID": "TtAAAAAAAAA=" + "Notes": "An Earlier Foo is suspicious at being Older Bar!", + "_AnnotatedBy": "mike", + "_AnnotationID": "TtAAAAAAAAA=", + "_Source": "Annotation" }, "Updated Annotations": [ { + "Timestamp": "2024-03-30T05:13:07Z", + "Message": "Original Event Message 2", + "Description": "", + "OriginalEventField": "Extra field 2", + "Foo": "Older Bar 2", + "Notes": "Updated First Annotation - all other fields remain", + "_AnnotatedBy": "admin", + "_AnnotationID": "TtAAAAAAAAA=", + "_Source": "Annotation" + }, + { "Timestamp": "2024-05-15T12:19:47Z", "Message": "Original Event Message 1", @@ -179,15 +179,4 @@ "_AnnotationID": "TdAAAAAAAAA=", "_Source": "Annotation" - }, - { - "Timestamp": "2024-05-15T12:36:27Z", - "Message": "Original Event Message 2", - "Description": "", - "OriginalEventField": "Extra field 2", - "Foo": "Older Bar 2", - "Notes": "Updated First Annotation - all other fields remain", - "_AnnotatedBy": "admin", - "_AnnotationID": "TtAAAAAAAAA=", - "_Source": "Annotation" } ] diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/notebook/initial.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/notebook/initial.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/notebook/initial.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/notebook/initial.go 2025-11-01 15:52:20.000000000 +0000 @@ -283,5 +283,12 @@ } - for _, s := range artifact.Sources { + // If there are no sources in this artifact add a single fake + // source so we can do something. + sources := artifact.Sources + if len(sources) == 0 { + sources = append(sources, &artifacts_proto.ArtifactSource{}) + } + + for _, s := range sources { new_source := &artifacts_proto.ArtifactSource{ Name: s.Name, @@ -306,4 +313,9 @@ new_source.Notebook = append(new_source.Notebook, n) switch strings.ToLower(n.Type) { + + // Artifacts may set a notebook cell to type "none" to + // declare a custom notebook which will not actually + // be used. This allows suppressing notebook cells for + // this source. case "vql", "md", "markdown", "none": custom_cells = true diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/notebook/initial_test.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/notebook/initial_test.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/notebook/initial_test.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/notebook/initial_test.go 2025-11-01 15:52:20.000000000 +0000 @@ -101,9 +101,11 @@ type checker func(t *testing.T, response *artifacts_proto.Artifact, spec *flows_proto.ArtifactSpec) -var ( - initialTestCases = []struct { - req *api_proto.NotebookMetadata - check checker - }{ +type notebookTestCase struct { + req *api_proto.NotebookMetadata + check checker +} + +func initialTestCases(client_id string) []notebookTestCase { + return []notebookTestCase{ { req: &api_proto.NotebookMetadata{ @@ -126,5 +128,5 @@ // should cause the PrivateNotebook to add client id and // flow id to the artifact parameters. - NotebookId: "N.F.1234-C.1235", + NotebookId: "N.F.1234-" + client_id, Description: "Notebook based on a client artifact with no custom notebooks.", Artifacts: []string{"Generic.Client.Info"}, @@ -139,5 +141,5 @@ // ClientId and Flow ID are added AssertDictRegex(t, "ClientId", "Parameters.2.Name", artifact) - AssertDictRegex(t, "C.1235", "Parameters.2.Default", artifact) + AssertDictRegex(t, client_id, "Parameters.2.Default", artifact) AssertDictRegex(t, "FlowId", "Parameters.3.Name", artifact) @@ -152,5 +154,5 @@ req: &api_proto.NotebookMetadata{ Name: "Custom.Generic.Client.Info", - NotebookId: "N.F.1235-C.1235", + NotebookId: "N.F.1235-" + client_id, Description: "Based on custom notebook cells", Artifacts: []string{"Custom.Generic.Client.Info"}, @@ -166,5 +168,5 @@ Name: "EventArtifact", Description: "Building a notebook from an event artifact adds StartTime and EndTime", - NotebookId: "N.E.Generic.Events-C.1235", + NotebookId: "N.E.Generic.Events-" + client_id, Artifacts: []string{"Generic.Events"}, Env: []*api_proto.Env{{ @@ -193,5 +195,5 @@ Name: "EventArtifact Default", Description: "Building a notebook from an event artifact without custom notebooks. This should populate the spec from the installed client event monitoring table.", - NotebookId: "N.E.Generic.Events-C.1235", + NotebookId: "N.E.Generic.Events-" + client_id, Artifacts: []string{"Generic.Events"}, Env: []*api_proto.Env{ @@ -285,5 +287,5 @@ }, } -) +} func (self *NotebookManagerTestSuite) createFlow( @@ -364,9 +366,9 @@ self.LoadArtifacts(InitialArtifacts...) - self.createFlow("F.1234", "C.1235", "Generic.Client.Info") - self.createFlow("F.1235", "C.1235", "Custom.Generic.Client.Info") + self.createFlow("F.1234", self.client_id, "Generic.Client.Info") + self.createFlow("F.1235", self.client_id, "Custom.Generic.Client.Info") golden := ordereddict.NewDict() - for _, tc := range initialTestCases { + for _, tc := range initialTestCases(self.client_id) { req := tc.req golden.Set(req.Name+" Request", proto.Clone(req)) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/notebook/timelines_test.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/notebook/timelines_test.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/notebook/timelines_test.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/notebook/timelines_test.go 2025-11-01 15:52:20.000000000 +0000 @@ -3,4 +3,5 @@ import ( "fmt" + "testing" "time" @@ -12,4 +13,5 @@ timelines_proto "www.velocidex.com/golang/velociraptor/timelines/proto" "www.velocidex.com/golang/velociraptor/utils" + "www.velocidex.com/golang/velociraptor/utils/rand" vql_subsystem "www.velocidex.com/golang/velociraptor/vql" "www.velocidex.com/golang/velociraptor/vtesting" @@ -100,4 +102,8 @@ func (self *NotebookManagerTestSuite) TestNotebookManagerTimelineAnnotations() { + if testing.Short() { + self.T().Skip("skipping test in short mode - too flakey on CI.") + return + } assert.Retry(self.T(), 10, time.Second, self._TestNotebookManagerTimelineAnnotations) @@ -106,4 +112,5 @@ func (self *NotebookManagerTestSuite) _TestNotebookManagerTimelineAnnotations( t *assert.R) { + defer rand.DisableRand() closer := utils.MockTime(utils.NewMockClock(time.Unix(1715775587, 0))) @@ -120,4 +127,27 @@ assert.NoError(t, err) + // Clear all previous notebooks + all_notebooks, err := notebook_manager.GetAllNotebooks(self.Ctx, + services.NotebookSearchOptions{ + Username: "admin", + Timelines: true, + }) + assert.NoError(t, err) + assert.Equal(t, len(all_notebooks), 0) + + for _, notebook := range all_notebooks { + err := notebook_manager.DeleteNotebook(self.Ctx, notebook.NotebookId, + nil, true) + assert.NoError(t, err) + } + + // Make sure they are cleared + all_notebooks, err = notebook_manager.GetAllNotebooks(self.Ctx, + services.NotebookSearchOptions{ + Username: "admin", + }) + assert.NoError(t, err) + assert.Equal(t, len(all_notebooks), 0) + golden := ordereddict.NewDict() @@ -155,5 +185,5 @@ // Check that GetAllNotebooks() returns this notebook now. - all_notebooks, err := notebook_manager.GetAllNotebooks(self.Ctx, + all_notebooks, err = notebook_manager.GetAllNotebooks(self.Ctx, services.NotebookSearchOptions{ Username: "admin", @@ -169,5 +199,5 @@ assert.Equal(t, all_notebooks[0].NotebookId, notebook.NotebookId) - // Check that GetAllNotebooks() returns only notebook for this + // Check that GetAllNotebooks() returns only notebooks for this // user. all_notebooks, err = notebook_manager.GetAllNotebooks(self.Ctx, @@ -222,10 +252,17 @@ first_event := ordereddict.NewDict() first_event.MergeFrom(read_all_events()[0].(*ordereddict.Dict)) - golden.Set("First Event Updated", first_event) + golden.Set("First Event to update", first_event.Copy()) + + timestamp_any, pres := first_event.Get("Timestamp") + assert.True(t, pres) + + timestamp, ok := timestamp_any.(time.Time) + assert.True(t, ok) + // Update the event at the same timestamp. err = notebook_manager.AnnotateTimeline(self.Ctx, scope, notebook.NotebookId, "supertimeline", "Updated First Annotation - all other fields remain", "admin", - time.Unix(1715776587, 0), first_event) + timestamp, first_event) assert.NoError(t, err) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/repository/backups.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/repository/backups.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/repository/backups.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/repository/backups.go 2025-11-01 15:52:20.000000000 +0000 @@ -4,9 +4,9 @@ "context" "fmt" - "io/ioutil" "sync" artifacts_proto "www.velocidex.com/golang/velociraptor/artifacts/proto" 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" @@ -159,5 +159,5 @@ } - data, err := ioutil.ReadAll(fd) + data, err := utils.ReadAllWithLimit(fd, constants.MAX_MEMORY) if err != nil { continue Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/repository: errors.go diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/repository/files.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/repository/files.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/repository/files.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/repository/files.go 2025-11-01 15:52:20.000000000 +0000 @@ -5,5 +5,4 @@ "errors" "fmt" - "io/ioutil" "os" "path/filepath" @@ -11,6 +10,8 @@ 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" ) @@ -91,5 +92,5 @@ // Skip files we can not read. - data, err := ioutil.ReadAll(fd) + data, err := utils.ReadAllWithLimit(fd, constants.MAX_MEMORY) if err != nil { logger.Error("InitializeGlobalRepositoryFromFilesystem: %v", err) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/repository/filestore.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/repository/filestore.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/repository/filestore.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/repository/filestore.go 2025-11-01 15:52:20.000000000 +0000 @@ -4,6 +4,4 @@ "context" "errors" - "io" - "io/ioutil" "os" "sync/atomic" @@ -17,4 +15,5 @@ "www.velocidex.com/golang/velociraptor/paths" "www.velocidex.com/golang/velociraptor/services" + "www.velocidex.com/golang/velociraptor/utils" ) @@ -69,6 +68,5 @@ defer fd.Close() - data, err := ioutil.ReadAll( - io.LimitReader(fd, constants.MAX_MEMORY)) + data, err := utils.ReadAllWithLimit(fd, constants.MAX_MEMORY) if err != nil { logger.Error("GetGlobalRepository: %v", err) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/repository/metadata.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/repository/metadata.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/repository/metadata.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/repository/metadata.go 2025-11-01 15:52:20.000000000 +0000 @@ -105,5 +105,5 @@ if utils.GetTime().Now().Sub(last_write) > time.Second && repository != nil { - self.SaveMetadata(self.ctx, self.config_obj, self.repository) + _ = self.SaveMetadata(self.ctx, self.config_obj, self.repository) } } @@ -132,5 +132,5 @@ } - self.SaveMetadata(ctx, config_obj, repository) + _ = self.SaveMetadata(ctx, config_obj, repository) } } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/repository/reformat.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/repository/reformat.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/repository/reformat.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/repository/reformat.go 2025-11-01 15:52:20.000000000 +0000 @@ -5,9 +5,8 @@ "fmt" "sort" - "strconv" "strings" "github.com/alecthomas/participle" - "gopkg.in/yaml.v3" + "www.velocidex.com/golang/velociraptor/utils/yaml" vql_subsystem "www.velocidex.com/golang/velociraptor/vql" "www.velocidex.com/golang/vfilter" @@ -21,72 +20,4 @@ } -type nodeContext struct { - *yaml.Node - - parent *yaml.Node -} - -// The yaml library emits nodes in an incosistent way which makes them -// hard to navigate. This function reorders the nodes into a proper -// document structure and fetches the relevant node. -func getYamlNodes(node, parent *yaml.Node, - components []string, nodes *[]nodeContext) bool { - - if len(components) == 0 { - *nodes = append(*nodes, nodeContext{ - Node: node, - parent: parent, - }) - return true - } - - next := components[0] - if next == "[]" { - if node.Tag != "!!seq" { - return false - } - res := false - for _, c := range node.Content { - if getYamlNodes(c, node, components[1:], nodes) { - res = true - } - } - return res - } - - idx, err := strconv.ParseInt(next, 0, 64) - if err == nil { - // It is not a sequence - if node.Tag != "!!seq" || - // Sequence too short - len(node.Content) < int(idx) { - return false - } - - // Child is found - keep going to the next component - return getYamlNodes(node.Content[idx], node, components[1:], nodes) - } - - // Walk a mapping - if node.Tag == "!!map" { - // should not happen - if len(node.Content)%2 != 0 { - return false - } - - // Maps are set up in node.Content as a list of key, value. - for i := 0; i < len(node.Content); i += 2 { - key := node.Content[i].Value - if key == next { - return getYamlNodes(node.Content[i+1], node, components[1:], nodes) - } - } - // Didnt find it - return false - } - - return false -} - var VQLPaths = []string{ "sources.[].query", @@ -97,8 +28,8 @@ func getAllMutations(root *yaml.Node) (res []mutation, err error) { - var nodes []nodeContext + var nodes []yaml.NodeContext for _, p := range VQLPaths { - getYamlNodes(root, root, strings.Split(p, "."), &nodes) + yaml.GetYamlNodes(root, root, strings.Split(p, "."), &nodes) } @@ -124,5 +55,5 @@ } -func reformatNode(vql_node nodeContext) (m mutation, err error) { +func reformatNode(vql_node yaml.NodeContext) (m mutation, err error) { scope := vql_subsystem.MakeScope() reformatted, err := reformat.ReFormatVQL( @@ -150,5 +81,5 @@ // Indent this block to the start of the previous block indented := []string{} - ind := strings.Repeat(" ", vql_node.parent.Column+1) + ind := strings.Repeat(" ", vql_node.Parent.Column+1) for _, l := range lines { indented = append(indented, ind+l) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/repository/repository.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/repository/repository.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/repository/repository.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/repository/repository.go 2025-11-01 15:52:20.000000000 +0000 @@ -228,5 +228,6 @@ if err != nil { return nil, fmt.Errorf( - "While parsing artifact precondition: %w", err) + "While parsing artifact precondition: %w", + reportError(err, artifact, "precondition", 0)) } } @@ -237,10 +238,11 @@ if err != nil { return nil, fmt.Errorf( - "While parsing artifact export: %w", err) + "While parsing artifact export: %w", + reportError(err, artifact, "export", 0)) } } // Check each source for validity - for _, source := range artifact.Sources { + for idx, source := range artifact.Sources { if source.Precondition != "" { if artifact.Precondition != "" { @@ -252,5 +254,7 @@ _, err := vfilter.MultiParse(source.Precondition) if err != nil { - return nil, fmt.Errorf("While parsing precondition: %w", err) + return nil, fmt.Errorf("While parsing precondition: %w", + reportError(err, artifact, + "sources.[].precondition", idx)) } } @@ -262,5 +266,7 @@ if err != nil { return nil, fmt.Errorf("While parsing source query %v: %w", - source.Name, err) + source.Name, + reportError(err, artifact, + "sources.[].query", idx)) } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/scheduler/scheduler.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/scheduler/scheduler.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/scheduler/scheduler.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/scheduler/scheduler.go 2025-11-01 15:52:20.000000000 +0000 @@ -5,9 +5,10 @@ "errors" "fmt" - "math/rand" "sort" "sync" "time" + "www.velocidex.com/golang/velociraptor/utils/rand" + "github.com/Velocidex/ordereddict" config_proto "www.velocidex.com/golang/velociraptor/config/proto" diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/scheduler/scheduler_test.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/scheduler/scheduler_test.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/scheduler/scheduler_test.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/scheduler/scheduler_test.go 2025-11-01 15:52:20.000000000 +0000 @@ -9,4 +9,5 @@ "www.velocidex.com/golang/velociraptor/file_store/test_utils" "www.velocidex.com/golang/velociraptor/services" + "www.velocidex.com/golang/velociraptor/utils/rand" "www.velocidex.com/golang/velociraptor/vtesting/assert" ) @@ -25,4 +26,6 @@ func (self *SchedulerTestSuite) TestScheduler() { + defer rand.DisableRand() + scheduler, err := services.GetSchedulerService(self.ConfigObj) assert.NoError(self.T(), err) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/secrets/initialize.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/secrets/initialize.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/secrets/initialize.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/secrets/initialize.go 2025-11-01 15:52:20.000000000 +0000 @@ -43,5 +43,7 @@ "hostname", }, - Template: map[string]string{}, + Template: map[string]string{ + "username": "uploader", + }, }, { TypeName: constants.HTTP_SECRETS, diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/server_artifacts/server_uploader.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/server_artifacts/server_uploader.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/server_artifacts/server_uploader.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/server_artifacts/server_uploader.go 2025-11-01 15:52:20.000000000 +0000 @@ -44,5 +44,5 @@ btime time.Time, mode os.FileMode, - reader io.ReadSeeker) (*uploads.UploadResponse, error) { + reader io.ReadSeeker) (result *uploads.UploadResponse, err error) { if !mode.IsRegular() { @@ -59,11 +59,11 @@ } - cached, pres, closer := uploads.DeduplicateUploads(scope, store_as_name) - defer closer() - if pres { - return cached, nil + result, closer := uploads.DeduplicateUploads(scope, store_as_name) + defer closer(result) + if result != nil { + return result, nil } - result, err := self.FileStoreUploader.Upload(ctx, scope, filename, + result, err = self.FileStoreUploader.Upload(ctx, scope, filename, accessor, store_as_name, expected_size, mtime, atime, ctime, btime, mode, reader) @@ -117,6 +117,5 @@ "server", self.session_id, ) - - uploads.CacheUploadResult(scope, store_as_name, result) + closer(result) return result, err } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/users/storage.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/users/storage.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/services/users/storage.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/services/users/storage.go 2025-11-01 15:52:20.000000000 +0000 @@ -140,4 +140,5 @@ if user_record.Name == "" { + utils.PrintStack() return errors.New("Must set a username") } @@ -362,4 +363,7 @@ // Merge the old options with the new options old_options := cache.gui_options + if old_options == nil { + old_options = &api_proto.SetGUIOptionsRequest{} + } // For now we do not allow the user to set the links in their diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/startup/client.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/startup/client.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/startup/client.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/startup/client.go 2025-11-01 15:52:20.000000000 +0000 @@ -12,5 +12,7 @@ "www.velocidex.com/golang/velociraptor/services/orgs" vql_subsystem "www.velocidex.com/golang/velociraptor/vql" + "www.velocidex.com/golang/velociraptor/vql/debug" "www.velocidex.com/golang/velociraptor/vql/networking" + "www.velocidex.com/golang/velociraptor/vql/parsers/journald" ) @@ -42,4 +44,10 @@ vql_subsystem.InstallUnimplemented(scope) + // Maybe add various debug plugins if we are in debug mode. + debug.AddDebugPlugins(config_obj) + + // Start the journald watcher service if needed. + journald.StartGlobalJournaldService(ctx, config_obj) + // Start encrypted logs service if possible err = encrypted_logs.StartEncryptedLog(sm.Ctx, sm.Wg, sm.Config) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/startup/frontend.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/startup/frontend.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/startup/frontend.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/startup/frontend.go 2025-11-01 15:52:20.000000000 +0000 @@ -13,4 +13,5 @@ vql_subsystem "www.velocidex.com/golang/velociraptor/vql" "www.velocidex.com/golang/velociraptor/vql/networking" + "www.velocidex.com/golang/velociraptor/vql/parsers/journald" ) @@ -42,4 +43,6 @@ vql_subsystem.InstallUnimplemented(scope) + journald.StartGlobalJournaldService(ctx, config_obj) + _, err = orgs.NewOrgManager(sm.Ctx, sm.Wg, config_obj) if err != nil { diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/startup/tool.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/startup/tool.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/startup/tool.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/startup/tool.go 2025-11-01 15:52:20.000000000 +0000 @@ -10,4 +10,5 @@ "www.velocidex.com/golang/velociraptor/services/orgs" vql_subsystem "www.velocidex.com/golang/velociraptor/vql" + "www.velocidex.com/golang/velociraptor/vql/parsers/journald" ) @@ -21,4 +22,5 @@ vql_subsystem.InstallUnimplemented(scope) + journald.StartGlobalJournaldService(ctx, config_obj) sm := services.NewServiceManager(ctx, config_obj) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/third_party/zip/writer_test.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/third_party/zip/writer_test.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/third_party/zip/writer_test.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/third_party/zip/writer_test.go 2025-11-01 15:52:20.000000000 +0000 @@ -11,9 +11,10 @@ "io" "io/ioutil" - "math/rand" "os" "strings" "testing" "time" + + "www.velocidex.com/golang/velociraptor/utils/rand" ) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/tools/fuse/times.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/tools/fuse/times.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/tools/fuse/times.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/tools/fuse/times.go 2025-11-01 15:52:20.000000000 +0000 @@ -22,5 +22,10 @@ var ( knownMetadataFiles = [][]string{ + // 0.74 and below {"results", "Windows.KapeFiles.Targets/All File Metadata.json"}, + + // 0.75 + + {"results", "Windows.KapeFiles.Targets/All Matches Metadata.json"}, + {"results", "Windows.Triage.Targets/All Matches Metadata.json"}, } ) Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/tools: json diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/tools/survey/compile.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/tools/survey/compile.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/tools/survey/compile.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/tools/survey/compile.go 2025-11-01 15:52:20.000000000 +0000 @@ -93,5 +93,5 @@ config_obj.GUI.BindAddress = "0.0.0.0" config_obj.GUI.PublicUrl = fmt.Sprintf( - "https://%s/", config_obj.Frontend.Hostname) + "https://%s/app/index.html", config_obj.Frontend.Hostname) config_obj.Client.ServerUrls = []string{ diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/uploads/api.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/uploads/api.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/uploads/api.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/uploads/api.go 2025-11-01 15:52:20.000000000 +0000 @@ -8,4 +8,5 @@ "time" + "github.com/Velocidex/ordereddict" "www.velocidex.com/golang/velociraptor/accessors" "www.velocidex.com/golang/vfilter" @@ -30,4 +31,49 @@ } +func (self *UploadResponse) AsDict() *ordereddict.Dict { + res := ordereddict.NewDict(). + Set("Path", self.Path). + Set("Size", self.Size). + Set("UploadId", self.ID) + + if self.StoredSize > 0 { + res.Set("StoredSize", self.StoredSize) + } + + if self.Error != "" { + res.Set("Error", self.Error) + } + + if self.Sha256 != "" { + res.Set("sha256", self.Sha256) + } + + if self.Md5 != "" { + res.Set("md5", self.Md5) + } + + if self.StoredName != "" { + res.Set("StoredName", self.StoredName) + } + + if self.Reference != "" { + res.Set("Reference", self.Reference) + } + + if len(self.Components) > 0 { + res.Set("Components", append([]string{}, self.Components...)) + } + + if self.Accessor != "" { + res.Set("Accessor", self.Accessor) + } + + if self.Type != "" { + res.Set("Type", self.Type) + } + + return res +} + // Provide an uploader capable of uploading any reader object. type Uploader interface { diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/uploads/client_uploader.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/uploads/client_uploader.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/uploads/client_uploader.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/uploads/client_uploader.go 2025-11-01 15:52:20.000000000 +0000 @@ -173,4 +173,8 @@ defer func() { self.Responder.FlowContext().DecTransaction() + + self.mu.Lock() + defer self.mu.Unlock() + delete(self.current, t.UploadId) }() @@ -228,4 +232,11 @@ } +func (self *VelociraptorUploader) GetTransactionCount() int { + self.mu.Lock() + defer self.mu.Unlock() + + return len(self.current) +} + func (self *VelociraptorUploader) Close() { // Signal the worker the uploads are done. @@ -252,5 +263,5 @@ btime time.Time, mode os.FileMode, - reader io.ReadSeeker) (*UploadResponse, error) { + reader io.ReadSeeker) (result *UploadResponse, err error) { if mode.IsDir() { @@ -267,8 +278,8 @@ } - cached, pres, closer := DeduplicateUploads(scope, store_as_name) - defer closer() - if pres { - return cached, nil + result, closer := DeduplicateUploads(scope, store_as_name) + defer closer(result) + if result != nil { + return result, nil } @@ -301,17 +312,21 @@ // When we upload asynchronously we return an upload id which // can be used to track the upload (or resume it) in future. - return &UploadResponse{ + result = &UploadResponse{ StoredName: store_as_name.String(), Accessor: accessor, Components: store_as_name.Components[:], ID: upload_id, - }, nil + } + closer(result) + return result, nil - } else { - self.wg.Add(1) - return self._Upload(ctx, scope, filename, accessor, - store_as_name, expected_size, mtime, atime, ctime, btime, - mode, reader, 0, upload_id) } + + self.wg.Add(1) + result, err = self._Upload(ctx, scope, filename, accessor, + store_as_name, expected_size, mtime, atime, ctime, btime, + mode, reader, 0, upload_id) + closer(result) + return result, err } @@ -383,5 +398,4 @@ expected_size, mtime, upload_id, reader) if err == nil { - CacheUploadResult(scope, store_as_name, result) return result, nil } @@ -473,6 +487,4 @@ result.Sha256 = hex.EncodeToString(sha_sum.Sum(nil)) result.Md5 = hex.EncodeToString(md5_sum.Sum(nil)) - - CacheUploadResult(scope, store_as_name, result) return result, nil } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/uploads/deduplication.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/uploads/deduplication.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/uploads/deduplication.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/uploads/deduplication.go 2025-11-01 15:52:20.000000000 +0000 @@ -16,13 +16,47 @@ type cachedUploadResponse struct { - mu sync.Mutex - + mu sync.Mutex response *UploadResponse } +// Lease the response for a time, when the caller is done with it, +// they can return it by calling the closer callback. It is safe to +// call the closer multiple times - only the first call will take an +// effect. +// +// result, closer := Deduplicate(....) +// defer closer(result) // Ensure that the closer is called for all error paths. +// ... +// Calculate a better result +// closer(result) // This will set the result in the cache. +// The defer call will have no effect if a better result was obtained. +func (self *cachedUploadResponse) LeaseResponse() ( + response *UploadResponse, closer func(response *UploadResponse)) { + + var once sync.Once + + self.mu.Lock() + return self.response, func(response *UploadResponse) { + once.Do(func() { + if response != nil { + self.response = response + } + self.mu.Unlock() + }) + } +} + // Manage the uploader cache - this is used to deduplicate files that // are uploaded multiple time so they only upload one file. func DeduplicateUploads(scope vfilter.Scope, - store_as_name *accessors.OSPath) (*UploadResponse, bool, func()) { + store_as_name *accessors.OSPath) ( + *UploadResponse, func(response *UploadResponse)) { + + cached_response := getCacheResponse(scope, store_as_name) + return cached_response.LeaseResponse() +} + +func getCacheResponse(scope vfilter.Scope, + store_as_name *accessors.OSPath) *cachedUploadResponse { dedup_mu.Lock() @@ -47,6 +81,5 @@ cached_response, ok := cached_response_any.(*cachedUploadResponse) if ok { - cached_response.mu.Lock() - return cached_response.response, true, cached_response.mu.Unlock + return cached_response } } @@ -55,40 +88,6 @@ // other uploaders will wait for us to complete. placeholder := &cachedUploadResponse{} - placeholder.mu.Lock() cache.Set(key, placeholder) - return nil, false, placeholder.mu.Unlock -} -// Add the result into the cache -func CacheUploadResult(scope vfilter.Scope, - store_as_name *accessors.OSPath, - response *UploadResponse) { - root_scope := vql_subsystem.GetRootScope(scope) - cache_any := vql_subsystem.CacheGet(root_scope, UPLOAD_CTX) - if utils.IsNil(cache_any) { - return - } - - cache, ok := cache_any.(*ordereddict.Dict) - if ok { - key := store_as_name.String() - cached_response_any, pres := cache.Get(key) - if !pres { - cached_response_any = &cachedUploadResponse{ - response: response, - } - } - - cached_response, ok := cached_response_any.(*cachedUploadResponse) - if ok { - cached_response.response = response - } else { - // Should not really happen but if it does, we just cache - // it anyway - cached_response = &cachedUploadResponse{ - response: response, - } - } - cache.Set(key, cached_response) - } + return placeholder } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/uploads/file_based.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/uploads/file_based.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/uploads/file_based.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/uploads/file_based.go 2025-11-01 15:52:20.000000000 +0000 @@ -93,8 +93,8 @@ } - cached, pres, closer := DeduplicateUploads(scope, store_as_name) - defer closer() - if pres { - return cached, nil + result, closer := DeduplicateUploads(scope, store_as_name) + defer closer(result) + if result != nil { + return result, nil } @@ -116,18 +116,17 @@ } - result := &UploadResponse{ + result = &UploadResponse{ Path: file_path, Components: store_as_name.Components, } - - CacheUploadResult(scope, store_as_name, result) + closer(result) return result, nil } // Try to collect sparse files if possible - result, err := self.maybeCollectSparseFile( + result, err = self.maybeCollectSparseFile( ctx, reader, store_as_name, file_path) if err == nil { - CacheUploadResult(scope, store_as_name, result) + closer(result) return result, nil } @@ -184,6 +183,5 @@ Md5: hex.EncodeToString(md5_sum.Sum(nil)), } - - CacheUploadResult(scope, store_as_name, result) + closer(result) return result, nil } Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/utils: arch.go diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/utils/copy.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/utils/copy.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/utils/copy.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/utils/copy.go 2025-11-01 15:52:20.000000000 +0000 @@ -4,5 +4,9 @@ "context" "io" + "io/ioutil" "sync" + + "www.velocidex.com/golang/velociraptor/constants" + "www.velocidex.com/golang/vfilter" ) @@ -10,5 +14,5 @@ pool = sync.Pool{ New: func() interface{} { - buffer := make([]byte, 32*1024) + buffer := make([]byte, 1024*1024) return &buffer }, @@ -16,4 +20,53 @@ ) +func ReadAllWithLimit( + fd io.Reader, limit int) ([]byte, error) { + return ioutil.ReadAll(io.LimitReader(fd, int64(limit))) +} + +func ReadAllWithCtx( + ctx context.Context, + scope vfilter.Scope, + fd io.Reader) ([]byte, error) { + + max_size := int64(10 * 1024 * 1024) + + max_size_any, pres := scope.Resolve(constants.HASH_MAX_SIZE) + if pres { + max_size_int, ok := ToInt64(max_size_any) + if ok { + max_size = max_size_int + } + } + + var result []byte + buff := pool.Get().(*[]byte) + defer pool.Put(buff) + + for { + select { + case <-ctx.Done(): + return result, nil + + default: + to_read := max_size - int64(len(result)) + if to_read > int64(len(*buff)) { + to_read = int64(len(*buff)) + } + + n, err := fd.Read((*buff)[:to_read]) + if err != nil && err != io.EOF { + return result, err + } + + if n == 0 { + return result, nil + } + + result = append(result, (*buff)[:n]...) + } + } +} + // An io.Copy() that respects context cancellations. func Copy(ctx context.Context, dst io.Writer, src io.Reader) (n int, err error) { diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/utils/debug.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/utils/debug.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/utils/debug.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/utils/debug.go 2025-11-01 15:52:20.000000000 +0000 @@ -79,8 +79,8 @@ select { case <-ctx.Done(): - fmt.Printf(name + ": Ctx is done!\n") + fmt.Printf("%s: Ctx is done!\n", name) default: - fmt.Printf(name + ": Ctx is still valid!\n") + fmt.Printf("%s: Ctx is still valid!\n", name) } } @@ -89,5 +89,5 @@ go func() { <-ctx.Done() - fmt.Printf(name + ": Ctx done!\n") + fmt.Printf("%s: Ctx done!\n", name) }() } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/utils/errors.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/utils/errors.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/utils/errors.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/utils/errors.go 2025-11-01 15:52:20.000000000 +0000 @@ -23,4 +23,5 @@ CancelledError = errors.New("Cancelled") SecretsEnforced = errors.New("Secrets are enforced - you must specify a secret name") + PermissionDenied = errors.New("PermissionDenied") ) Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/utils: faults Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/utils: http.go Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/utils: logger.go Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/utils: rand diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/utils/read_seek_reader_adapter.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/utils/read_seek_reader_adapter.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/utils/read_seek_reader_adapter.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/utils/read_seek_reader_adapter.go 2025-11-01 15:52:20.000000000 +0000 @@ -4,4 +4,5 @@ "errors" "io" + "sync" ) @@ -11,4 +12,5 @@ type ReadSeekReaderAdapter struct { + mu sync.Mutex reader io.ReaderAt offset int64 @@ -19,5 +21,8 @@ } -func (self ReadSeekReaderAdapter) Close() error { +func (self *ReadSeekReaderAdapter) Close() error { + self.mu.Lock() + defer self.mu.Unlock() + // Try to close our delegate if possible switch t := self.reader.(type) { @@ -39,4 +44,7 @@ func (self *ReadSeekReaderAdapter) Read(buf []byte) (int, error) { + self.mu.Lock() + defer self.mu.Unlock() + if self.eof { return 0, io.EOF @@ -68,4 +76,7 @@ func (self *ReadSeekReaderAdapter) SetSize(size int64) { + self.mu.Lock() + defer self.mu.Unlock() + self.size = size } @@ -80,4 +91,7 @@ } + self.mu.Lock() + defer self.mu.Unlock() + self.offset = offset return offset, nil diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/utils/time.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/utils/time.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/utils/time.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/utils/time.go 2025-11-01 15:52:20.000000000 +0000 @@ -76,4 +76,8 @@ } +func WinFileTime(in int64) time.Time { + return time.Unix((in/10000000)-11644473600, 0).UTC() +} + func init() { vjson.RegisterCustomEncoder(time.Time{}, MarshalTimes) Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/utils: yaml Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75: velociraptor.spec diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/common/env.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/common/env.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/common/env.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/common/env.go 2025-11-01 15:52:20.000000000 +0000 @@ -117,6 +117,8 @@ parts := strings.SplitN(env_var, "=", 2) + // Just hide ShadowedEnv but do not warn about + // it since there is nothing the caller can do + // to avoid it. if utils.InString(ShadowedEnv, parts[0]) { - scope.Log("environ: access to env var %s is denied", parts[0]) continue } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/common/yara.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/common/yara.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/common/yara.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/common/yara.go 2025-11-01 15:52:20.000000000 +0000 @@ -27,5 +27,4 @@ "crypto/md5" "encoding/hex" - "errors" "fmt" "io" @@ -38,8 +37,10 @@ "www.velocidex.com/golang/velociraptor/accessors" "www.velocidex.com/golang/velociraptor/acls" + "www.velocidex.com/golang/velociraptor/constants" "www.velocidex.com/golang/velociraptor/uploads" "www.velocidex.com/golang/velociraptor/utils" "www.velocidex.com/golang/velociraptor/vql" vql_subsystem "www.velocidex.com/golang/velociraptor/vql" + "www.velocidex.com/golang/velociraptor/vql/functions" vfilter "www.velocidex.com/golang/vfilter" "www.velocidex.com/golang/vfilter/arg_parser" @@ -47,20 +48,4 @@ ) -type YaraHit struct { - Name string - Offset uint64 - HexData []string - Data []byte -} - -type YaraResult struct { - Rule string - Meta *ordereddict.Dict - Tags []string - String *YaraHit - File accessors.FileInfo - FileName *accessors.OSPath -} - type YaraScanPluginArgs struct { Rules string `vfilter:"optional,field=rules,doc=Yara rules in the yara DSL or after being compiled by the yarac compiler."` @@ -93,5 +78,5 @@ err := arg_parser.ExtractArgsWithContext(ctx, scope, args, arg) if err != nil { - scope.Log("yara: %v", err) + scope.Error("yara: %v", err) return } @@ -108,5 +93,5 @@ arg.YaraVariables, scope) if err != nil { - scope.Log("yara: %v", err) + functions.DeduplicatedLog(ctx, scope, "ERROR:yara: "+err.Error()) return } @@ -117,4 +102,7 @@ } + logger, closer := utils.NewDeduplicatedLogger(10 * time.Second) + defer closer() + matcher := &scanReporter{ output_chan: output_chan, @@ -123,5 +111,7 @@ context: arg.Context, ctx: ctx, - + log_level: vql_subsystem.GetIntFromRow( + scope, scope, constants.YARA_LOG_LEVEL), + logger: logger, rules: rules, scope: scope, @@ -131,5 +121,5 @@ accessor, err := accessors.GetAccessor(arg.Accessor, scope) if err != nil { - scope.Log("yara: %v", err) + scope.Error("yara: %v", err) return } @@ -144,10 +134,4 @@ matcher.filename = filename - accessor, err := accessors.GetAccessor(arg.Accessor, scope) - if err != nil { - scope.Log("yara: %v", err) - return - } - // As an optimization, we try to call yara's ScanFile API // which mmaps the entire file into memory avoiding the @@ -164,5 +148,5 @@ continue } else { - scope.Log("Directly scanning file %v failed, will use accessor", + scope.Log("yara: Directly scanning file %v failed, will use accessor", filename.String()) } @@ -195,25 +179,27 @@ } cached_result := vql_subsystem.CacheGet(scope, key) - if cached_result == nil { - compiled_rules, err := compileRules( - scope, vars, key, namespace, rules) - if err != nil { - vql_subsystem.CacheSet(scope, key, err) - return nil, err - } - - // Cache the successful rules for further use - vql_subsystem.CacheSet(scope, key, compiled_rules) - return compiled_rules, nil - } - - switch t := cached_result.(type) { - case error: - return nil, t - case *yara.Rules: - return t, nil - default: - return nil, errors.New("Error") + if cached_result != nil { + switch t := cached_result.(type) { + case error: + return nil, t + + case *yara.Rules: + return t, nil + + default: + // Unknown type - recompile again. + } + } + + compiled_rules, err := compileRules( + scope, vars, key, namespace, rules) + if err != nil { + vql_subsystem.CacheSet(scope, key, err) + return nil, err } + + // Cache the successful rules for further use + vql_subsystem.CacheSet(scope, key, compiled_rules) + return compiled_rules, nil } @@ -318,5 +304,8 @@ buf := make([]byte, self.blocksize) - // self.scope.Log("Scanning %v from %#0x to %#0x", self.filename, start, end) + if self.log_level >= 1 { + self.logger.Log(self.scope, + "Scanning %v from %#0x to %#0x", self.filename, start, end) + } // base_offset reflects the file offset where we scan. @@ -366,4 +355,11 @@ self.reader = nil + if self.log_level >= 2 { + self.logger.Log(self.scope, + "Range %v from %#0x to %#0x: Got to %#0x (%d %%)", + self.filename, start, end, self.base_offset, + 100*(self.base_offset-start)/(end-start)) + } + // We count an op as one MB scanned. self.scope.ChargeOp() @@ -431,4 +427,6 @@ reader io.ReaderAt ctx context.Context + log_level uint64 + logger *utils.DeduplicatedLogger // Internal scan state @@ -629,5 +627,5 @@ arg.Rules, arg.YaraVariables, scope) if err != nil { - scope.Log("proc_yara: %v", err) + functions.DeduplicatedLog(ctx, scope, "ERROR:proc_yara: "+err.Error()) return } @@ -635,5 +633,5 @@ scanner, err := yara.NewScanner(rules) if err != nil { - scope.Log("proc_yara: %v", err) + functions.DeduplicatedLog(ctx, scope, "ERROR:proc_yara: "+err.Error()) return } Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/common: yara_common.go Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/common: yarax.go Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql: debug Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/filesystem: cat.go diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/filesystem/tempfile.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/filesystem/tempfile.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/filesystem/tempfile.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/filesystem/tempfile.go 2025-11-01 15:52:20.000000000 +0000 @@ -98,5 +98,5 @@ if arg.RemoveLast { - scope.Log("Adding global destructor for %v", tmpfile.Name()) + scope.Log("tempfile: Adding global destructor for %v", tmpfile.Name()) root_scope := vql_subsystem.GetRootScope(scope) err := root_scope.AddDestructor(func() { @@ -161,5 +161,5 @@ if arg.RemoveLast { - scope.Log("Adding global destructor for %v", dir) + scope.Log("tempdir: Adding global destructor for %v", dir) root_scope := vql_subsystem.GetRootScope(scope) err := root_scope.AddDestructor(func() { diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/functions/hash.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/functions/hash.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/functions/hash.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/functions/hash.go 2025-11-01 15:52:20.000000000 +0000 @@ -31,4 +31,5 @@ "www.velocidex.com/golang/velociraptor/accessors" "www.velocidex.com/golang/velociraptor/acls" + "www.velocidex.com/golang/velociraptor/constants" "www.velocidex.com/golang/velociraptor/vql" vql_subsystem "www.velocidex.com/golang/velociraptor/vql" @@ -66,4 +67,5 @@ Accessor string `vfilter:"optional,field=accessor,doc=The accessor to use"` HashSelect []string `vfilter:"optional,field=hashselect,doc=The hash function to use (MD5,SHA1,SHA256)"` + MaxSize uint64 `vfilter:"optional,field=max_size,doc=The maximum size of the file that will be hashed (default 100mb)"` } @@ -85,4 +87,13 @@ } + if arg.MaxSize == 0 { + arg.MaxSize = vql_subsystem.GetIntFromRow( + scope, scope, constants.HASH_MAX_SIZE) + } + + if arg.MaxSize == 0 { + arg.MaxSize = 100 * 1024 * 1024 + } + cached_buffer := pool.Get().(*[]byte) defer pool.Put(cached_buffer) @@ -128,4 +139,5 @@ } + var count uint64 for { select { @@ -136,4 +148,11 @@ n, err := file.Read(buf) + count += uint64(n) + if count > arg.MaxSize { + DeduplicatedLog( + ctx, scope, "Hash of %v aborted due to exceeding size", arg.Path) + n = 0 + } + // We are done! if n == 0 || err == io.EOF { @@ -184,5 +203,5 @@ Doc: "Calculate the hash of a file.", ArgType: type_map.AddType(scope, &HashFunctionArgs{}), - Version: 2, + Version: 3, Metadata: vql.VQLMetadata().Permissions(acls.FILESYSTEM_READ).Build(), } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/functions/sleep.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/functions/sleep.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/functions/sleep.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/functions/sleep.go 2025-11-01 15:52:20.000000000 +0000 @@ -3,7 +3,8 @@ import ( "context" - "math/rand" "time" + "www.velocidex.com/golang/velociraptor/utils/rand" + "github.com/Velocidex/ordereddict" vql_subsystem "www.velocidex.com/golang/velociraptor/vql" diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/functions/time.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/functions/time.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/functions/time.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/functions/time.go 2025-11-01 15:52:20.000000000 +0000 @@ -177,5 +177,5 @@ if arg.WinFileTime > 0 { - return time.Unix((arg.WinFileTime/10000000)-11644473600, 0).UTC() + return utils.WinFileTime(arg.WinFileTime) } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/golang/goroutines.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/golang/goroutines.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/golang/goroutines.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/golang/goroutines.go 2025-11-01 15:52:20.000000000 +0000 @@ -6,5 +6,4 @@ "context" "fmt" - "io/ioutil" "runtime/pprof" @@ -12,4 +11,5 @@ "google.golang.org/protobuf/proto" "www.velocidex.com/golang/velociraptor/acls" + "www.velocidex.com/golang/velociraptor/constants" "www.velocidex.com/golang/velociraptor/services/debug" "www.velocidex.com/golang/velociraptor/utils" @@ -61,5 +61,6 @@ } - cleartext, err := ioutil.ReadAll(reader) + cleartext, err := utils.ReadAllWithLimit(reader, + constants.MAX_MEMORY) if err != nil { return diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/info.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/info.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/info.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/info.go 2025-11-01 15:52:20.000000000 +0000 @@ -22,5 +22,4 @@ "os" "runtime" - "strings" "time" @@ -29,4 +28,5 @@ "www.velocidex.com/golang/velociraptor/acls" + "www.velocidex.com/golang/velociraptor/utils" "www.velocidex.com/golang/velociraptor/vql/psutils" "www.velocidex.com/golang/vfilter" @@ -105,5 +105,5 @@ item := GetInfo(info). Set("Fqdn", fqdn.Get()). - Set("Architecture", getArch()) + Set("Architecture", utils.GetArch()) result = append(result, item) @@ -113,23 +113,2 @@ }) } - -func getArch() string { - res := runtime.GOARCH - - // On windows, detect if we are running in Wow64 - if runtime.GOOS == "windows" { - proc_arch := os.Getenv("PROCESSOR_ARCHITECTURE") - if proc_arch != "" { - res = proc_arch - - if proc_arch == "x86" { - wow_arch := os.Getenv("PROCESSOR_ARCHITEW6432") - if wow_arch == "AMD64" { - res = "wow64" - } - } - } - } - - return strings.ToLower(res) -} diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/networking/http_client.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/networking/http_client.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/networking/http_client.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/networking/http_client.go 2025-11-01 15:52:20.000000000 +0000 @@ -507,5 +507,5 @@ if arg.RemoveLast { - scope.Log("Adding global destructor for %v", tmpfile.Name()) + scope.Log("http_client: Adding global destructor for %v", tmpfile.Name()) root_scope := vql_subsystem.GetRootScope(scope) err := root_scope.AddDestructor(func() { diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/networking/mail.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/networking/mail.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/networking/mail.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/networking/mail.go 2025-11-01 15:52:20.000000000 +0000 @@ -257,6 +257,9 @@ } - if config_obj.Security != nil && - !config_obj.Security.VqlMustUseSecrets { + if config_obj.Security == nil { + return nil + } + + if !config_obj.Security.VqlMustUseSecrets { return nil } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/networking/multipart.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/networking/multipart.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/networking/multipart.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/networking/multipart.go 2025-11-01 15:52:20.000000000 +0000 @@ -6,5 +6,4 @@ "fmt" "io" - "io/ioutil" "mime/multipart" "strings" @@ -12,4 +11,5 @@ "github.com/Velocidex/ordereddict" "www.velocidex.com/golang/velociraptor/accessors" + "www.velocidex.com/golang/velociraptor/constants" "www.velocidex.com/golang/velociraptor/utils" vfilter "www.velocidex.com/golang/vfilter" @@ -166,5 +166,6 @@ func (self *multiPartReader) Debug() string { - result, err := ioutil.ReadAll(self.pipe_reader) + result, err := utils.ReadAllWithLimit(self.pipe_reader, + constants.MAX_MEMORY) if err != nil { return fmt.Sprintf("Error: %v\n", err) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/networking/secrets.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/networking/secrets.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/networking/secrets.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/networking/secrets.go 2025-11-01 15:52:20.000000000 +0000 @@ -142,5 +142,8 @@ } - if config_obj.Security != nil && + // The Security part of the config is normally only on the server. + if config_obj.Security == nil || + + // The default is to allow arbitrary URL access. !config_obj.Security.VqlMustUseSecrets { return diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/networking/upload.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/networking/upload.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/networking/upload.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/networking/upload.go 2025-11-01 15:52:20.000000000 +0000 @@ -123,5 +123,5 @@ } } - return upload_response + return upload_response.AsDict() } @@ -134,4 +134,5 @@ ArgType: type_map.AddType(scope, &UploadFunctionArgs{}), Metadata: vql.VQLMetadata().Permissions(acls.FILESYSTEM_READ).Build(), + Version: 2, } } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/networking/wrapper.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/networking/wrapper.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/networking/wrapper.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/networking/wrapper.go 2025-11-01 15:52:20.000000000 +0000 @@ -14,4 +14,5 @@ "www.velocidex.com/golang/velociraptor/accessors/smb" "www.velocidex.com/golang/velociraptor/utils" + "www.velocidex.com/golang/velociraptor/utils/faults" vql_subsystem "www.velocidex.com/golang/velociraptor/vql" vfilter "www.velocidex.com/golang/vfilter" @@ -47,4 +48,7 @@ func (self httpClientWrapper) Do(req *http.Request) (*http.Response, error) { + // Emulate a significant network delay on HTTP + defer faults.FaultInjector.BlockHTTPDo(req.Context()) + if req.URL != nil { // Handle different url schemes diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/parsers/authenticode/cat.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/parsers/authenticode/cat.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/parsers/authenticode/cat.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/parsers/authenticode/cat.go 2025-11-01 15:52:20.000000000 +0000 @@ -7,5 +7,4 @@ "errors" "fmt" - "io/ioutil" "os" "syscall" @@ -158,5 +157,5 @@ return err } - data, err := ioutil.ReadAll(cat_fd) + data, err := utils.ReadAllWithLimit(cat_fd, constants.MAX_MEMORY) if err != nil { return err diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/parsers/crypto/pubkey.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/parsers/crypto/pubkey.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/parsers/crypto/pubkey.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/parsers/crypto/pubkey.go 2025-11-01 15:52:20.000000000 +0000 @@ -6,5 +6,4 @@ "context" "io" - "io/ioutil" "strings" @@ -15,5 +14,7 @@ "www.velocidex.com/golang/velociraptor/acls" + "www.velocidex.com/golang/velociraptor/constants" crypto_utils "www.velocidex.com/golang/velociraptor/crypto/utils" + "www.velocidex.com/golang/velociraptor/utils" "www.velocidex.com/golang/velociraptor/vql" vql_subsystem "www.velocidex.com/golang/velociraptor/vql" @@ -206,5 +207,6 @@ return vfilter.Null{} } - bytes, err := ioutil.ReadAll(m.UnverifiedBody) + bytes, err := utils.ReadAllWithLimit(m.UnverifiedBody, + constants.MAX_MEMORY) if err != nil { scope.Log("ERROR:pk_decrypt: %s", err.Error()) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/parsers/journald/journald.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/parsers/journald/journald.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/parsers/journald/journald.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/parsers/journald/journald.go 2025-11-01 15:52:20.000000000 +0000 @@ -9,6 +9,4 @@ "www.velocidex.com/golang/velociraptor/accessors" "www.velocidex.com/golang/velociraptor/acls" - "www.velocidex.com/golang/velociraptor/artifacts" - config_proto "www.velocidex.com/golang/velociraptor/config/proto" "www.velocidex.com/golang/velociraptor/vql" vql_subsystem "www.velocidex.com/golang/velociraptor/vql" @@ -75,5 +73,5 @@ journal.MaxTime = arg.EndTime - for log := range journal.GetLogs() { + for log := range journal.GetLogs(ctx) { select { case <-ctx.Done(): @@ -114,14 +112,4 @@ } - // This plugin needs to be running on clients which have no - // server config object. - client_config_obj, ok := artifacts.GetConfig(scope) - if !ok { - scope.Log("watch_journald: unable to get config") - return - } - - config_obj := &config_proto.Config{Client: client_config_obj} - event_channel := make(chan vfilter.Row) @@ -129,5 +117,5 @@ // global event. for _, filename := range arg.Filenames { - cancel := GlobalJournaldService(config_obj).Register( + cancel := gJournaldService.Register( filename, arg.Accessor, ctx, scope, arg.Raw, event_channel) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/parsers/journald/watcher.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/parsers/journald/watcher.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/parsers/journald/watcher.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/parsers/journald/watcher.go 2025-11-01 15:52:20.000000000 +0000 @@ -17,16 +17,10 @@ var ( - mu sync.Mutex gJournaldService *JournaldWatcherService ) -func GlobalJournaldService(config_obj *config_proto.Config) *JournaldWatcherService { - mu.Lock() - defer mu.Unlock() - - if gJournaldService == nil { - gJournaldService = NewJournaldWatcherService(config_obj) - } - return gJournaldService +func StartGlobalJournaldService( + ctx context.Context, config_obj *config_proto.Config) { + gJournaldService = NewJournaldWatcherService(ctx, config_obj) } @@ -43,7 +37,9 @@ monitor_count int + ctx context.Context } func NewJournaldWatcherService( + ctx context.Context, config_obj *config_proto.Config) *JournaldWatcherService { @@ -61,4 +57,5 @@ return &JournaldWatcherService{ + ctx: ctx, sleep_time: sleep_time, buffer_size: buffer_size, @@ -215,5 +212,5 @@ } - for log := range journal.GetLogs() { + for log := range journal.GetLogs(self.ctx) { handles = self.distributeLog(log, key, handles) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/parsers/json.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/parsers/json.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/parsers/json.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/parsers/json.go 2025-11-01 15:52:20.000000000 +0000 @@ -37,4 +37,5 @@ config_proto "www.velocidex.com/golang/velociraptor/config/proto" "www.velocidex.com/golang/velociraptor/json" + json_tools "www.velocidex.com/golang/velociraptor/tools/json" utils "www.velocidex.com/golang/velociraptor/utils" "www.velocidex.com/golang/velociraptor/vql" @@ -51,5 +52,6 @@ type ParseJsonFunctionArg struct { - Data string `vfilter:"required,field=data,doc=Json encoded string."` + Data string `vfilter:"required,field=data,doc=Json encoded string."` + Schema []string `vfilter:"optional,field=schema,doc=Json schema to use for validation."` } type ParseJsonFunction struct{} @@ -60,4 +62,5 @@ Doc: "Parse a JSON string into an object.", ArgType: type_map.AddType(scope, &ParseJsonFunctionArg{}), + Version: 2, } } @@ -76,7 +79,20 @@ } + if len(arg.Schema) > 0 { + var options json_tools.ValidationOptions + result, errs := json_tools.ParseJsonToObjectWithSchema( + arg.Data, arg.Schema, options) + if len(errs) > 0 { + for _, err := range errs { + scope.Log("ERROR:parse_json: %v", err) + } + return &vfilter.Null{} + } + return result + } + result, err := utils.ParseJsonToObject([]byte(arg.Data)) if err != nil { - scope.Log("parse_json: %v", err) + scope.Log("parse_json: %v: %v", err, utils.Elide(arg.Data, 100)) return &vfilter.Null{} } @@ -614,5 +630,5 @@ default: - scope.Log("write_csv: Unsupported accessor for writing %v", arg.Accessor) + scope.Log("write_jsonl: Unsupported accessor for writing %v", arg.Accessor) return } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/parsers/lzxpress.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/parsers/lzxpress.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/parsers/lzxpress.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/parsers/lzxpress.go 2025-11-01 15:52:20.000000000 +0000 @@ -22,4 +22,7 @@ scope vfilter.Scope, args *ordereddict.Dict) vfilter.Any { + + defer vql_subsystem.CheckForPanic(scope, "lzxpress_decompress") + arg := &LZXpressFunctionArgs{} err := arg_parser.ExtractArgsWithContext(ctx, scope, args, arg) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/parsers/ole.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/parsers/ole.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/parsers/ole.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/parsers/ole.go 2025-11-01 15:52:20.000000000 +0000 @@ -22,5 +22,4 @@ "errors" "io" - "io/ioutil" "github.com/Velocidex/ordereddict" @@ -94,5 +93,5 @@ } - data, err := ioutil.ReadAll(io.LimitReader(fd, constants.MAX_MEMORY)) + data, err := utils.ReadAllWithLimit(fd, constants.MAX_MEMORY) if err != nil { return nil, err @@ -116,6 +115,6 @@ return nil, err } - data, err := ioutil.ReadAll( - io.LimitReader(rc, constants.MAX_MEMORY)) + data, err := utils.ReadAllWithLimit(rc, + constants.MAX_MEMORY) if err != nil { return nil, err diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/parsers/pe.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/parsers/pe.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/parsers/pe.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/parsers/pe.go 2025-11-01 15:52:20.000000000 +0000 @@ -89,4 +89,11 @@ } + // Set the max hash size if needed + hash_max_size := vql_subsystem.GetIntFromRow( + scope, scope, constants.HASH_MAX_SIZE) + if hash_max_size > 0 { + pe.SetHashSizeLimit(int64(hash_max_size)) + } + // Return a lazy object. return ordereddict.NewDict(). @@ -125,5 +132,9 @@ }). Set("AuthenticodeHash", func() vfilter.Any { - return pe_file.CalcHashToDict() + res, err := pe_file.CalcHashToDict(ctx) + if err != nil { + res = ordereddict.NewDict() + } + return res }) } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/parsers/syslog/scanner.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/parsers/syslog/scanner.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/parsers/syslog/scanner.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/parsers/syslog/scanner.go 2025-11-01 15:52:20.000000000 +0000 @@ -8,4 +8,6 @@ "os" "strings" + "sync" + "time" "github.com/Velocidex/ordereddict" @@ -14,4 +16,5 @@ "www.velocidex.com/golang/velociraptor/artifacts" config_proto "www.velocidex.com/golang/velociraptor/config/proto" + "www.velocidex.com/golang/velociraptor/utils" "www.velocidex.com/golang/velociraptor/vql" vql_subsystem "www.velocidex.com/golang/velociraptor/vql" @@ -20,4 +23,8 @@ ) +const ( + DUMP_FILES = true +) + type ScannerPluginArgs struct { Filenames []*accessors.OSPath `vfilter:"required,field=filename,doc=A list of log files to parse."` @@ -100,4 +107,159 @@ } +type fileEntry struct { + full_path *accessors.OSPath + cancel func() +} + +type fileManager struct { + mu sync.Mutex + files map[string]*fileEntry + + config_obj *config_proto.Config + accessor string + ctx context.Context + scope vfilter.Scope + event_channel chan vfilter.Row + query vfilter.StoredQuery +} + +func (self *fileManager) AddFiles( + files []*accessors.OSPath, dump_new bool) { + self.mu.Lock() + defer self.mu.Unlock() + + new_files := make(map[string]*fileEntry) + for _, f := range files { + key := f.String() + + entry, pres := self.files[key] + if pres { + new_files[key] = entry + continue + } + entry = &fileEntry{ + full_path: f, + } + + syslog_service := GlobalSyslogService(self.config_obj) + + entry.cancel = syslog_service.Register( + f, self.accessor, self.ctx, self.scope, + self.event_channel) + new_files[key] = entry + + // This is a new file - dump it if we need to. + if dump_new { + accessor, err := accessors.GetAccessor(self.accessor, self.scope) + if err == nil { + _ = syslog_service.monitorOnce( + entry.full_path, self.accessor, accessor, &Cursor{}) + } + } + } + + // Delete old trackers if the file is disappeared. + for key, entry := range self.files { + _, pres := new_files[key] + if !pres { + entry.cancel() + } + } + + self.files = new_files + + GlobalSyslogService(self.config_obj).Reap() +} + +// Run the query periodically and update the watched files list. NOTE: +// Watched files are never removed, only added by the query. +func (self *fileManager) Start() { + if self.query == nil { + return + } + + sleep_time := 3 * time.Second + if self.config_obj.Defaults != nil { + if self.config_obj.Defaults.WatchPluginFrequency > 0 { + sleep_time = time.Second * time.Duration( + self.config_obj.Defaults.WatchPluginFrequency) + } + } + + // First run through do not dump existing lines + var files []*accessors.OSPath + + for row := range self.query.Eval(self.ctx, self.scope) { + full_path_any, pres := self.scope.Associative(row, "OSPath") + if pres { + full_path, ok := full_path_any.(*accessors.OSPath) + if ok { + files = append(files, full_path) + } + } + } + self.AddFiles(files, !DUMP_FILES) + + // Now periodically check for updates. If a new file appears by + // the query, dump it from the start. + go func() { + for { + var files []*accessors.OSPath + + for row := range self.query.Eval(self.ctx, self.scope) { + full_path_any, pres := self.scope.Associative(row, "OSPath") + if pres { + full_path, ok := full_path_any.(*accessors.OSPath) + if ok { + files = append(files, full_path) + } + } + } + self.AddFiles(files, DUMP_FILES) + utils.SleepWithCtx(self.ctx, sleep_time) + } + }() +} + +func (self *fileManager) Close() { + self.mu.Lock() + defer self.mu.Unlock() + + if self.files == nil { + return + } + + for _, entry := range self.files { + entry.cancel() + } + + close(self.event_channel) + self.files = nil +} + +func newFileManager( + ctx context.Context, + scope vfilter.Scope, + config_obj *config_proto.Config, + accessor string, + query vfilter.StoredQuery) *fileManager { + return &fileManager{ + ctx: ctx, + config_obj: config_obj, + accessor: accessor, + scope: scope, + query: query, + event_channel: make(chan vfilter.Row), + files: make(map[string]*fileEntry), + } +} + +type WatchSyslogPluginArgs struct { + Filenames []*accessors.OSPath `vfilter:"optional,field=filename,doc=A list of log files to parse."` + Accessor string `vfilter:"optional,field=accessor,doc=The accessor to use."` + BufferSize int `vfilter:"optional,field=buffer_size,doc=Maximum size of line buffer."` + Query vfilter.StoredQuery `vfilter:"optional,field=query,doc=If specified we run this query periodically to watch for new files. Rows must have an OSPath column."` +} + type WatchSyslogPlugin struct{} @@ -112,5 +274,5 @@ defer vql_subsystem.RegisterMonitor(ctx, "watch_syslog", args)() - arg := &ScannerPluginArgs{} + arg := &WatchSyslogPluginArgs{} err := arg_parser.ExtractArgsWithContext(ctx, scope, args, arg) if err != nil { @@ -128,16 +290,10 @@ config_obj := &config_proto.Config{Client: client_config_obj} + manager := newFileManager(ctx, scope, config_obj, + arg.Accessor, arg.Query) + defer manager.Close() - event_channel := make(chan vfilter.Row) - - // Register the output channel as a listener to the - // global event. - for _, filename := range arg.Filenames { - cancel := GlobalSyslogService(config_obj).Register( - filename, arg.Accessor, ctx, scope, - event_channel) - - defer cancel() - } + manager.AddFiles(arg.Filenames, !DUMP_FILES) + manager.Start() // Wait until the query is complete. @@ -147,5 +303,9 @@ return - case event := <-event_channel: + case event, ok := <-manager.event_channel: + if !ok { + return + } + select { case <-ctx.Done(): @@ -165,5 +325,5 @@ Name: "watch_syslog", Doc: "Watch a syslog file and stream events from it. ", - ArgType: type_map.AddType(scope, &ScannerPluginArgs{}), + ArgType: type_map.AddType(scope, &WatchSyslogPluginArgs{}), Metadata: vql.VQLMetadata().Permissions(acls.FILESYSTEM_READ).Build(), } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/parsers/syslog/watcher.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/parsers/syslog/watcher.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/parsers/syslog/watcher.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/parsers/syslog/watcher.go 2025-11-01 15:52:20.000000000 +0000 @@ -192,4 +192,27 @@ } +func (self *SyslogWatcherService) Reap() { + self.mu.Lock() + defer self.mu.Unlock() + + new_registrations := make(map[string][]*Handle) + + for key, handles := range self.registrations { + new_handles := make([]*Handle, 0, len(handles)) + for _, handle := range handles { + select { + case <-handle.ctx.Done(): + handle.scope.Log("Unregistering watcher for %v", key) + default: + new_handles = append(new_handles, handle) + } + } + if len(new_handles) > 0 { + new_registrations[key] = new_handles + } + } + self.registrations = new_registrations +} + func (self *SyslogWatcherService) monitorOnce( filename *accessors.OSPath, @@ -327,5 +350,7 @@ key string, handles []*Handle) []*Handle { - event := ordereddict.NewDict().Set("Line", line) + event := ordereddict.NewDict(). + Set("OSPath", filename). + Set("Line", line) new_handles := make([]*Handle, 0, len(handles)) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/parsers/syslog/watcher_test.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/parsers/syslog/watcher_test.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/parsers/syslog/watcher_test.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/parsers/syslog/watcher_test.go 2025-11-01 15:52:20.000000000 +0000 @@ -70,6 +70,8 @@ return } + line, _ := self.scope.Associative(item, "Line") self.mu.Lock() - self.result = append(self.result, item) + self.result = append(self.result, ordereddict.NewDict(). + Set("Line", line)) self.mu.Unlock() } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/parsers/yaml.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/parsers/yaml.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/parsers/yaml.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/parsers/yaml.go 2025-11-01 15:52:20.000000000 +0000 @@ -3,5 +3,4 @@ import ( "context" - "io/ioutil" "github.com/Velocidex/ordereddict" @@ -9,4 +8,7 @@ "www.velocidex.com/golang/velociraptor/accessors" "www.velocidex.com/golang/velociraptor/acls" + "www.velocidex.com/golang/velociraptor/json" + json_tools "www.velocidex.com/golang/velociraptor/tools/json" + utils "www.velocidex.com/golang/velociraptor/utils" "www.velocidex.com/golang/velociraptor/vql" vql_subsystem "www.velocidex.com/golang/velociraptor/vql" @@ -18,4 +20,5 @@ Filename *accessors.OSPath `vfilter:"required,field=filename,doc=Yaml Filename"` Accessor string `vfilter:"optional,field=accessor,doc=File accessor"` + Schema []string `vfilter:"optional,field=schema,doc=Json schema to use for validation."` } @@ -50,5 +53,5 @@ defer fd.Close() - data, err := ioutil.ReadAll(fd) + data, err := utils.ReadAllWithCtx(ctx, scope, fd) if err != nil { scope.Log("parse_yaml: %v", err) @@ -64,5 +67,29 @@ return nil } - return yamlToDict(parsed) + result := yamlToDict(parsed) + result_dict, ok := result.(*ordereddict.Dict) + if len(arg.Schema) == 0 || !ok { + return result + } + + // Validating the json requires us to pass to parse_json. + var options json_tools.ValidationOptions + serialized, err := json.Marshal(result) + if err != nil { + scope.Log("parse_yaml: %v", err) + return &vfilter.Null{} + } + + intermediate, schema, errs := json_tools.ParseJsonToMapWithSchema( + string(serialized), arg.Schema, options) + if len(errs) > 0 { + for _, err := range errs { + scope.Log("ERROR:parse_yaml: %v", err) + } + return &vfilter.Null{} + } + + json_tools.PopulateDefaults(result_dict, intermediate, schema) + return result_dict } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/protocols/dict.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/protocols/dict.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/protocols/dict.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/protocols/dict.go 2025-11-01 15:52:20.000000000 +0000 @@ -193,4 +193,33 @@ } +type _LtDict struct{} + +func (self _LtDict) Applicable(a, b types.Any) bool { + _, a_ok := a.(*ordereddict.Dict) + _, b_ok := b.(*ordereddict.Dict) + + return a_ok || b_ok +} + +func (self _LtDict) Lt(scope types.Scope, a types.Any, b types.Any) bool { + a_dict, a_ok := a.(*ordereddict.Dict) + b_dict, b_ok := b.(*ordereddict.Dict) + + if !a_ok && b_ok { + return true + } + + if !b_ok && a_ok { + return false + } + + if !b_ok && !a_ok { + return false + } + + return a_dict.Len() < b_dict.Len() + +} + func init() { vql_subsystem.RegisterProtocol(&_RegexDict{}) @@ -200,3 +229,4 @@ vql_subsystem.RegisterProtocol(&_MulDict{}) vql_subsystem.RegisterProtocol(&_AddMap{}) + vql_subsystem.RegisterProtocol(&_LtDict{}) } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/server/compress.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/server/compress.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/server/compress.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/server/compress.go 2025-11-01 15:52:20.000000000 +0000 @@ -36,5 +36,5 @@ type CompressArgs struct { Path string `vfilter:"required,field=path,doc=A path to compress"` - Output string `vfilter:"optional,field=output,doc=A path to write the output - default is the path with a .gz extension"` + Output string `vfilter:"required,field=output,doc=A path to write the output - default is the path with a .gz extension"` } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/server/downloads/downloads.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/server/downloads/downloads.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/server/downloads/downloads.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/server/downloads/downloads.go 2025-11-01 15:52:20.000000000 +0000 @@ -6,5 +6,4 @@ "context" "io" - "io/ioutil" "sync" "time" @@ -17,4 +16,5 @@ 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/file_store" "www.velocidex.com/golang/velociraptor/file_store/api" @@ -628,5 +628,5 @@ defer idx_fd.Close() - serialized, err := ioutil.ReadAll(idx_fd) + serialized, err := utils.ReadAllWithLimit(idx_fd, constants.MAX_MEMORY) if err != nil { return reader diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/server/downloads/fixtures/TestExportCollectionServerArtifact.golden /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/server/downloads/fixtures/TestExportCollectionServerArtifact.golden --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/server/downloads/fixtures/TestExportCollectionServerArtifact.golden 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/server/downloads/fixtures/TestExportCollectionServerArtifact.golden 2025-11-01 15:52:20.000000000 +0000 @@ -116,5 +116,5 @@ "results/TestArtifact.csv": [ "Col,OSPath,Upload1,Upload2", - "Hello,/bin/ls,\"{\"\"Path\"\":\"\"/test.txt\"\",\"\"Size\"\":9,\"\"StoredSize\"\":9,\"\"sha256\"\":\"\"2d27ec8437ec76ec2db484c98ed89f7793f0575e271518dd1d62a18fde6e202d\"\",\"\"md5\"\":\"\"30057e5031bcf44d47b005a1f1700f7b\"\",\"\"Components\"\":[\"\"clients\"\",\"\"server\"\",\"\"collections\"\",\"\"F.1234\"\",\"\"uploads\"\",\"\"data\"\",\"\"test.txt\"\"],\"\"UploadId\"\":0}\",\"{\"\"Path\"\":\"\"/test2.txt\"\",\"\"Size\"\":15,\"\"StoredSize\"\":15,\"\"sha256\"\":\"\"c42af293c4c339ce802ae6827124cc416bfffb574da3d9f35068b6068a75528b\"\",\"\"md5\"\":\"\"d89eef4147c900bc8af8a49e73a09de4\"\",\"\"Components\"\":[\"\"clients\"\",\"\"server\"\",\"\"collections\"\",\"\"F.1234\"\",\"\"uploads\"\",\"\"data\"\",\"\"test2.txt\"\"],\"\"UploadId\"\":0}\"", + "Hello,/bin/ls,\"{\"\"Path\"\":\"\"/test.txt\"\",\"\"Size\"\":9,\"\"UploadId\"\":0,\"\"StoredSize\"\":9,\"\"sha256\"\":\"\"2d27ec8437ec76ec2db484c98ed89f7793f0575e271518dd1d62a18fde6e202d\"\",\"\"md5\"\":\"\"30057e5031bcf44d47b005a1f1700f7b\"\",\"\"Components\"\":[\"\"clients\"\",\"\"server\"\",\"\"collections\"\",\"\"F.1234\"\",\"\"uploads\"\",\"\"data\"\",\"\"test.txt\"\"]}\",\"{\"\"Path\"\":\"\"/test2.txt\"\",\"\"Size\"\":15,\"\"UploadId\"\":0,\"\"StoredSize\"\":15,\"\"sha256\"\":\"\"c42af293c4c339ce802ae6827124cc416bfffb574da3d9f35068b6068a75528b\"\",\"\"md5\"\":\"\"d89eef4147c900bc8af8a49e73a09de4\"\",\"\"Components\"\":[\"\"clients\"\",\"\"server\"\",\"\"collections\"\",\"\"F.1234\"\",\"\"uploads\"\",\"\"data\"\",\"\"test2.txt\"\"]}\"", "" ], @@ -126,4 +126,5 @@ "Path": "/test.txt", "Size": 9, + "UploadId": 0, "StoredSize": 9, "sha256": "2d27ec8437ec76ec2db484c98ed89f7793f0575e271518dd1d62a18fde6e202d", @@ -137,10 +138,10 @@ "data", "test.txt" - ], - "UploadId": 0 + ] }, "Upload2": { "Path": "/test2.txt", "Size": 15, + "UploadId": 0, "StoredSize": 15, "sha256": "c42af293c4c339ce802ae6827124cc416bfffb574da3d9f35068b6068a75528b", @@ -154,6 +155,5 @@ "data", "test2.txt" - ], - "UploadId": 0 + ] } } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/server/elastic.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/server/elastic.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/server/elastic.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/server/elastic.go 2025-11-01 15:52:20.000000000 +0000 @@ -41,5 +41,4 @@ "fmt" "io" - "io/ioutil" "net/http" "strings" @@ -240,6 +239,7 @@ } - id = int64(utils.GetId()) - err := append_row_to_buffer(ctx, scope, action, row, id, &buf, arg, opts) + id += int64(utils.GetId()) + err := append_row_to_buffer(ctx, scope, action, row, + id, &buf, arg, opts) if err != nil { scope.Log("elastic: %v", err) @@ -280,12 +280,21 @@ } + // Allow the user to specify the elastic document ID as the _id + // column. + _id, pres := row_dict.GetString("_id") + if pres { + row_dict.Delete("_id") + } else { + _id = fmt.Sprintf("%v", id) + } + var meta []byte pipeline := arg.PipeLine if pipeline != "" { - meta = []byte(fmt.Sprintf(`{ %q : {"_id" : "%d", "_index": %q, "pipeline": %q } }%s`, - action, id, index, pipeline, "\n")) + meta = []byte(fmt.Sprintf(`{ %q : {"_id" : "%s", "_index": %q, "pipeline": %q } }%s`, + action, _id, index, pipeline, "\n")) } else { - meta = []byte(fmt.Sprintf(`{ %q : {"_id" : "%d", "_index": %q} }%s`, - action, id, index, "\n")) + meta = []byte(fmt.Sprintf(`{ %q : {"_id" : "%s", "_index": %q} }%s`, + action, _id, index, "\n")) } @@ -326,5 +335,5 @@ var response *ordereddict.Dict - b1, err := ioutil.ReadAll(res.Body) + b1, err := utils.ReadAllWithLimit(res.Body, constants.MAX_MEMORY) if err == nil { response, err = utils.ParseJsonToObject(b1) @@ -390,6 +399,9 @@ } - if config_obj.Security != nil && - !config_obj.Security.VqlMustUseSecrets { + if config_obj.Security == nil { + return nil + } + + if !config_obj.Security.VqlMustUseSecrets { return nil } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/server/flows/flows.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/server/flows/flows.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/server/flows/flows.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/server/flows/flows.go 2025-11-01 15:52:20.000000000 +0000 @@ -57,4 +57,18 @@ } + client_info_manager, err := services.GetClientInfoManager(config_obj) + if err != nil { + scope.Log("flows: %v", err) + return + } + + // Check the client exists at all. + _, err = client_info_manager.Get(ctx, arg.ClientId) + if err != nil { + scope.Log("flows: unable to get client %v: %v", + arg.ClientId, err) + return + } + launcher, err := services.GetLauncher(config_obj) if err != nil { diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/server/flows/parallel_test.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/server/flows/parallel_test.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/server/flows/parallel_test.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/server/flows/parallel_test.go 2025-11-01 15:52:20.000000000 +0000 @@ -11,4 +11,5 @@ "github.com/Velocidex/ordereddict" "github.com/stretchr/testify/suite" + actions_proto "www.velocidex.com/golang/velociraptor/actions/proto" api_proto "www.velocidex.com/golang/velociraptor/api/proto" "www.velocidex.com/golang/velociraptor/file_store" @@ -173,8 +174,17 @@ defer utils.SetIdGenerator(gen)() + client_info_manager, err := services.GetClientInfoManager(self.ConfigObj) + assert.NoError(self.T(), err) + for client_number := 0; client_number < 10; client_number++ { gen.SetId(fmt.Sprintf("%s_%v", self.flow_id, client_number)) client_id := fmt.Sprintf("%s_%v", self.client_id, client_number) + err = client_info_manager.Set(self.Ctx, &services.ClientInfo{ + &actions_proto.ClientInfo{ + ClientId: client_id, + }}) + assert.NoError(self.T(), err) + flow_id, err := launcher.ScheduleArtifactCollection(self.Ctx, self.ConfigObj, acl_managers.NullACLManager{}, diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/server/notebooks/export.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/server/notebooks/export.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/server/notebooks/export.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/server/notebooks/export.go 2025-11-01 15:52:20.000000000 +0000 @@ -9,5 +9,4 @@ "fmt" "html" - "io/ioutil" "net/url" "os" @@ -24,4 +23,5 @@ 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/file_store" "www.velocidex.com/golang/velociraptor/file_store/api" @@ -595,5 +595,5 @@ } - data, err := ioutil.ReadAll(fd) + data, err := utils.ReadAllWithLimit(fd, constants.MAX_MEMORY) if err != nil { return "", err @@ -669,5 +669,6 @@ } - data, err := ioutil.ReadAll(fd) + data, err := utils.ReadAllWithLimit(fd, + constants.MAX_MEMORY) if err != nil { continue Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/server/notebooks: list.go diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/server/repository.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/server/repository.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/server/repository.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/server/repository.go 2025-11-01 15:52:20.000000000 +0000 @@ -55,5 +55,4 @@ ValidateArtifact: true, ArtifactIsBuiltIn: false, - Tags: arg.Tags, }) if err != nil { @@ -96,4 +95,20 @@ } + if len(arg.Tags) > 0 { + metadata := definition.Metadata + if metadata == nil { + metadata = &artifacts_proto.ArtifactMetadata{} + } + + metadata.Tags = arg.Tags + + err = manager.SetArtifactMetadata(ctx, config_obj, + principal, definition.Name, metadata) + if err != nil { + scope.Log("artifact_set: %s", err) + return vfilter.Null{} + } + } + return json.ConvertProtoToOrderedDict(definition) } @@ -400,7 +415,8 @@ } - tags, pres := args.GetStrings("tags") + // Override the tags if specified. + _, pres = args.Get("tags") if pres { - metadata.Tags = tags + metadata.Tags = arg.Tags } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/server/splunk.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/server/splunk.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/server/splunk.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/server/splunk.go 2025-11-01 15:52:20.000000000 +0000 @@ -319,6 +319,9 @@ } - if config_obj.Security != nil && - !config_obj.Security.VqlMustUseSecrets { + if config_obj.Security == nil { + return nil + } + + if !config_obj.Security.VqlMustUseSecrets { return nil } @@ -351,12 +354,13 @@ } + // Allow the user to override these fields s.UpdateString("source", &arg.Source) + s.UpdateString("index", &arg.Index) + s.UpdateString("hostname_field", &arg.HostnameField) + s.UpdateString("hostname", &arg.Hostname) arg.URL = s.GetString("url") arg.Token = s.GetString("token") - arg.Index = s.GetString("index") arg.RootCerts = s.GetString("root_ca") - arg.Hostname = s.GetString("hostname") - arg.HostnameField = s.GetString("hostname_field") arg.SkipVerify = s.GetBool("skip_verify") diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/collector/collector_test.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/collector/collector_test.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/collector/collector_test.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/collector/collector_test.go 2025-11-01 15:52:20.000000000 +0000 @@ -299,5 +299,5 @@ Set("root", root_path_spec)) { line := json.MustMarshalString(row) - if strings.Contains(line, "/Subdir/data/hello.txt\"") { + if strings.Contains(line, `/Subdir/data/hello.txt\"`) { found = true } @@ -322,5 +322,5 @@ Set("root", root_path_spec)) { line := json.MustMarshalString(row) - if strings.Contains(line, "/Subdir/data/hello.txt\"") { + if strings.Contains(line, `/Subdir/data/hello.txt\"`) { found = true } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/collector/fixtures/TestCollectionWithUpload.golden /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/collector/fixtures/TestCollectionWithUpload.golden --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/collector/fixtures/TestCollectionWithUpload.golden 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/collector/fixtures/TestCollectionWithUpload.golden 2025-11-01 15:52:20.000000000 +0000 @@ -30,4 +30,5 @@ "Path": "data", "Size": 11, + "UploadId": 0, "StoredSize": 11, "sha256": "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9", @@ -38,10 +39,10 @@ "data", "file.db" - ], - "UploadId": 0 + ] }, "SparseUpload": { "Path": "{\"DelegateAccessor\":\"data\",\"DelegatePath\":\"This is...", "Size": 13, + "UploadId": 0, "StoredSize": 8, "sha256": "d2bc3dd9279837fd268d82ea397b6980dee5ae462464493c80f495786b4025c2", @@ -53,6 +54,5 @@ "C:", "file.sparse.txt" - ], - "UploadId": 0 + ] } } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/collector/fixtures/TestCreateAndImportCollection.golden /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/collector/fixtures/TestCreateAndImportCollection.golden --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/collector/fixtures/TestCreateAndImportCollection.golden 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/collector/fixtures/TestCreateAndImportCollection.golden 2025-11-01 15:52:20.000000000 +0000 @@ -8,5 +8,5 @@ "/clients/server/artifacts/TestArtifact/F.1234.json": [ "", - "{\"Artifact\":\"TestArtifact\",\"Upload\":{\"Path\":\"/Hello\",\"Size\":5,\"StoredSize\":5,\"sha256\":\"185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969\",\"md5\":\"8b1a9953c4611296a827abf8c47804d7\",\"Components\":[\"clients\",\"server\",\"collections\",\"F.1234\",\"uploads\",\"data\",\"Hello\"],\"UploadId\":0}}" + "{\"Artifact\":\"TestArtifact\",\"Upload\":{\"Path\":\"/Hello\",\"Size\":5,\"UploadId\":0,\"StoredSize\":5,\"sha256\":\"185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969\",\"md5\":\"8b1a9953c4611296a827abf8c47804d7\",\"Components\":[\"clients\",\"server\",\"collections\",\"F.1234\",\"uploads\",\"data\",\"Hello\"]}}" ], "/clients/server/artifacts/TestArtifact/F.1234.json.index": "Index 8 bytes", @@ -55,5 +55,5 @@ "/clients/server/artifacts/TestArtifact/F.1234.json": [ "", - "{\"Artifact\":\"TestArtifact\",\"Upload\":{\"Path\":\"/Hello\",\"Size\":5,\"StoredSize\":5,\"sha256\":\"185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969\",\"md5\":\"8b1a9953c4611296a827abf8c47804d7\",\"Components\":[\"clients\",\"server\",\"collections\",\"F.1234\",\"uploads\",\"data\",\"Hello\"],\"UploadId\":0}}" + "{\"Artifact\":\"TestArtifact\",\"Upload\":{\"Path\":\"/Hello\",\"Size\":5,\"UploadId\":0,\"StoredSize\":5,\"sha256\":\"185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969\",\"md5\":\"8b1a9953c4611296a827abf8c47804d7\",\"Components\":[\"clients\",\"server\",\"collections\",\"F.1234\",\"uploads\",\"data\",\"Hello\"]}}" ], "/clients/server/artifacts/TestArtifact/F.1234.json.index": "Index 8 bytes", diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/collector/fixtures/TestCreateAndImportHunt.golden /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/collector/fixtures/TestCreateAndImportHunt.golden --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/collector/fixtures/TestCreateAndImportHunt.golden 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/collector/fixtures/TestCreateAndImportHunt.golden 2025-11-01 15:52:20.000000000 +0000 @@ -8,5 +8,5 @@ "/clients/server/artifacts/TestArtifact/F.1234.json": [ "", - "{\"Artifact\":\"TestArtifact\",\"Upload\":{\"Path\":\"/Hello\",\"Size\":5,\"StoredSize\":5,\"sha256\":\"185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969\",\"md5\":\"8b1a9953c4611296a827abf8c47804d7\",\"Components\":[\"clients\",\"server\",\"collections\",\"F.1234\",\"uploads\",\"data\",\"Hello\"],\"UploadId\":0}}" + "{\"Artifact\":\"TestArtifact\",\"Upload\":{\"Path\":\"/Hello\",\"Size\":5,\"UploadId\":0,\"StoredSize\":5,\"sha256\":\"185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969\",\"md5\":\"8b1a9953c4611296a827abf8c47804d7\",\"Components\":[\"clients\",\"server\",\"collections\",\"F.1234\",\"uploads\",\"data\",\"Hello\"]}}" ], "/clients/server/artifacts/TestArtifact/F.1234.json.index": "Index 8 bytes", @@ -57,5 +57,5 @@ "/clients/server/artifacts/TestArtifact/F.1234.json": [ "", - "{\"Artifact\":\"TestArtifact\",\"Upload\":{\"Path\":\"/Hello\",\"Size\":5,\"StoredSize\":5,\"sha256\":\"185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969\",\"md5\":\"8b1a9953c4611296a827abf8c47804d7\",\"Components\":[\"clients\",\"server\",\"collections\",\"F.1234\",\"uploads\",\"data\",\"Hello\"],\"UploadId\":0}}" + "{\"Artifact\":\"TestArtifact\",\"Upload\":{\"Path\":\"/Hello\",\"Size\":5,\"UploadId\":0,\"StoredSize\":5,\"sha256\":\"185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969\",\"md5\":\"8b1a9953c4611296a827abf8c47804d7\",\"Components\":[\"clients\",\"server\",\"collections\",\"F.1234\",\"uploads\",\"data\",\"Hello\"]}}" ], "/clients/server/artifacts/TestArtifact/F.1234.json.index": "Index 8 bytes", diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/collector/import.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/collector/import.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/collector/import.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/collector/import.go 2025-11-01 15:52:20.000000000 +0000 @@ -8,5 +8,4 @@ "fmt" "io" - "io/ioutil" "os" "strings" @@ -19,4 +18,5 @@ api_proto "www.velocidex.com/golang/velociraptor/api/proto" config_proto "www.velocidex.com/golang/velociraptor/config/proto" + "www.velocidex.com/golang/velociraptor/constants" crypto_proto "www.velocidex.com/golang/velociraptor/crypto/proto" "www.velocidex.com/golang/velociraptor/file_store" @@ -602,6 +602,5 @@ defer fd.Close() - limitedReader := &io.LimitedReader{R: fd, N: BUFF_SIZE} - data, err := ioutil.ReadAll(limitedReader) + data, err := utils.ReadAllWithLimit(fd, constants.MAX_MEMORY) if err != nil && err != io.EOF { return err @@ -689,6 +688,5 @@ defer fd.Close() - limitedReader := &io.LimitedReader{R: fd, N: BUFF_SIZE} - data, err := ioutil.ReadAll(limitedReader) + data, err := utils.ReadAllWithLimit(fd, constants.MAX_MEMORY) if err != nil && err != io.EOF { return nil, err diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/packaging/debian_test.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/packaging/debian_test.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/packaging/debian_test.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/packaging/debian_test.go 2025-11-01 15:52:20.000000000 +0000 @@ -31,5 +31,6 @@ assert.NoError(self.T(), err) - target_config := validateServerConfig(self.ConfigObj) + target_config, err := validateServerConfig(self.ConfigObj) + assert.NoError(self.T(), err) spec.SetRuntimeParameters(target_config, arch, "releaseX", "", 0, self.elf_data) @@ -51,5 +52,6 @@ }} - target_config := validateServerConfig(self.ConfigObj) + target_config, err := validateServerConfig(self.ConfigObj) + assert.NoError(self.T(), err) spec.SetRuntimeParameters(target_config, arch, "releaseX", "master", 0, self.elf_data) @@ -71,5 +73,7 @@ }} - target_config := validateServerConfig(self.ConfigObj) + target_config, err := validateServerConfig(self.ConfigObj) + assert.NoError(self.T(), err) + spec.SetRuntimeParameters(target_config, arch, "releaseX", "minion", 0, self.elf_data) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/packaging/package.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/packaging/package.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/packaging/package.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/packaging/package.go 2025-11-01 15:52:20.000000000 +0000 @@ -3,4 +3,5 @@ import ( "context" + "errors" "fmt" "os" @@ -134,5 +135,13 @@ } if spec.Server { - target_config = validateServerConfig(config_obj) + target_config, err = validateServerConfig(config_obj) + if err != nil { + scope.Log("ERROR:%v: %v", self.name, err) + return + } + + // We force the binary to run as the velociraptor user + target_config.Frontend.RunAsUser = spec.Expansion.ServerUser + } else { target_config, err = validateClientConfig(config_obj, arg.Config) @@ -145,5 +154,12 @@ } else if arg.Server { spec = self.serverSpecFactory() - target_config = validateServerConfig(config_obj) + target_config, err = validateServerConfig(config_obj) + if err != nil { + scope.Log("ERROR:%v: %v", self.name, err) + return + } + + // We force the binary to run as the velociraptor user + target_config.Frontend.RunAsUser = spec.Expansion.ServerUser } else { @@ -282,7 +298,11 @@ } -func validateServerConfig(config_obj *config_proto.Config) *config_proto.Config { +func validateServerConfig(config_obj *config_proto.Config) (*config_proto.Config, error) { res := proto.Clone(config_obj).(*config_proto.Config) - return res + if res.Frontend == nil || res.Client == nil { + return nil, errors.New("Server Config requires a Frontend and Client sections.") + } + + return res, nil } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/packaging/rpm_test.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/packaging/rpm_test.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/packaging/rpm_test.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/packaging/rpm_test.go 2025-11-01 15:52:20.000000000 +0000 @@ -115,5 +115,7 @@ assert.NoError(self.T(), err) - target_config := validateServerConfig(self.ConfigObj) + target_config, err := validateServerConfig(self.ConfigObj) + assert.NoError(self.T(), err) + spec.SetRuntimeParameters( target_config, arch, "releaseX", "server", 0, self.elf_data) @@ -140,5 +142,7 @@ }} - target_config := validateServerConfig(self.ConfigObj) + target_config, err := validateServerConfig(self.ConfigObj) + assert.NoError(self.T(), err) + spec.SetRuntimeParameters( target_config, arch, "releaseX", "master", 0, self.elf_data) @@ -166,5 +170,7 @@ }} - target_config := validateServerConfig(self.ConfigObj) + target_config, err := validateServerConfig(self.ConfigObj) + assert.NoError(self.T(), err) + spec.SetRuntimeParameters( target_config, arch, "releaseX", "minion", 0, self.elf_data) diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/process/api.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/process/api.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/process/api.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/process/api.go 2025-11-01 15:52:20.000000000 +0000 @@ -13,6 +13,8 @@ Stats() cache.Stats Processes(ctx context.Context, scope vfilter.Scope) []*ProcessEntry - Children(ctx context.Context, scope vfilter.Scope, id string) []*ProcessEntry - CallChain(ctx context.Context, scope vfilter.Scope, id string) []*ProcessEntry + Children(ctx context.Context, scope vfilter.Scope, + id string, max_items int64) []*ProcessEntry + CallChain(ctx context.Context, scope vfilter.Scope, + id string, max_items int64) []*ProcessEntry // Listen to the update stream from the tracker. diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/process/callchain.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/process/callchain.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/process/callchain.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/process/callchain.go 2025-11-01 15:52:20.000000000 +0000 @@ -14,5 +14,6 @@ type getChainArgs struct { - Id string `vfilter:"required,field=id,doc=Process ID."` + Id string `vfilter:"required,field=id,doc=Process ID."` + MaxItems int64 `vfilter:"optional,field=max_items,doc=The maximum number of process entries to return (default 10)"` } @@ -36,5 +37,5 @@ } - return tracker.CallChain(ctx, scope, arg.Id) + return tracker.CallChain(ctx, scope, arg.Id, arg.MaxItems) } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/process/children.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/process/children.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/process/children.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/process/children.go 2025-11-01 15:52:20.000000000 +0000 @@ -25,4 +25,8 @@ } + if arg.MaxItems == 0 { + arg.MaxItems = 100 + } + tracker := GetGlobalTracker() if tracker == nil { @@ -31,5 +35,5 @@ } - return tracker.Children(ctx, scope, arg.Id) + return tracker.Children(ctx, scope, arg.Id, arg.MaxItems) } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/process/dummy.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/process/dummy.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/process/dummy.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/process/dummy.go 2025-11-01 15:52:20.000000000 +0000 @@ -105,5 +105,10 @@ func (self *DummyProcessTracker) CallChain( - ctx context.Context, scope vfilter.Scope, id string) []*ProcessEntry { + ctx context.Context, scope vfilter.Scope, + id string, max_items int64) []*ProcessEntry { + + if max_items == 0 { + max_items = 10 + } lookup := self.getLookup(ctx, scope) @@ -118,4 +123,7 @@ result = append(result, proc) + if int64(len(result)) > max_items { + break + } id = proc.ParentId } @@ -125,5 +133,10 @@ func (self *DummyProcessTracker) Children( - ctx context.Context, scope vfilter.Scope, id string) []*ProcessEntry { + ctx context.Context, scope vfilter.Scope, + id string, max_items int64) []*ProcessEntry { + + if max_items == 0 { + max_items = 10 + } result := []*ProcessEntry{} @@ -131,4 +144,7 @@ if proc.ParentId == id { result = append(result, proc) + if int64(len(result)) > max_items { + break + } } } Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/process/fixtures: TestForkBomb.golden diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/process/tracker.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/process/tracker.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/process/tracker.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/process/tracker.go 2025-11-01 15:52:20.000000000 +0000 @@ -226,7 +226,12 @@ // Return all the processes that are children of this id func (self *ProcessTracker) Children( - ctx context.Context, scope vfilter.Scope, id string) []*ProcessEntry { + ctx context.Context, scope vfilter.Scope, + id string, max_items int64) []*ProcessEntry { res := []*ProcessEntry{} + if max_items == 0 { + max_items = 10 + } + self.mu.Lock() defer self.mu.Unlock() @@ -237,4 +242,7 @@ if v.ParentId == id { res = append(res, v) + if int64(len(res)) > max_items { + break + } } } @@ -370,8 +378,13 @@ func (self *ProcessTracker) CallChain( - ctx context.Context, scope vfilter.Scope, id string) []*ProcessEntry { + ctx context.Context, scope vfilter.Scope, + id string, max_items int64) []*ProcessEntry { self.mu.Lock() defer self.mu.Unlock() + if max_items == 0 { + max_items = 10 + } + result := []*ProcessEntry{} for { @@ -384,4 +397,7 @@ proc_copy := *proc result = append(result, &proc_copy) + if int64(len(result)) > max_items { + return reverse(result) + } id = proc.ParentId diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/process/tracker_test.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/process/tracker_test.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/process/tracker_test.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/process/tracker_test.go 2025-11-01 15:52:20.000000000 +0000 @@ -3,4 +3,5 @@ import ( "context" + "fmt" "regexp" "testing" @@ -14,7 +15,10 @@ "www.velocidex.com/golang/velociraptor/services" "www.velocidex.com/golang/velociraptor/utils" + vql_subsystem "www.velocidex.com/golang/velociraptor/vql" "www.velocidex.com/golang/velociraptor/vtesting/assert" "www.velocidex.com/golang/velociraptor/vtesting/goldie" "www.velocidex.com/golang/vfilter" + "www.velocidex.com/golang/vfilter/arg_parser" + "www.velocidex.com/golang/vfilter/types" _ "www.velocidex.com/golang/velociraptor/result_sets/simple" @@ -288,5 +292,133 @@ } +func (self *ProcessTrackerTestSuite) TestForkBomb() { + vql_subsystem.RegisterPlugin(&_MockForkBombUpdate{}) + + query := ` +LET Tracker <= process_tracker( +update_query={ + SELECT * FROM mock_forkbomb(depth=Depth) +}, sync_period=500000, max_size=100000) + +// Wait for the tracker to be updated +LET _ <= mock_update_wait() + +-- Pid 5 should be exited. +LET Tree <= process_tracker_tree(id=1) +LET Serialized <= serialize(item=Tree) +LET JSONTreeSize <= len(list=Serialized) +LET ProcessCount = SELECT count() AS Count + FROM process_tracker_pslist() GROUP BY 1 + +SELECT len(list=split(string=Serialized, sep_string='"name"')) - 1 AS Number, + JSONTreeSize, ProcessCount.Count[0] AS TrackedCount +FROM scope() +` + golden := "" + + for depth := 1; depth < 8; depth++ { + // Just build a standard scope. + builder := services.ScopeBuilder{ + Config: self.ConfigObj, + ACLManager: acl_managers.NullACLManager{}, + Logger: logging.NewPlainLogger(self.ConfigObj, &logging.FrontendComponent), + Env: ordereddict.NewDict(). + Set("Depth", depth), + } + + manager, err := services.GetRepositoryManager(self.ConfigObj) + assert.NoError(self.T(), err) + + scope := manager.BuildScope(builder) + + mvql, err := vfilter.MultiParse(query) + for _, vql := range mvql { + for row := range vql.Eval(self.Ctx, scope) { + golden += json.StringIndent(row) + } + } + scope.Close() + } + + goldie.Assert(self.T(), "TestForkBomb", []byte(golden)) +} + func TestProcessTracker(t *testing.T) { suite.Run(t, &ProcessTrackerTestSuite{}) } + +type _MockForkBombUpdateArgs struct { + Depth int64 `vfilter:"required,field=depth"` +} + +type _MockForkBombUpdate struct{} + +func (self _MockForkBombUpdate) Info( + scope vfilter.Scope, type_map *vfilter.TypeMap) *vfilter.PluginInfo { + return &vfilter.PluginInfo{ + Name: "mock_forkbomb", + } +} + +func (self _MockForkBombUpdate) Call( + ctx context.Context, scope types.Scope, + args *ordereddict.Dict) <-chan types.Row { + + output_chan := make(chan types.Row) + + mu.Lock() + plugin_update_done = false + mu.Unlock() + + go func() { + defer close(output_chan) + + arg := &_MockForkBombUpdateArgs{} + err := arg_parser.ExtractArgsWithContext(ctx, scope, args, arg) + if err != nil { + scope.Log("mock_forkbomb: %s", err.Error()) + return + } + + counter := &utils.Counter{} + fork(int(arg.Depth), counter.Get(), 3, output_chan, counter) + + scope.Log("Fork simulation ended with %v processes", counter.Get()) + + // Signal to the query it may proceed. + mu.Lock() + plugin_update_done = true + mu.Unlock() + + // Wait here until the end of the test. + <-ctx.Done() + }() + + return output_chan +} + +// Emulate the pid creating count children. Each of these children +// will also create count children up to the depth specified. +func fork(depth, pid, count int, output_chan chan types.Row, + counter *utils.Counter) { + + if depth < 0 { + return + } + + for i := 0; i < count; i++ { + counter.Inc() + record := ordereddict.NewDict(). + Set("update_type", "start"). + Set("id", counter.Get()). + Set("parent_id", pid). + Set("start_time", time.Unix(100000000+int64(counter.Get()), 0)). + Set("data", ordereddict.NewDict(). + Set("Pid", counter.Get()). + Set("Ppid", pid). + Set("Name", fmt.Sprintf("Pid%v", counter.Get()))) + output_chan <- record + + fork(depth-1, counter.Get(), count, output_chan, counter) + } +} diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/process/tree.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/process/tree.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/process/tree.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/process/tree.go 2025-11-01 15:52:20.000000000 +0000 @@ -8,4 +8,5 @@ "github.com/Velocidex/ordereddict" vql_subsystem "www.velocidex.com/golang/velociraptor/vql" + "www.velocidex.com/golang/velociraptor/vql/functions" "www.velocidex.com/golang/vfilter" "www.velocidex.com/golang/vfilter/arg_parser" @@ -26,4 +27,5 @@ Id string `vfilter:"optional,field=id,doc=Process ID."` DataCallback *vfilter.Lambda `vfilter:"optional,field=data_callback,doc=A VQL Lambda function to that receives a ProcessEntry and returns the data node for each process."` + MaxItems int64 `vfilter:"optional,field=max_items,doc=The maximum number of process entries to return (default 1000)"` } @@ -41,4 +43,8 @@ } + if arg.MaxItems == 0 { + arg.MaxItems = 1000 + } + tracker := GetGlobalTracker() if tracker == nil { @@ -52,4 +58,5 @@ } + arg.MaxItems-- new_node := &node{ Id: entry.Id, @@ -61,5 +68,6 @@ seen := make(map[string]bool) depth := 0 - getTreeChildren(ctx, scope, new_node, seen, tracker, depth) + getTreeChildren(ctx, scope, new_node, seen, tracker, + depth, &arg.MaxItems) return new_node @@ -79,10 +87,11 @@ func getTreeChildren( ctx context.Context, scope vfilter.Scope, - n *node, seen map[string]bool, tracker IProcessTracker, depth int) { + n *node, seen map[string]bool, tracker IProcessTracker, + depth int, max_items *int64) { if depth > 20 { return } - for _, e := range tracker.Children(ctx, scope, n.Id) { + for _, e := range tracker.Children(ctx, scope, n.Id, *max_items) { _, pres := seen[e.Id] if pres { @@ -95,4 +104,11 @@ e.Data.Update("EndTime", e.EndTime) + *max_items-- + if *max_items < 0 { + functions.DeduplicatedLog(ctx, scope, + "process_tracker_tree: Exceeding number of items in tree output. Truncating output") + return + } + new_node := &node{ Id: e.Id, @@ -102,5 +118,6 @@ } n.Children = append(n.Children, new_node) - getTreeChildren(ctx, scope, new_node, seen, tracker, depth+1) + getTreeChildren(ctx, scope, new_node, seen, tracker, + depth+1, max_items) } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/repack.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/repack.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/repack.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/repack.go 2025-11-01 15:52:20.000000000 +0000 @@ -19,5 +19,4 @@ "encoding/binary" "errors" - "io/ioutil" "os" "regexp" @@ -54,4 +53,6 @@ const ( + // Repacking uses a lot of memory because currently it is all done + // in memory. MAX_MEMORY = 200 * 1024 * 1024 OLE_PAGESIZE = 0x1000 @@ -250,5 +251,5 @@ defer fd.Close() - return ioutil.ReadAll(fd) + return utils.ReadAllWithLimit(fd, MAX_MEMORY) } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/repack_test.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/repack_test.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/repack_test.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/repack_test.go 2025-11-01 15:52:20.000000000 +0000 @@ -115,15 +115,17 @@ Set("upload_name", "test.zip")) - upload_response, ok := result.(*uploads.UploadResponse) + upload_response, ok := result.(*ordereddict.Dict) assert.True(self.T(), ok, "Result type is %T", result) + upload_response_path, _ := upload_response.GetString("Path") + // Save a copy of the repacked data for inspection. if repacked_dst != "" { - utils.CopyFile(ctx, upload_response.Path, repacked_dst, 0644) + utils.CopyFile(ctx, upload_response_path, repacked_dst, 0644) scope.Log("Stored repacked binary in %v for manual inspection", repacked_dst) } // Check the content of the packed binaries. - fd, err := os.Open(upload_response.Path) + fd, err := os.Open(upload_response_path) assert.NoError(self.T(), err) s, err := fd.Stat() @@ -228,9 +230,11 @@ Set("upload_name", "test.zip")) - upload_response, ok := result.(*uploads.UploadResponse) + upload_response, ok := result.(*ordereddict.Dict) assert.True(self.T(), ok, "Result type is %T", result) + upload_response_path, _ := upload_response.GetString("Path") + // Now extract the config from the result. - config_obj, err := config.ExtractEmbeddedConfig(upload_response.Path) + config_obj, err := config.ExtractEmbeddedConfig(upload_response_path) assert.NoError(self.T(), err) @@ -244,10 +248,10 @@ // Save a copy of the repacked data for inspection. if repacked_dst != "" { - utils.CopyFile(ctx, upload_response.Path, repacked_dst, 0644) + utils.CopyFile(ctx, upload_response_path, repacked_dst, 0644) scope.Log("Stored repacked binary in %v for manual inspection", repacked_dst) } // Check the content of the packed binaries. - fd, err = os.Open(upload_response.Path) + fd, err = os.Open(upload_response_path) assert.NoError(self.T(), err) s, err := fd.Stat() @@ -338,10 +342,12 @@ Set("upload_name", "test.zip")) - upload_response, ok := result.(*uploads.UploadResponse) + upload_response, ok := result.(*ordereddict.Dict) assert.True(self.T(), ok, "Result type is %T", result) + upload_response_path, _ := upload_response.GetString("Path") + // Save a copy of the repacked data for inspection. if repacked_dst != "" { - utils.CopyFile(ctx, upload_response.Path, repacked_msi_dst, 0644) + utils.CopyFile(ctx, upload_response_path, repacked_msi_dst, 0644) scope.Log("Stored repacked msi in %v for manual inspection", repacked_msi_dst) } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/s3_upload.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/s3_upload.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/tools/s3_upload.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/tools/s3_upload.go 2025-11-01 15:52:20.000000000 +0000 @@ -257,6 +257,9 @@ } - if config_obj.Security != nil && - !config_obj.Security.VqlMustUseSecrets { + if config_obj.Security == nil { + return nil + } + + if !config_obj.Security.VqlMustUseSecrets { return nil } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/vql.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/vql.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/vql.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/vql.go 2025-11-01 15:52:20.000000000 +0000 @@ -50,19 +50,28 @@ // Used when we deliberately want to override a registered plugin. func OverridePlugin(plugin vfilter.PluginGeneratorInterface) { + mu.Lock() + defer mu.Unlock() + name := plugin.Info(nil, nil).Name exportedPlugins[name] = plugin - ResetGlobalScopeCache() + resetGlobalScopeCache() } // Used when we deliberately want to override a registered function. func OverrideFunction(function vfilter.FunctionInterface) { + mu.Lock() + defer mu.Unlock() + name := function.Info(nil, nil).Name exportedFunctions[name] = function - ResetGlobalScopeCache() + resetGlobalScopeCache() } func RegisterPlugin(plugin vfilter.PluginGeneratorInterface) { + mu.Lock() + defer mu.Unlock() + name := plugin.Info(nil, nil).Name _, pres := exportedPlugins[name] @@ -73,8 +82,11 @@ exportedPlugins[name] = plugin - ResetGlobalScopeCache() + resetGlobalScopeCache() } func RegisterFunction(plugin vfilter.FunctionInterface) { + mu.Lock() + defer mu.Unlock() + name := plugin.Info(nil, nil).Name _, pres := exportedFunctions[name] @@ -85,11 +97,14 @@ exportedFunctions[name] = plugin - ResetGlobalScopeCache() + resetGlobalScopeCache() } func RegisterProtocol(plugin vfilter.Any) { + mu.Lock() + defer mu.Unlock() + exportedProtocolImpl = append(exportedProtocolImpl, plugin) - ResetGlobalScopeCache() + resetGlobalScopeCache() } @@ -150,5 +165,5 @@ // Reset the global scope so we will be forced to recreate it. - globalScope = nil + resetGlobalScopeCache() return nil @@ -163,10 +178,14 @@ ) -func _makeRootScope() vfilter.Scope { +func MakeScope() vfilter.Scope { mu.Lock() defer mu.Unlock() + return _makeRootScope() +} + +func _makeRootScope() vfilter.Scope { if globalScope == nil { - globalScope = MakeNewScope() + globalScope = _MakeNewScope() } @@ -174,8 +193,4 @@ } -func MakeScope() vfilter.Scope { - return _makeRootScope() -} - func GetRootScope(scope vfilter.Scope) vfilter.Scope { root_any, pres := scope.Resolve(constants.SCOPE_ROOT) @@ -192,4 +207,11 @@ // this! use MakeScope() above which is much faster. func MakeNewScope() vfilter.Scope { + mu.Lock() + defer mu.Unlock() + + return _MakeNewScope() +} + +func _MakeNewScope() vfilter.Scope { scopeCounter.Inc() @@ -215,4 +237,9 @@ mu.Lock() defer mu.Unlock() + + globalScope = nil +} + +func resetGlobalScopeCache() { globalScope = nil } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/windows/crypto.c /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/windows/crypto.c --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/windows/crypto.c 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/windows/crypto.c 2025-11-01 15:52:20.000000000 +0000 @@ -6,4 +6,5 @@ #include +#include #include #include @@ -33,11 +34,14 @@ HCERTSTORE hCertStore = CertOpenSystemStoreW(0, store_name); if (hCertStore == NULL) { - printf("Failed to open cert store %S with %d\n", systemStore, GetLastError()); + printf("Failed to open cert store %S with %ld\n", + (wchar_t *)systemStore, (uint32_t)GetLastError()); return FALSE; } - while(pCertContext=CertEnumCertificatesInStore( - hCertStore, - pCertContext)) { + while(1) { + pCertContext=CertEnumCertificatesInStore(hCertStore, pCertContext); + if (pCertContext == NULL) { + break; + } // Just pass the certificate to Go - we will deal with it Only in /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/windows/process: kernel_info_manager.go diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/windows/process/thread.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/windows/process/thread.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/windows/process/thread.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/windows/process/thread.go 2025-11-01 15:52:20.000000000 +0000 @@ -1,4 +1,4 @@ -//go:build windows && amd64 -// +build windows,amd64 +//go:build windows && amd64 && cgo +// +build windows,amd64,cgo package process @@ -8,4 +8,5 @@ "errors" "fmt" + "path/filepath" "syscall" "unsafe" @@ -14,4 +15,5 @@ "golang.org/x/sys/windows" "www.velocidex.com/golang/velociraptor/acls" + "www.velocidex.com/golang/velociraptor/utils" vql_subsystem "www.velocidex.com/golang/velociraptor/vql" vwindows "www.velocidex.com/golang/velociraptor/vql/windows" @@ -136,4 +138,17 @@ return nil, fmt.Errorf("NtQueryInformationProcess failed, %X", status) } + length = 0 + + user_times := vwindows.KERNEL_USER_TIMES{} + status, _ = vwindows.NtQueryInformationThread( + syscall.Handle(thread), + vwindows.ThreadTimes, + (*byte)(unsafe.Pointer(&user_times)), + uint32(unsafe.Sizeof(user_times)), + &length) + if status != vwindows.STATUS_SUCCESS || length == 0 { + scope.Log("NtQueryInformationProcess failed (ThreadTimes) for pid %v, %X", + pid, status) + } var thread_start_address uint64 @@ -178,4 +193,16 @@ } + kim := GetKernelInfoManager(scope) + rva := int64(thread_start_address - memory_basic_info.AllocationBase) + module_path := kim.NormalizeFilename(filename) + module_file_name := filepath.Base(module_path) + + func_name := kim.GuessFunctionName(module_path, rva) + if func_name != "" { + func_name = fmt.Sprintf("%v!%v", module_file_name, func_name) + } else { + func_name = fmt.Sprintf("%v!%#x", module_file_name, rva) + } + ret := ordereddict.NewDict(). Set("pid", pid). @@ -183,6 +210,12 @@ Set("thread_info", thread_info). Set("thread_start_address", thread_start_address). + Set("thread_start_address_name", func_name). Set("memory_basic_info", memory_basic_info). - Set("filename", filename) + Set("times", ordereddict.NewDict(). + Set("CreateTime", utils.WinFileTime(int64(user_times.CreateTime))). + Set("ExitTime", utils.WinFileTime(int64(user_times.ExitTime))). + Set("KernelTime", user_times.KernelTime). + Set("UserTime", user_times.UserTime)). + Set("filename", module_path) return ret, nil diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/windows/win32_windows.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/windows/win32_windows.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/windows/win32_windows.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/windows/win32_windows.go 2025-11-01 15:52:20.000000000 +0000 @@ -190,4 +190,5 @@ // NtQueryInformationThread ThreadBasicInformation = 0 + ThreadTimes = 1 ThreadImpersonationToken = 5 @@ -257,4 +258,11 @@ } +type KERNEL_USER_TIMES struct { + CreateTime uint64 // The creation time of the process or thread. + ExitTime uint64 // The exit time of the process or thread. + KernelTime uint64 // The amount of time the process has executed in kernel mode. + UserTime uint64 +} + type OBJECT_TYPE_INFORMATION struct { TypeName UNICODE_STRING diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/windows/wmi/events.c /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/windows/wmi/events.c --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql/windows/wmi/events.c 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql/windows/wmi/events.c 2025-11-01 15:52:20.000000000 +0000 @@ -6,4 +6,5 @@ #define _WIN32_DCOM +#include #include #include @@ -323,5 +324,5 @@ // what it means. char buf[512]; - snprintf(buf, 512, "%s: Error code %#x", function, hres); + snprintf(buf, 512, "%s: Error code %#lx", function, (uint32_t)hres); log_error(go_ctx, buf); } diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql_plugins/accessors.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql_plugins/accessors.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql_plugins/accessors.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql_plugins/accessors.go 2025-11-01 15:52:20.000000000 +0000 @@ -13,4 +13,5 @@ _ "www.velocidex.com/golang/velociraptor/accessors/ntfs" _ "www.velocidex.com/golang/velociraptor/accessors/offset" + _ "www.velocidex.com/golang/velociraptor/accessors/overlay" _ "www.velocidex.com/golang/velociraptor/accessors/pipe" _ "www.velocidex.com/golang/velociraptor/accessors/process" diff -U2 -r /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql_plugins/plugins.go /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql_plugins/plugins.go --- /var/lib/copr-rpmbuild/results/velociraptor/upstream-unpacked/Source0/velociraptor-0.75/vql_plugins/plugins.go 2025-08-25 01:52:19.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/velociraptor/srpm-unpacked/velociraptor-0.75.tar.gz-extract/velociraptor-0.75/vql_plugins/plugins.go 2025-11-01 15:52:20.000000000 +0000 @@ -25,4 +25,5 @@ _ "www.velocidex.com/golang/velociraptor/vql/aggregates" _ "www.velocidex.com/golang/velociraptor/vql/common" + _ "www.velocidex.com/golang/velociraptor/vql/debug" _ "www.velocidex.com/golang/velociraptor/vql/efi" _ "www.velocidex.com/golang/velociraptor/vql/filesystem"