VYPR
Moderate severityNVD Advisory· Published Jun 20, 2025· Updated Nov 28, 2025

Velociraptor priviledge escalation via UpdateConfig artifact

CVE-2025-6264

Description

Velociraptor allows collection of VQL queries packaged into Artifacts from endpoints. These artifacts can be used to do anything and usually run with elevated permissions.  To limit access to some dangerous artifact, Velociraptor allows for those to require high permissions like EXECVE to launch.

The Admin.Client.UpdateClientConfig is an artifact used to update the client's configuration. This artifact did not enforce an additional required permission, allowing users with COLLECT_CLIENT permissions (normally given by the "Investigator" role) to collect it from endpoints and update the configuration.

This can lead to arbitrary command execution and endpoint takeover.

To successfully exploit this vulnerability the user must already have access to collect artifacts from the endpoint (i.e. have the COLLECT_CLIENT given typically by the "Investigator' role).

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
www.velocidex.com/golang/velociraptorGo
< 0.74.30.74.3

Affected products

1

Patches

1
21e7fd7138dd

Implemented static analysis for client side permissions (#4246)

https://github.com/Velocidex/velociraptorMike CohenMay 20, 2025via ghsa
46 files changed · +646 360
  • accessors/pst/cache.go+2 2 modified
    @@ -1,5 +1,5 @@
    -//go:build !linux && !386
    -// +build !linux,!386
    +//go:build !386
    +// +build !386
     
     package pst
     
    
  • accessors/pst/pst_accessor.go+2 2 modified
    @@ -1,5 +1,5 @@
    -//go:build !linux && !386
    -// +build !linux,!386
    +//go:build !386
    +// +build !386
     
     package pst
     
    
  • artifacts/definitions/Admin/Client/UpdateClientConfig.yaml+4 0 modified
    @@ -25,6 +25,10 @@ parameters:
          default: Y
          description: Should the client rekey its client ID.
     
    +required_permissions:
    +  - EXECVE
    +  - FILESYSTEM_WRITE
    +
     sources:
       - query: |
     
    
  • artifacts/definitions/Admin/Client/Upgrade/Debian.yaml+4 0 modified
    @@ -24,6 +24,10 @@ parameters:
         description: |
           The name of the service to restart after the upgrade.
     
    +implied_permissions:
    +  - EXECVE
    +  - FILESYSTEM_WRITE
    +
     sources:
       - precondition:
           SELECT OS From info() where OS =~ 'linux'
    
  • artifacts/definitions/Admin/Client/Upgrade/RedHat.yaml+3 0 modified
    @@ -24,6 +24,9 @@ parameters:
         description: |
           The name of the service to restart after the upgrade.
     
    +implied_permissions:
    +  - EXECVE
    +
     sources:
       - precondition:
           SELECT OS From info() where OS =~ 'linux'
    
  • artifacts/definitions/Admin/Client/Upgrade/Windows.yaml+4 0 modified
    @@ -22,6 +22,10 @@ parameters:
           overwhelm the server so we stagger the download over this many
           seconds.
     
    +implied_permissions:
    +  - EXECVE
    +  - FILESYSTEM_WRITE
    +
     sources:
       - precondition:
           SELECT OS From info() where OS = 'windows'
    
  • artifacts/definitions/Generic/Client/CleanupTemp.yaml+2 0 modified
    @@ -13,6 +13,8 @@ parameters:
       - name: ReadllyDoIt
         type: bool
     
    +required_permissions:
    +  - FILESYSTEM_WRITE
     
     sources:
       - query: |
    
  • artifacts/definitions/Generic/Client/DiskSpace.yaml+3 0 modified
    @@ -6,6 +6,9 @@ description: |
         1. On Linux and MacOS we call `df -h`.
         2. On Windows we use WMI
     
    +implied_permissions:
    +  - EXECVE
    +
     sources:
     - query: |
         LET NonWindows = SELECT * FROM foreach(row={
    
  • artifacts/definitions/Generic/Client/VQL.yaml+1 1 modified
    @@ -3,7 +3,7 @@ description: |
       Run arbitrary VQL on the endpoint.
     
     required_permissions:
    -  - EXECVE
    +  - IMPERSONATION
     
     parameters:
       - name: Command
    
  • artifacts/definitions/Generic/Forensic/LocalHashes/Init.yaml+3 0 modified
    @@ -8,6 +8,9 @@ parameters:
         description: Name of the local hash database
         default: hashdb.sqlite
     
    +implied_permissions:
    +  - FILESYSTEM_WRITE
    +
     sources:
       - query: |
           LET SQL = "
    
  • artifacts/definitions/Generic/Utils/FetchBinary.yaml+4 0 modified
    @@ -42,6 +42,10 @@ parameters:
       - name: Version
         description: The version of the tool to fetch
     
    +implied_permissions:
    +  - SERVER_ADMIN
    +  - FILESYSTEM_WRITE
    +
     sources:
       - query: |
           -- The following VQL is particularly ancient because it is
    
  • artifacts/definitions/Linux/Network/PacketCapture.yaml+6 3 modified
    @@ -6,26 +6,29 @@ description: |
       The `Duration` parameter is used to define how long (in seconds) the capture should be.  Specific interfaces can be defined using the `Interface` parameter, otherwise the artifact defaults to an interface assignment of `any`.
     
       A `BPF` (Berkeley Packet Filter) expression can also be supplied to filter the captured traffic as desired.
    -  
    +
       Read more about BPF expressions here: https://biot.com/capstats/bpf.html
     
     required_permissions:
       - EXECVE
     
    +implied_permissions:
    +  - FILESYSTEM_WRITE
    +
     parameters:
       - name: Duration
         type: integer
         description: Duration (in seconds) of PCAP to be recorded.
         default: 10
    -  
    +
       - name: Interface
         type: string
         default: any
     
       - name: BPF
         type: string
         default:
    -    
    +
     precondition:
       SELECT * FROM info() where OS = 'linux'
     
    
  • artifacts/definitions/Linux/RHEL/Packages.yaml+4 0 modified
    @@ -1,6 +1,10 @@
     name: Linux.RHEL.Packages
     description: |
       Parse packages installed from dnf or yum
    +
    +implied_permissions:
    +  - EXECVE
    +
     sources:
       - precondition: |
           SELECT OS From info() where OS = 'linux'
    
  • artifacts/definitions/Linux/SuSE/Packages.yaml+5 2 modified
    @@ -3,6 +3,9 @@ author: Hilko Bengen <bengen@hilluzination.de>
     description: |
       Parse list of installed packages from zypper output
     
    +implied_permissions:
    +  - EXECVE
    +
     sources:
       - precondition: |
           SELECT OS From info() WHERE OS = 'linux'
    @@ -12,11 +15,11 @@ sources:
             FROM execve(
               length=1000000,
               argv=["zypper", "--xmlout", "search", "--installed-only", "--details", "--type=package"])
    -      
    +
           LET xml = parse_xml(
               file=str(str=zypper_output.Stdout),
               accessor="data")
    -      
    +
           SELECT *
           FROM foreach(
             row=xml.stream.`search-result`.`solvable-list`.solvable,
    
  • artifacts/definitions/Linux/Sys/Services.yaml+6 5 modified
    @@ -1,16 +1,17 @@
     name: Linux.Sys.Services
    -description: Parse services from systemctl 
    +description: Parse services from systemctl
    +
    +implied_permissions:
    +  - EXECVE
     
     sources:
       - precondition: |
           SELECT OS From info() where OS = 'linux'
         queries:
           - |
             LET services = SELECT Stdout FROM execve(argv=['systemctl', 'list-units',  '--type=service'])
    -        
    +
             LET all_services = SELECT grok(grok="%{NOTSPACE:Unit}%{SPACE}%{NOTSPACE:Load}%{SPACE}%{NOTSPACE:Active}%{SPACE}%{NOTSPACE:Sub}%{SPACE}%{GREEDYDATA:Description}", data=Line) AS Parsed
             FROM parse_lines(accessor="data", filename=services.Stdout)
    -        
    +
             SELECT * FROM foreach(row=all_services, column="Parsed") WHERE Unit =~ ".service"
    -        
    -        
    \ No newline at end of file
    
  • artifacts/definitions/Linux/Users/RootUsers.yaml+3 0 modified
    @@ -7,6 +7,9 @@ author: George-Andrei Iosif (@iosifache)
     
     type: CLIENT
     
    +implied_permissions:
    +  - EXECVE
    +
     sources:
       - precondition: |
           SELECT OS
    
  • artifacts/definitions/Linux/Utils/InstallDeb.yaml+1 0 modified
    @@ -31,6 +31,7 @@ type: CLIENT
     
     required_permissions:
        - EXECVE
    +   - FILESYSTEM_WRITE
     
     reference:
        - https://manpages.debian.org/bookworm/debconf-doc/debconf-devel.7.en.html#Type
    
  • artifacts/definitions/MacOS/Network/PacketCapture.yaml+6 3 modified
    @@ -6,26 +6,29 @@ description: |
       The `Duration` parameter is used to define how long (in seconds) the capture should be.  Specific interfaces can be defined using the `Interface` parameter, otherwise the artifact defaults to an interface assignment of `any`.
     
       A `BPF` (Berkeley Packet Filter) expression can also be supplied to filter the captured traffic as desired.
    -  
    +
       Read more about BPF expressions here: https://biot.com/capstats/bpf.html
     
     required_permissions:
       - EXECVE
     
    +implied_permissions:
    +  - FILESYSTEM_WRITE
    +
     parameters:
       - name: Duration
         type: integer
         description: Duration (in seconds) of PCAP to be recorded.
         default: 10
    -  
    +
       - name: Interface
         type: string
         default: any
     
       - name: BPF
         type: string
         default:
    -    
    +
     precondition:
       SELECT * FROM info() where OS = 'darwin'
     
    
  • artifacts/definitions/MacOS/System/Packages.yaml+9 4 modified
    @@ -1,24 +1,29 @@
     name: MacOS.System.Packages
     description: |
       Parse packages installed on Macs
    +
     parameters:
       - name: Length
         description: Size (in bytes) of output that will be returned
         type: int
         default: "100000000"
    +
    +implied_permissions:
    +  - EXECVE
    +
     sources:
       - precondition: |
           SELECT OS From info() where OS = 'darwin'
         query: |
    -        LET packages = SELECT parse_json(data=Stdout) AS Json 
    +        LET packages = SELECT parse_json(data=Stdout) AS Json
               FROM execve(argv=[
                 "system_profiler", "-json", "SPApplicationsDataType"
               ], length=Length)
     
             SELECT  _name AS Name,
    -                get(field="version") AS Version, 
    -                path AS Path, 
    -                lastModified AS LastModified, 
    +                get(field="version") AS Version,
    +                path AS Path,
    +                lastModified AS LastModified,
                     obtained_from AS ObtainedFrom,
                     get(field="signed_by") AS SignedBy,
                     arch_kind AS _Architecture
    
  • artifacts/definitions/Windows/ActiveDirectory/BloodHound.yaml+3 0 modified
    @@ -23,6 +23,9 @@ reference:
     required_permissions:
       - EXECVE
     
    +implied_permissions:
    +  - FILESYSTEM_WRITE
    +
     tools:
       - name: SharpHound
         url: https://github.com/BloodHoundAD/BloodHound/raw/master/Collectors/SharpHound.exe
    
  • artifacts/definitions/Windows/Applications/NirsoftBrowserViewer.yaml+4 0 modified
    @@ -38,6 +38,10 @@ parameters:
          default: LOCAL
          description: Default timezone for parsing timestamps
     
    +implied_permissions:
    +  - EXECVE
    +  - FILESYSTEM_WRITE
    +
     sources:
       - precondition:
           SELECT OS From info() where OS = 'windows'
    
  • artifacts/definitions/Windows/Applications/SBECmd.yaml+4 0 modified
    @@ -34,6 +34,10 @@ tools:
     
     precondition: SELECT OS From info() where OS = 'windows'
     
    +implied_permissions:
    +  - EXECVE
    +  - FILESYSTEM_WRITE
    +
     parameters:
       - name: userRegex
         default: .
    
  • artifacts/definitions/Windows/Forensics/BulkExtractor.yaml+3 0 modified
    @@ -45,6 +45,9 @@ author: Matt Green - @mgreen27
     required_permissions:
       - EXECVE
     
    +implied_permissions:
    +  - FILESYSTEM_WRITE
    +
     tools:
       - name: Bulk_Extractor_Binary
         url: https://github.com/Velocidex/Tools/raw/main/BulkExtractor/bulk_extractor.exe
    
  • artifacts/definitions/Windows/Memory/Acquisition.yaml+3 0 modified
    @@ -20,6 +20,9 @@ description: |
       go-winpmem.exe expand image.compressed image.raw
       ```
     
    +implied_permissions:
    +  - FILESYSTEM_WRITE
    +
     precondition: |
       SELECT OS FROM info()
       WHERE OS = 'windows'
    
  • artifacts/definitions/Windows/Network/PacketCapture.yaml+4 0 modified
    @@ -15,6 +15,10 @@ tools:
         - name: etl2pcapng
           url: https://github.com/microsoft/etl2pcapng/releases/download/v1.4.0/etl2pcapng.zip
     
    +implied_permissions:
    +  - FILESYSTEM_WRITE
    +  - EXECVE
    +
     parameters:
         - name: StartTrace
           type: bool
    
  • artifacts/definitions/Windows/Remediation/Sinkhole.yaml+3 0 modified
    @@ -20,6 +20,9 @@ author: Matt Green - @mgreen27
     required_permissions:
       - EXECVE
     
    +implied_permissions:
    +  - FILESYSTEM_WRITE
    +
     type: CLIENT
     
     parameters:
    
  • artifacts/definitions/Windows/Sys/Interfaces.yaml+3 0 modified
    @@ -3,6 +3,9 @@ description: |
       Report information about the systems interfaces. This artifact
       simply parses the output from ipconfig /all.
     
    +implied_permissions:
    +  - EXECVE
    +
     sources:
      - precondition:
          SELECT OS from info() where OS = "windows"
    
  • artifacts/definitions/Windows/Sysinternals/Autoruns.yaml+3 0 modified
    @@ -15,6 +15,9 @@ tools:
     
     precondition: SELECT OS From info() where OS = 'windows'
     
    +implied_permissions:
    +  - EXECVE
    +
     parameters:
       - name: All
         type: bool
    
  • artifacts/definitions/Windows/System/AuditPolicy.yaml+6 3 modified
    @@ -1,24 +1,27 @@
     name: Windows.System.AuditPolicy
     
     description: |
    -   Artifact using auditpol to retrieve the logging settings 
    +   Artifact using auditpol to retrieve the logging settings
        defined in the Windows Audit Policy.
    -   
    +
        Use this artifact to determine what Windows event logs are audited
        and if there are any discrepancies across the environment.
     
     type: CLIENT
     
     author: Zach Stanford - @svch0st
     
    +implied_permissions:
    +  - EXECVE
    +
     sources:
       - precondition:
           SELECT OS From info() where OS = 'windows'
     
         query: |
           LET output = SELECT * FROM execve(
             argv=["auditpol.exe","/get","/category:*","/r"])
    -      
    +
           SELECT * FROM foreach(
             row=output,
             query={
    
  • artifacts/definitions/Windows/System/VBScript.yaml+16 13 modified
    @@ -2,30 +2,33 @@ name: Windows.System.VBScript
     author: Matt Green - @mgreen27
     description: |
       This artifact allows running VBScript through cscript.exe.
    -  
    -  This is a very powerful artifact since it allows for arbitrary command execution 
    -  on the endpoints as SYSTEM. Therefore this artifact requires elevated permissions 
    -  (specifically the EXECVE permission). Typically it is only available with the 
    +
    +  This is a very powerful artifact since it allows for arbitrary command execution
    +  on the endpoints as SYSTEM. Therefore this artifact requires elevated permissions
    +  (specifically the EXECVE permission). Typically it is only available with the
       administrator role.
    -  
    -  Note: Output is formatted to 1 row per line of Stdout. Ensure appropriately 
    -  formatted scripts. Pasting scripts direct from word or webpages may lead to 
    -  formatting issues when unicode characters are substituted. Copy script into 
    +
    +  Note: Output is formatted to 1 row per line of Stdout. Ensure appropriately
    +  formatted scripts. Pasting scripts direct from word or webpages may lead to
    +  formatting issues when unicode characters are substituted. Copy script into
       a notepad, save as ASCII then try again.
    -  
    +
     required_permissions:
       - EXECVE
     
    +implied_permissions:
    +  - FILESYSTEM_WRITE
    +
     precondition:
       SELECT OS From info() where OS = 'windows'
     
     parameters:
       - name: Script
         default: Wscript.Echo "Hello world!"
    -       
    +
     sources:
       - query: |
           LET temp_script <= tempfile(extension='.vbs', data=str(str=Script))
    - 
    -      SELECT Stdout 
    -      FROM execve(argv=['cscript.exe','//NoLogo','/E:vbs',temp_script], sep='\n')
    \ No newline at end of file
    +
    +      SELECT Stdout
    +      FROM execve(argv=['cscript.exe','//NoLogo','/E:vbs',temp_script], sep='\n')
    
  • artifacts/proto/artifact.pb.go+200 169 modified
    @@ -515,6 +515,27 @@ type Artifact struct {
     	Reference           []string `protobuf:"bytes,5,rep,name=reference,proto3" json:"reference,omitempty"`
     	References          []string `protobuf:"bytes,23,rep,name=references,proto3" json:"references,omitempty"`
     	RequiredPermissions []string `protobuf:"bytes,13,rep,name=required_permissions,json=requiredPermissions,proto3" json:"required_permissions,omitempty"`
    +	// A list of permissions implied by this artifact. This is used by
    +	// the artifact writer to declare what additional permissions the
    +	// artifact provides over the permissions provided by the user.
    +	//
    +	// On the client, artifacts do not run with ACL enforced,
    +	// therefore they can do anything, including actions which the
    +	// user launching the artifact does not have. For example, the
    +	// user may have the investigator role which does not have
    +	// EXECVE. However, when launching this artifact on the client,
    +	// the artifact will be able to run actions requiring the EXEVE
    +	// permission (because there is no ACL enforcement on the client).
    +	//
    +	// Therefore we say this artifact implies the user has EXECVE -
    +	// this is safe if the aritfact takes steps to ensure the user
    +	// does not have arbitrary control over what to execute (for
    +	// example, if the artifact launches a tool with restricted
    +	// command line args).
    +	//
    +	// This field is only used to ensure the static analysis engine
    +	// that the implied permission is properly controlled.
    +	ImpliedPermissions []string `protobuf:"bytes,28,rep,name=implied_permissions,json=impliedPermissions,proto3" json:"implied_permissions,omitempty"`
     	// If this is specified, we run this artifact as the named user,
     	// with that user's ACL token. This is similar to the Unix suid
     	// mechanism or the Windows impersonation mechanism in that it
    @@ -640,6 +661,13 @@ func (x *Artifact) GetRequiredPermissions() []string {
     	return nil
     }
     
    +func (x *Artifact) GetImpliedPermissions() []string {
    +	if x != nil {
    +		return x.ImpliedPermissions
    +	}
    +	return nil
    +}
    +
     func (x *Artifact) GetImpersonate() string {
     	if x != nil {
     		return x.Impersonate
    @@ -1427,7 +1455,7 @@ var file_artifact_proto_rawDesc = []byte{
     	0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x74, 0x79,
     	0x70, 0x65, 0x73, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, 0x64, 0x65,
     	0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65,
    -	0x78, 0x74, 0x2e, 0x22, 0x94, 0x0f, 0x0a, 0x08, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74,
    +	0x78, 0x74, 0x2e, 0x22, 0xc5, 0x0f, 0x0a, 0x08, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74,
     	0x12, 0xb1, 0x01, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42,
     	0x9c, 0x01, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x95, 0x01, 0x12, 0x92, 0x01, 0x54, 0x68, 0x65, 0x20,
     	0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, 0x74, 0x69,
    @@ -1465,174 +1493,177 @@ var file_artifact_proto_rawDesc = []byte{
     	0x65, 0x64, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74,
     	0x6f, 0x20, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x61,
     	0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x2e, 0x52, 0x13, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72,
    -	0x65, 0x64, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x20, 0x0a,
    -	0x0b, 0x69, 0x6d, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x65, 0x18, 0x1b, 0x20, 0x01,
    -	0x28, 0x09, 0x52, 0x0b, 0x69, 0x6d, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x65, 0x12,
    -	0x2e, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x13, 0x20, 0x01,
    -	0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75,
    -	0x72, 0x63, 0x65, 0x73, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12,
    -	0x21, 0x0a, 0x05, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b,
    -	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x6f, 0x6f, 0x6c, 0x52, 0x05, 0x74, 0x6f, 0x6f,
    -	0x6c, 0x73, 0x12, 0x68, 0x0a, 0x0c, 0x70, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69,
    -	0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x42, 0x44, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x3e,
    -	0x12, 0x3c, 0x41, 0x20, 0x56, 0x51, 0x4c, 0x20, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69,
    -	0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74,
    -	0x65, 0x64, 0x20, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x75, 0x73, 0x69, 0x6e,
    -	0x67, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x0c,
    -	0x70, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x6c, 0x0a, 0x0a,
    -	0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 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, 0x32, 0xe2, 0xfc, 0xe3, 0xc4,
    -	0x01, 0x2c, 0x12, 0x2a, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x20, 0x74,
    -	0x6f, 0x20, 0x62, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x74, 0x6f,
    -	0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x2e, 0x52, 0x0a,
    -	0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x6e, 0x0a, 0x04, 0x74, 0x79,
    -	0x70, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x42, 0x5a, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x54,
    -	0x12, 0x52, 0x54, 0x68, 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68,
    -	0x65, 0x20, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x20, 0x43, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20,
    -	0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x2c, 0x20, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x45,
    -	0x56, 0x45, 0x4e, 0x54, 0x2c, 0x20, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x2c, 0x20, 0x53, 0x45,
    -	0x52, 0x56, 0x45, 0x52, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x2c, 0x20, 0x49, 0x4e, 0x54, 0x45,
    -	0x52, 0x4e, 0x41, 0x4c, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x5a, 0x0a, 0x07, 0x73, 0x6f,
    -	0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72,
    -	0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x6f, 0x75, 0x72,
    -	0x63, 0x65, 0x42, 0x29, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x23, 0x12, 0x21, 0x57, 0x68, 0x65, 0x72,
    -	0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x20, 0x67,
    -	0x65, 0x74, 0x73, 0x20, 0x69, 0x74, 0x73, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x07, 0x73,
    -	0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x6a, 0x0a, 0x07, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74,
    -	0x73, 0x18, 0x11, 0x20, 0x03, 0x28, 0x09, 0x42, 0x50, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x4a, 0x12,
    -	0x48, 0x41, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72,
    -	0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x27, 0x20, 0x65, 0x78, 0x70, 0x6f,
    -	0x72, 0x74, 0x20, 0x56, 0x51, 0x4c, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x72, 0x65, 0x6c, 0x6f, 0x61,
    -	0x64, 0x20, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20,
    -	0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x2e, 0x52, 0x07, 0x69, 0x6d, 0x70, 0x6f, 0x72,
    -	0x74, 0x73, 0x12, 0x7b, 0x0a, 0x06, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x12, 0x20, 0x01,
    -	0x28, 0x09, 0x42, 0x63, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x5d, 0x12, 0x5b, 0x56, 0x51, 0x4c, 0x20,
    -	0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61,
    -	0x63, 0x74, 0x20, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x77,
    -	0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69, 0x63,
    -	0x61, 0x6c, 0x6c, 0x79, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e,
    -	0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x20, 0x73,
    -	0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x06, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x12,
    -	0x6d, 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b,
    -	0x32, 0x0d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x42,
    -	0x44, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x3e, 0x12, 0x3c, 0x41, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20,
    -	0x6f, 0x66, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x6f,
    -	0x74, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x70, 0x6f, 0x73, 0x74, 0x20, 0x70,
    -	0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x61, 0x72, 0x74, 0x69,
    -	0x66, 0x61, 0x63, 0x74, 0x2e, 0x52, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x34,
    -	0x0a, 0x0c, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x10,
    -	0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6c,
    -	0x75, 0x6d, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54,
    -	0x79, 0x70, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x03, 0x72, 0x61, 0x77, 0x18, 0x07, 0x20, 0x01, 0x28,
    -	0x09, 0x42, 0x26, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x20, 0x12, 0x1e, 0x54, 0x68, 0x65, 0x20, 0x72,
    -	0x61, 0x77, 0x20, 0x59, 0x41, 0x4d, 0x4c, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20,
    -	0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x2e, 0x52, 0x03, 0x72, 0x61, 0x77, 0x12, 0x1a,
    -	0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08,
    -	0x52, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x75,
    -	0x69, 0x6c, 0x74, 0x5f, 0x69, 0x6e, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x62, 0x75,
    -	0x69, 0x6c, 0x74, 0x49, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65,
    -	0x64, 0x5f, 0x69, 0x6e, 0x18, 0x18, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x70,
    -	0x69, 0x6c, 0x65, 0x64, 0x49, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x73, 0x5f, 0x61, 0x6c, 0x69,
    -	0x61, 0x73, 0x18, 0x16, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x41, 0x6c, 0x69, 0x61,
    -	0x73, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x65,
    -	0x64, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x49, 0x6e, 0x68, 0x65, 0x72,
    -	0x69, 0x74, 0x65, 0x64, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
    -	0x18, 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41,
    -	0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52,
    -	0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x7f, 0xda, 0xfc, 0xe3, 0xc4, 0x01,
    -	0x79, 0x0a, 0x77, 0x41, 0x6e, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x20, 0x77,
    -	0x72, 0x61, 0x70, 0x73, 0x20, 0x61, 0x20, 0x56, 0x51, 0x4c, 0x20, 0x71, 0x75, 0x65, 0x72, 0x79,
    -	0x20, 0x69, 0x6e, 0x20, 0x72, 0x65, 0x75, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x2c, 0x20, 0x64, 0x6f,
    -	0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x77, 0x61, 0x79, 0x2e, 0x41, 0x72, 0x74,
    -	0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x61,
    -	0x62, 0x6f, 0x75, 0x74, 0x20, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x20,
    -	0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x6e, 0x61, 0x6c, 0x79,
    -	0x7a, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x2e, 0x22, 0x3c, 0x0a, 0x13, 0x41, 0x72,
    -	0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72,
    -	0x73, 0x12, 0x25, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
    -	0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63,
    -	0x74, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x40, 0x0a, 0x10, 0x41, 0x72, 0x74, 0x69,
    -	0x66, 0x61, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x16, 0x0a, 0x06,
    -	0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x68, 0x69,
    -	0x64, 0x64, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x61, 0x73, 0x69, 0x63, 0x18, 0x02, 0x20,
    -	0x01, 0x28, 0x08, 0x52, 0x05, 0x62, 0x61, 0x73, 0x69, 0x63, 0x22, 0xb9, 0x01, 0x0a, 0x17, 0x41,
    -	0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x53,
    -	0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x48, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61,
    -	0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
    -	0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
    -	0x61, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
    -	0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
    -	0x1a, 0x54, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72,
    -	0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
    -	0x6b, 0x65, 0x79, 0x12, 0x2d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01,
    -	0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66,
    -	0x61, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x05, 0x76, 0x61, 0x6c,
    -	0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xa9, 0x04, 0x0a, 0x04, 0x54, 0x6f, 0x6f, 0x6c, 0x12,
    -	0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
    -	0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
    -	0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x25, 0x0a, 0x0e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x5f,
    -	0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x67,
    -	0x69, 0x74, 0x68, 0x75, 0x62, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x2c, 0x0a, 0x12,
    -	0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x5f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x72, 0x65, 0x67,
    -	0x65, 0x78, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
    -	0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x65, 0x67, 0x65, 0x78, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x65,
    -	0x72, 0x76, 0x65, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28,
    -	0x08, 0x52, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x12,
    -	0x25, 0x0a, 0x0e, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64,
    -	0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x4f, 0x76,
    -	0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74,
    -	0x65, 0x64, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65,
    -	0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x48, 0x61, 0x73, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x76,
    -	0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65,
    -	0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61,
    -	0x6c, 0x69, 0x7a, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x6d, 0x61, 0x74, 0x65,
    -	0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x72, 0x74, 0x69, 0x66,
    -	0x61, 0x63, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x72, 0x74, 0x69, 0x66,
    -	0x61, 0x63, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65,
    -	0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x66, 0x69, 0x6c,
    -	0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x65,
    -	0x72, 0x76, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73,
    -	0x65, 0x72, 0x76, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x65,
    -	0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x72,
    -	0x76, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61,
    -	0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61,
    -	0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09,
    -	0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69,
    -	0x64, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e,
    -	0x76, 0x61, 0x6c, 0x69, 0x64, 0x48, 0x61, 0x73, 0x68, 0x12, 0x27, 0x0a, 0x08, 0x76, 0x65, 0x72,
    -	0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x72,
    -	0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x6f, 0x6f, 0x6c, 0x52, 0x08, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
    -	0x6e, 0x73, 0x22, 0x4a, 0x0a, 0x0b, 0x74, 0x68, 0x69, 0x72, 0x64, 0x5f, 0x70, 0x61, 0x72, 0x74,
    -	0x79, 0x12, 0x21, 0x0a, 0x05, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
    -	0x32, 0x0b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x6f, 0x6f, 0x6c, 0x52, 0x05, 0x74,
    -	0x6f, 0x6f, 0x6c, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18,
    -	0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xcb,
    -	0x02, 0x0a, 0x09, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07,
    -	0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x74,
    -	0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x6f, 0x70, 0x73, 0x5f, 0x70, 0x65,
    -	0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0c,
    -	0x6f, 0x70, 0x73, 0x50, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x12, 0x1b, 0x0a, 0x09,
    -	0x63, 0x70, 0x75, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x05, 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, 0x06, 0x20, 0x01, 0x28, 0x02, 0x52, 0x09, 0x69,
    -	0x6f, 0x70, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f,
    -	0x72, 0x6f, 0x77, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x52,
    -	0x6f, 0x77, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x6d, 0x61, 0x78, 0x5f, 0x75, 0x70, 0x6c, 0x6f, 0x61,
    -	0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x6d,
    -	0x61, 0x78, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x24, 0x0a,
    -	0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x18,
    -	0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x42, 0x61, 0x74, 0x63, 0x68, 0x57,
    -	0x61, 0x69, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68,
    -	0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6d, 0x61, 0x78,
    -	0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x6f, 0x77, 0x73, 0x12, 0x31, 0x0a, 0x15, 0x6d, 0x61, 0x78,
    -	0x5f, 0x62, 0x61, 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, 0x42, 0x37, 0x5a, 0x35,
    -	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, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x2f,
    -	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
    +	0x65, 0x64, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2f, 0x0a,
    +	0x13, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73,
    +	0x69, 0x6f, 0x6e, 0x73, 0x18, 0x1c, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x69, 0x6d, 0x70, 0x6c,
    +	0x69, 0x65, 0x64, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x20,
    +	0x0a, 0x0b, 0x69, 0x6d, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x65, 0x18, 0x1b, 0x20,
    +	0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6d, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x65,
    +	0x12, 0x2e, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x13, 0x20,
    +	0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x6f,
    +	0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73,
    +	0x12, 0x21, 0x0a, 0x05, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32,
    +	0x0b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x6f, 0x6f, 0x6c, 0x52, 0x05, 0x74, 0x6f,
    +	0x6f, 0x6c, 0x73, 0x12, 0x68, 0x0a, 0x0c, 0x70, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74,
    +	0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x42, 0x44, 0xe2, 0xfc, 0xe3, 0xc4, 0x01,
    +	0x3e, 0x12, 0x3c, 0x41, 0x20, 0x56, 0x51, 0x4c, 0x20, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73,
    +	0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61,
    +	0x74, 0x65, 0x64, 0x20, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x75, 0x73, 0x69,
    +	0x6e, 0x67, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52,
    +	0x0c, 0x70, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x6c, 0x0a,
    +	0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 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, 0x32, 0xe2, 0xfc, 0xe3,
    +	0xc4, 0x01, 0x2c, 0x12, 0x2a, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x20,
    +	0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x74,
    +	0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x2e, 0x52,
    +	0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x6e, 0x0a, 0x04, 0x74,
    +	0x79, 0x70, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x42, 0x5a, 0xe2, 0xfc, 0xe3, 0xc4, 0x01,
    +	0x54, 0x12, 0x52, 0x54, 0x68, 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74,
    +	0x68, 0x65, 0x20, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x20, 0x43, 0x61, 0x6e, 0x20, 0x62, 0x65,
    +	0x20, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x2c, 0x20, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f,
    +	0x45, 0x56, 0x45, 0x4e, 0x54, 0x2c, 0x20, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x2c, 0x20, 0x53,
    +	0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x2c, 0x20, 0x49, 0x4e, 0x54,
    +	0x45, 0x52, 0x4e, 0x41, 0x4c, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x5a, 0x0a, 0x07, 0x73,
    +	0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70,
    +	0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x6f, 0x75,
    +	0x72, 0x63, 0x65, 0x42, 0x29, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x23, 0x12, 0x21, 0x57, 0x68, 0x65,
    +	0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x20,
    +	0x67, 0x65, 0x74, 0x73, 0x20, 0x69, 0x74, 0x73, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x07,
    +	0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x6a, 0x0a, 0x07, 0x69, 0x6d, 0x70, 0x6f, 0x72,
    +	0x74, 0x73, 0x18, 0x11, 0x20, 0x03, 0x28, 0x09, 0x42, 0x50, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x4a,
    +	0x12, 0x48, 0x41, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x6f, 0x74, 0x68, 0x65,
    +	0x72, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x27, 0x20, 0x65, 0x78, 0x70,
    +	0x6f, 0x72, 0x74, 0x20, 0x56, 0x51, 0x4c, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x72, 0x65, 0x6c, 0x6f,
    +	0x61, 0x64, 0x20, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x69, 0x73,
    +	0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x2e, 0x52, 0x07, 0x69, 0x6d, 0x70, 0x6f,
    +	0x72, 0x74, 0x73, 0x12, 0x7b, 0x0a, 0x06, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x12, 0x20,
    +	0x01, 0x28, 0x09, 0x42, 0x63, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x5d, 0x12, 0x5b, 0x56, 0x51, 0x4c,
    +	0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66,
    +	0x61, 0x63, 0x74, 0x20, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x20, 0x49, 0x74, 0x20,
    +	0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69,
    +	0x63, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x20, 0x69,
    +	0x6e, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x20,
    +	0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x06, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74,
    +	0x12, 0x6d, 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28,
    +	0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74,
    +	0x42, 0x44, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x3e, 0x12, 0x3c, 0x41, 0x20, 0x6c, 0x69, 0x73, 0x74,
    +	0x20, 0x6f, 0x66, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x70,
    +	0x6f, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x70, 0x6f, 0x73, 0x74, 0x20,
    +	0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x61, 0x72, 0x74,
    +	0x69, 0x66, 0x61, 0x63, 0x74, 0x2e, 0x52, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12,
    +	0x34, 0x0a, 0x0c, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18,
    +	0x10, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f,
    +	0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e,
    +	0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x03, 0x72, 0x61, 0x77, 0x18, 0x07, 0x20, 0x01,
    +	0x28, 0x09, 0x42, 0x26, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x20, 0x12, 0x1e, 0x54, 0x68, 0x65, 0x20,
    +	0x72, 0x61, 0x77, 0x20, 0x59, 0x41, 0x4d, 0x4c, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73,
    +	0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x2e, 0x52, 0x03, 0x72, 0x61, 0x77, 0x12,
    +	0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28,
    +	0x08, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x62,
    +	0x75, 0x69, 0x6c, 0x74, 0x5f, 0x69, 0x6e, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x62,
    +	0x75, 0x69, 0x6c, 0x74, 0x49, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c,
    +	0x65, 0x64, 0x5f, 0x69, 0x6e, 0x18, 0x18, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x63, 0x6f, 0x6d,
    +	0x70, 0x69, 0x6c, 0x65, 0x64, 0x49, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x73, 0x5f, 0x61, 0x6c,
    +	0x69, 0x61, 0x73, 0x18, 0x16, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x41, 0x6c, 0x69,
    +	0x61, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74,
    +	0x65, 0x64, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x49, 0x6e, 0x68, 0x65,
    +	0x72, 0x69, 0x74, 0x65, 0x64, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
    +	0x61, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
    +	0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
    +	0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x7f, 0xda, 0xfc, 0xe3, 0xc4,
    +	0x01, 0x79, 0x0a, 0x77, 0x41, 0x6e, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x20,
    +	0x77, 0x72, 0x61, 0x70, 0x73, 0x20, 0x61, 0x20, 0x56, 0x51, 0x4c, 0x20, 0x71, 0x75, 0x65, 0x72,
    +	0x79, 0x20, 0x69, 0x6e, 0x20, 0x72, 0x65, 0x75, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x2c, 0x20, 0x64,
    +	0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x77, 0x61, 0x79, 0x2e, 0x41, 0x72,
    +	0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x61, 0x6c, 0x6c, 0x20,
    +	0x61, 0x62, 0x6f, 0x75, 0x74, 0x20, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6e, 0x67,
    +	0x20, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x6e, 0x61, 0x6c,
    +	0x79, 0x7a, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x2e, 0x22, 0x3c, 0x0a, 0x13, 0x41,
    +	0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f,
    +	0x72, 0x73, 0x12, 0x25, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
    +	0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61,
    +	0x63, 0x74, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x40, 0x0a, 0x10, 0x41, 0x72, 0x74,
    +	0x69, 0x66, 0x61, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x16, 0x0a,
    +	0x06, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x68,
    +	0x69, 0x64, 0x64, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x61, 0x73, 0x69, 0x63, 0x18, 0x02,
    +	0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x62, 0x61, 0x73, 0x69, 0x63, 0x22, 0xb9, 0x01, 0x0a, 0x17,
    +	0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
    +	0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x48, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64,
    +	0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x72, 0x6f, 0x74,
    +	0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61,
    +	0x74, 0x61, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61,
    +	0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
    +	0x61, 0x1a, 0x54, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74,
    +	0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
    +	0x03, 0x6b, 0x65, 0x79, 0x12, 0x2d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20,
    +	0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69,
    +	0x66, 0x61, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x05, 0x76, 0x61,
    +	0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xa9, 0x04, 0x0a, 0x04, 0x54, 0x6f, 0x6f, 0x6c,
    +	0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
    +	0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28,
    +	0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x25, 0x0a, 0x0e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
    +	0x5f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d,
    +	0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x2c, 0x0a,
    +	0x12, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x5f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x72, 0x65,
    +	0x67, 0x65, 0x78, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x67, 0x69, 0x74, 0x68, 0x75,
    +	0x62, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x65, 0x67, 0x65, 0x78, 0x12, 0x23, 0x0a, 0x0d, 0x73,
    +	0x65, 0x72, 0x76, 0x65, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x18, 0x03, 0x20, 0x01,
    +	0x28, 0x08, 0x52, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x6c, 0x79,
    +	0x12, 0x25, 0x0a, 0x0e, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69,
    +	0x64, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x4f,
    +	0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x78, 0x70, 0x65, 0x63,
    +	0x74, 0x65, 0x64, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c,
    +	0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x48, 0x61, 0x73, 0x68, 0x12, 0x18, 0x0a, 0x07,
    +	0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76,
    +	0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69,
    +	0x61, 0x6c, 0x69, 0x7a, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x6d, 0x61, 0x74,
    +	0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x72, 0x74, 0x69,
    +	0x66, 0x61, 0x63, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x72, 0x74, 0x69,
    +	0x66, 0x61, 0x63, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x74, 0x6f, 0x72,
    +	0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x66, 0x69,
    +	0x6c, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1b, 0x0a, 0x09, 0x73,
    +	0x65, 0x72, 0x76, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
    +	0x73, 0x65, 0x72, 0x76, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x72, 0x76,
    +	0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65,
    +	0x72, 0x76, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e,
    +	0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e,
    +	0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28,
    +	0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x6e, 0x76, 0x61, 0x6c,
    +	0x69, 0x64, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69,
    +	0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x48, 0x61, 0x73, 0x68, 0x12, 0x27, 0x0a, 0x08, 0x76, 0x65,
    +	0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70,
    +	0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x6f, 0x6f, 0x6c, 0x52, 0x08, 0x76, 0x65, 0x72, 0x73, 0x69,
    +	0x6f, 0x6e, 0x73, 0x22, 0x4a, 0x0a, 0x0b, 0x74, 0x68, 0x69, 0x72, 0x64, 0x5f, 0x70, 0x61, 0x72,
    +	0x74, 0x79, 0x12, 0x21, 0x0a, 0x05, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
    +	0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x6f, 0x6f, 0x6c, 0x52, 0x05,
    +	0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
    +	0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22,
    +	0xcb, 0x02, 0x0a, 0x09, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x18, 0x0a,
    +	0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07,
    +	0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x6f, 0x70, 0x73, 0x5f, 0x70,
    +	0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x02, 0x52,
    +	0x0c, 0x6f, 0x70, 0x73, 0x50, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x12, 0x1b, 0x0a,
    +	0x09, 0x63, 0x70, 0x75, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x05, 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, 0x06, 0x20, 0x01, 0x28, 0x02, 0x52, 0x09,
    +	0x69, 0x6f, 0x70, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78,
    +	0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x6d, 0x61, 0x78,
    +	0x52, 0x6f, 0x77, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x6d, 0x61, 0x78, 0x5f, 0x75, 0x70, 0x6c, 0x6f,
    +	0x61, 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e,
    +	0x6d, 0x61, 0x78, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x24,
    +	0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x77, 0x61, 0x69, 0x74,
    +	0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x42, 0x61, 0x74, 0x63, 0x68,
    +	0x57, 0x61, 0x69, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x61, 0x74, 0x63,
    +	0x68, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6d, 0x61,
    +	0x78, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x6f, 0x77, 0x73, 0x12, 0x31, 0x0a, 0x15, 0x6d, 0x61,
    +	0x78, 0x5f, 0x62, 0x61, 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, 0x42, 0x37, 0x5a,
    +	0x35, 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, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73,
    +	0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
     }
     
     var (
    
  • artifacts/proto/artifact.proto+22 0 modified
    @@ -150,6 +150,28 @@ message Artifact {
                 description: "A list of required permissions to collect this artifact."
             }];
     
    +    // A list of permissions implied by this artifact. This is used by
    +    // the artifact writer to declare what additional permissions the
    +    // artifact provides over the permissions provided by the user.
    +    //
    +    // On the client, artifacts do not run with ACL enforced,
    +    // therefore they can do anything, including actions which the
    +    // user launching the artifact does not have. For example, the
    +    // user may have the investigator role which does not have
    +    // EXECVE. However, when launching this artifact on the client,
    +    // the artifact will be able to run actions requiring the EXEVE
    +    // permission (because there is no ACL enforcement on the client).
    +    //
    +    // Therefore we say this artifact implies the user has EXECVE -
    +    // this is safe if the aritfact takes steps to ensure the user
    +    // does not have arbitrary control over what to execute (for
    +    // example, if the artifact launches a tool with restricted
    +    // command line args).
    +    //
    +    // This field is only used to ensure the static analysis engine
    +    // that the implied permission is properly controlled.
    +    repeated string implied_permissions = 28;
    +
         // If this is specified, we run this artifact as the named user,
         // with that user's ACL token. This is similar to the Unix suid
         // mechanism or the Windows impersonation mechanism in that it
    
  • artifacts/testdata/server/testcases/verify.in.yaml+5 0 added
    @@ -0,0 +1,5 @@
    +Queries:
    +  - SELECT count()  AS Count ,
    +       verify(artifact=name) AS V
    +    FROM artifact_definitions()
    +    WHERE type=~'client' AND built_in AND V.Warnings
    
  • artifacts/testdata/server/testcases/verify.out.yaml+1 0 added
    @@ -0,0 +1 @@
    +SELECT count()  AS Count , verify(artifact=name) AS V FROM artifact_definitions() WHERE type=~'client' AND built_in AND V.Warnings[]
    \ No newline at end of file
    
  • bin/verify.go+18 12 modified
    @@ -47,26 +47,27 @@ func doVerify() error {
     	logger := logging.GetLogger(config_obj, &logging.ToolComponent)
     
     	// Report all errors and keep going as much as possible.
    -	returned_errs := make(map[string]error)
    -
     	artifacts := make(map[string]*artifacts_proto.Artifact)
    +	states := make(map[string]*launcher.AnalysisState)
     
     	repository, err := manager.GetGlobalRepository(config_obj)
     	if err != nil {
     		return err
     	}
    +
     	for _, artifact_path := range *verify_args {
    -		returned_errs[artifact_path] = nil
    +		state := launcher.NewAnalysisState(artifact_path)
    +		states[artifact_path] = state
     
     		fd, err := os.Open(artifact_path)
     		if err != nil {
    -			returned_errs[artifact_path] = err
    +			state.SetError(err)
     			continue
     		}
     
     		data, err := ioutil.ReadAll(fd)
     		if err != nil {
    -			returned_errs[artifact_path] = err
    +			state.SetError(err)
     			continue
     		}
     
    @@ -76,24 +77,29 @@ func doVerify() error {
     			AllowOverridingAlias: true,
     		})
     		if err != nil {
    -			returned_errs[artifact_path] = err
    +			state.SetError(err)
     			continue
     		}
     		artifacts[artifact_path] = a
     	}
     
    -	for artifact_path, a := range artifacts {
    +	for artifact_path, artifact := range artifacts {
    +		state, _ := states[artifact_path]
     		launcher.VerifyArtifact(ctx, config_obj,
    -			artifact_path, a, returned_errs)
    +			repository, artifact, state)
     	}
     
     	var ret error
    -	for artifact_path, err := range returned_errs {
    -		if err != nil {
    +	for artifact_path, state := range states {
    +		if len(state.Errors) == 0 {
    +			logger.Info("Verified %v: <green>OK</>", artifact_path)
    +		}
    +		for _, err := range state.Errors {
     			logger.Error("%v: <red>%v</>", artifact_path, err)
     			ret = err
    -		} else {
    -			logger.Info("Verified %v: <green>OK</>", artifact_path)
    +		}
    +		for _, msg := range state.Warnings {
    +			logger.Info("%v: %v", artifact_path, msg)
     		}
     	}
     
    
  • docs/references/vql.yaml+1 1 modified
    @@ -8868,7 +8868,7 @@
     
         2. The `enrichment` field specifies a VQL lambda which will be
            used to build an enrichment object after a match is made. This
    -       is used to additional infomation for the analyst to assess.
    +       is used to additional information for the analyst to assess.
     
         3. The `vql` modifier can be used to specify a VQL lambda that
            will be used in a detection clause. The lambda will receive the
    
  • go.mod+3 3 modified
    @@ -74,7 +74,7 @@ require (
     	golang.org/x/mod v0.21.0
     	golang.org/x/net v0.38.0
     	golang.org/x/sys v0.32.0
    -	golang.org/x/text v0.24.0
    +	golang.org/x/text v0.25.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
    @@ -92,7 +92,7 @@ require (
     	www.velocidex.com/golang/go-prefetch v0.0.0-20240910051453-2385582c1c22
     	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-20250506071806-b4ce88fa0048
    +	www.velocidex.com/golang/vfilter v0.0.0-20250520023105-e30ee3b29709
     )
     
     require (
    @@ -281,7 +281,7 @@ require (
     	go.uber.org/multierr v1.11.0 // indirect
     	go.uber.org/zap v1.27.0 // indirect
     	golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect
    -	golang.org/x/sync v0.13.0 // indirect
    +	golang.org/x/sync v0.14.0 // indirect
     	golang.org/x/term v0.30.0 // indirect
     	google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 // indirect
     	kernel.org/pub/linux/libs/security/libcap/cap v1.2.71 // indirect
    
  • go.sum+6 6 modified
    @@ -818,8 +818,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ
     golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
     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.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
    -golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
    +golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
    +golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
     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=
     golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
    @@ -877,8 +877,8 @@ golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
     golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
     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.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
    -golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
    +golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
    +golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
     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=
     golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
    @@ -1007,7 +1007,7 @@ www.velocidex.com/golang/oleparse v0.0.0-20250312121321-f7c2b4ec0959 h1:qJlm0T61
     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-20250506071806-b4ce88fa0048 h1:EEtilwfOb8pfaZ2cbavThTZVXQ1lbPABVjXwaQHb3lM=
    -www.velocidex.com/golang/vfilter v0.0.0-20250506071806-b4ce88fa0048/go.mod h1:P50KPQr2LpWVAu7ilGH8CBLBASGtOJ2971yA9YhR8rY=
    +www.velocidex.com/golang/vfilter v0.0.0-20250520023105-e30ee3b29709 h1:FD1zc0go4SJW/FFkYV5LvYNs2nNJ9YHoLRpq+YXT9uQ=
    +www.velocidex.com/golang/vfilter v0.0.0-20250520023105-e30ee3b29709/go.mod h1:P50KPQr2LpWVAu7ilGH8CBLBASGtOJ2971yA9YhR8rY=
     www.velocidex.com/golang/vtypes v0.0.0-20240123105603-069d4a7f435c h1:rL/It+Ig+mvIhmy9vl5gg5b6CX2J12x0v2SXIT2RoWE=
     www.velocidex.com/golang/vtypes v0.0.0-20240123105603-069d4a7f435c/go.mod h1:tjaJNlBWbvH4cEMrEu678CFR2hrtcdyPINIpRxrOh4U=
    
  • gui/velociraptor/package.json+7 2 modified
    @@ -10,8 +10,13 @@
             "@fortawesome/free-solid-svg-icons": "^6.7.2",
             "@fortawesome/react-fontawesome": "0.2.2",
             "@popperjs/core": "^2.11.8",
    -        "axios": ">=1.8.4",
    +<<<<<<< HEAD
    +        "axios": ">=1.9.0",
             "ace-builds": "1.40.0",
    +=======
    +        "axios": ">=1.8.4",
    +        "ace-builds": "1.40.1",
    +>>>>>>> a977a6e22 (fix: upgrade ace-builds from 1.40.0 to 1.40.1)
             "axios-retry": "3.9.1",
             "bootstrap": "5.3.5",
             "classnames": "^2.5.1",
    @@ -49,7 +54,7 @@
             "recharts": "^2.15.3",
             "sprintf-js": "1.1.3",
             "url-parse": "^1.5.10",
    -        "webpack": "5.99.6"
    +        "webpack": "5.99.7"
         },
         "homepage": ".",
         "scripts": {
    
  • gui/velociraptor/package-lock.json+32 30 modified
    @@ -15,10 +15,10 @@
                     "@fortawesome/free-solid-svg-icons": "^6.7.2",
                     "@fortawesome/react-fontawesome": "0.2.2",
                     "@popperjs/core": "^2.11.8",
    -                "ace-builds": "^1.40.0",
    -                "axios": ">=1.8.4",
    +                "ace-builds": "1.40.1",
    +                "axios": "^1.9.0",
                     "axios-retry": "3.9.1",
    -                "bootstrap": "^5.3.5",
    +                "bootstrap": "5.3.5",
                     "classnames": "^2.5.1",
                     "csv-parse": "4.16.3",
                     "csv-stringify": "5.6.5",
    @@ -54,7 +54,7 @@
                     "recharts": "^2.15.3",
                     "sprintf-js": "1.1.3",
                     "url-parse": "^1.5.10",
    -                "webpack": "^5.99.6"
    +                "webpack": "^5.99.7"
                 },
                 "devDependencies": {
                     "@babel/core": "^7.25.2",
    @@ -3736,9 +3736,9 @@
                 "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
             },
             "node_modules/ace-builds": {
    -            "version": "1.40.0",
    -            "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.40.0.tgz",
    -            "integrity": "sha512-wOCyJfNRsq/yLTR7z2KpwcjaInuUs/mosu/OFLGGUA+g+ApD9OJ1AToHDIp0Xpa2koHJ79bmOya73oWjCNbjlA==",
    +            "version": "1.40.1",
    +            "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.40.1.tgz",
    +            "integrity": "sha512-32uwJNwmhqpnYtr6oq8RoO1D6F6tnxisv5f9w2XPX3vi4QruuHNikadHUiHvnxLAV1n5Azv4LFtpItQ5dD1eRw==",
                 "license": "BSD-3-Clause"
             },
             "node_modules/acorn": {
    @@ -3982,9 +3982,9 @@
                 }
             },
             "node_modules/axios": {
    -            "version": "1.8.4",
    -            "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz",
    -            "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==",
    +            "version": "1.9.0",
    +            "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz",
    +            "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==",
                 "license": "MIT",
                 "dependencies": {
                     "follow-redirects": "^1.15.6",
    @@ -8581,9 +8581,9 @@
                 }
             },
             "node_modules/schema-utils": {
    -            "version": "4.3.0",
    -            "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz",
    -            "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==",
    +            "version": "4.3.2",
    +            "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz",
    +            "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==",
                 "license": "MIT",
                 "dependencies": {
                     "@types/json-schema": "^7.0.9",
    @@ -9535,13 +9535,14 @@
                 }
             },
             "node_modules/webpack": {
    -            "version": "5.99.6",
    -            "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.6.tgz",
    -            "integrity": "sha512-TJOLrJ6oeccsGWPl7ujCYuc0pIq2cNsuD6GZDma8i5o5Npvcco/z+NKvZSFsP0/x6SShVb0+X2JK/JHUjKY9dQ==",
    +            "version": "5.99.7",
    +            "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.7.tgz",
    +            "integrity": "sha512-CNqKBRMQjwcmKR0idID5va1qlhrqVUKpovi+Ec79ksW8ux7iS1+A6VqzfZXgVYCFRKl7XL5ap3ZoMpwBJxcg0w==",
                 "license": "MIT",
                 "dependencies": {
                     "@types/eslint-scope": "^3.7.7",
                     "@types/estree": "^1.0.6",
    +                "@types/json-schema": "^7.0.15",
                     "@webassemblyjs/ast": "^1.14.1",
                     "@webassemblyjs/wasm-edit": "^1.14.1",
                     "@webassemblyjs/wasm-parser": "^1.14.1",
    @@ -9558,7 +9559,7 @@
                     "loader-runner": "^4.2.0",
                     "mime-types": "^2.1.27",
                     "neo-async": "^2.6.2",
    -                "schema-utils": "^4.3.0",
    +                "schema-utils": "^4.3.2",
                     "tapable": "^2.1.1",
                     "terser-webpack-plugin": "^5.3.11",
                     "watchpack": "^2.4.1",
    @@ -12201,9 +12202,9 @@
                 "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
             },
             "ace-builds": {
    -            "version": "1.40.0",
    -            "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.40.0.tgz",
    -            "integrity": "sha512-wOCyJfNRsq/yLTR7z2KpwcjaInuUs/mosu/OFLGGUA+g+ApD9OJ1AToHDIp0Xpa2koHJ79bmOya73oWjCNbjlA=="
    +            "version": "1.40.1",
    +            "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.40.1.tgz",
    +            "integrity": "sha512-32uwJNwmhqpnYtr6oq8RoO1D6F6tnxisv5f9w2XPX3vi4QruuHNikadHUiHvnxLAV1n5Azv4LFtpItQ5dD1eRw=="
             },
             "acorn": {
                 "version": "8.14.0",
    @@ -12377,9 +12378,9 @@
                 "dev": true
             },
             "axios": {
    -            "version": "1.8.4",
    -            "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz",
    -            "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==",
    +            "version": "1.9.0",
    +            "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz",
    +            "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==",
                 "requires": {
                     "follow-redirects": "^1.15.6",
                     "form-data": "^4.0.0",
    @@ -15734,9 +15735,9 @@
                 }
             },
             "schema-utils": {
    -            "version": "4.3.0",
    -            "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz",
    -            "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==",
    +            "version": "4.3.2",
    +            "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz",
    +            "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==",
                 "requires": {
                     "@types/json-schema": "^7.0.9",
                     "ajv": "^8.9.0",
    @@ -16415,12 +16416,13 @@
                 }
             },
             "webpack": {
    -            "version": "5.99.6",
    -            "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.6.tgz",
    -            "integrity": "sha512-TJOLrJ6oeccsGWPl7ujCYuc0pIq2cNsuD6GZDma8i5o5Npvcco/z+NKvZSFsP0/x6SShVb0+X2JK/JHUjKY9dQ==",
    +            "version": "5.99.7",
    +            "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.7.tgz",
    +            "integrity": "sha512-CNqKBRMQjwcmKR0idID5va1qlhrqVUKpovi+Ec79ksW8ux7iS1+A6VqzfZXgVYCFRKl7XL5ap3ZoMpwBJxcg0w==",
                 "requires": {
                     "@types/eslint-scope": "^3.7.7",
                     "@types/estree": "^1.0.6",
    +                "@types/json-schema": "^7.0.15",
                     "@webassemblyjs/ast": "^1.14.1",
                     "@webassemblyjs/wasm-edit": "^1.14.1",
                     "@webassemblyjs/wasm-parser": "^1.14.1",
    @@ -16437,7 +16439,7 @@
                     "loader-runner": "^4.2.0",
                     "mime-types": "^2.1.27",
                     "neo-async": "^2.6.2",
    -                "schema-utils": "^4.3.0",
    +                "schema-utils": "^4.3.2",
                     "tapable": "^2.1.1",
                     "terser-webpack-plugin": "^5.3.11",
                     "watchpack": "^2.4.1",
    
  • services/launcher/verifier.go+122 36 modified
    @@ -5,6 +5,7 @@ import (
     	"fmt"
     	"strings"
     
    +	api_proto "www.velocidex.com/golang/velociraptor/api/proto"
     	artifacts_proto "www.velocidex.com/golang/velociraptor/artifacts/proto"
     	config_proto "www.velocidex.com/golang/velociraptor/config/proto"
     	"www.velocidex.com/golang/velociraptor/services"
    @@ -17,18 +18,102 @@ var (
     	api_description = &ApiDescription{}
     )
     
    +// Contains the result of the static analysis.
    +type AnalysisState struct {
    +	Artifact    string
    +	Permissions []string
    +	Errors      []error
    +	Warnings    []string
    +}
    +
    +func (self *AnalysisState) SetError(err error) {
    +	self.Errors = append(self.Errors, err)
    +}
    +
    +func (self *AnalysisState) AnalyseCall(
    +	callsite vfilter.CallSite, desc CallDesciptor) {
    +	self.Permissions = utils.Sort(utils.DeduplicateStringSlice(
    +		append(self.Permissions, desc.Permissions...)))
    +}
    +
    +func (self *AnalysisState) AnalyseArtifactRequiredPermissions(
    +	artifact *artifacts_proto.Artifact) {
    +	switch strings.ToUpper(artifact.Type) {
    +	case "", "CLIENT":
    +	default:
    +		return
    +	}
    +
    +	// When a user runs an artifact on a client they implicitly have
    +	// these permissions.
    +	implied_permissions := []string{
    +		"FILESYSTEM_READ", "MACHINE_STATE",
    +
    +		// Used by http_client on the client side.
    +		"COLLECT_SERVER",
    +	}
    +
    +	// They also receive permissins required by the artifact because
    +	// this will be enforced on the server.
    +	implied_permissions = append(implied_permissions,
    +		artifact.RequiredPermissions...)
    +
    +	// The artifact writer can also declare which permission are
    +	// safely controlled.
    +	implied_permissions = append(implied_permissions,
    +		artifact.ImpliedPermissions...)
    +
    +	// Now go over all the permissions used by the artifact an warn
    +	// about all permissions that are not required
    +	for _, perm := range self.Permissions {
    +		if !utils.InString(implied_permissions, perm) {
    +			self.Warnings = append(self.Warnings,
    +				fmt.Sprintf("<yellow>Suggestion</>: Add %v to artifact's required_permissions or implied_permissions fields", perm))
    +		}
    +	}
    +}
    +
    +func NewAnalysisState(artifact string) *AnalysisState {
    +	return &AnalysisState{
    +		Artifact: artifact,
    +	}
    +}
    +
     type Required bool
     
    +type CallDesciptor struct {
    +	ArgsRequired map[string]Required
    +	Permissions  []string
    +}
    +
    +func (self *CallDesciptor) SetPermissions(api *api_proto.Completion) {
    +	if api.Metadata != nil {
    +		perms, pres := api.Metadata["permissions"]
    +		if pres {
    +			self.Permissions = strings.Split(perms, ",")
    +		}
    +	}
    +}
    +
    +func NewCallDesciptor(api *api_proto.Completion) CallDesciptor {
    +	res := &CallDesciptor{
    +		ArgsRequired: make(map[string]Required),
    +	}
    +
    +	res.SetPermissions(api)
    +	return *res
    +}
    +
     type ApiDescription struct {
    -	functions map[string]map[string]Required
    -	plugins   map[string]map[string]Required
    +	functions map[string]CallDesciptor
    +	plugins   map[string]CallDesciptor
     }
     
     func (self *ApiDescription) init() error {
     	// Initialize if needed
     	if self.functions == nil || self.plugins == nil {
    -		self.functions = make(map[string]map[string]Required)
    -		self.plugins = make(map[string]map[string]Required)
    +		self.functions = make(map[string]CallDesciptor)
    +		self.plugins = make(map[string]CallDesciptor)
     
     		apis, err := utils.LoadApiDescription()
     		if err != nil {
    @@ -37,21 +122,24 @@ func (self *ApiDescription) init() error {
     
     		for _, api := range apis {
     			if api.Type == "Function" {
    -				desc := make(map[string]Required)
    +				desc := NewCallDesciptor(api)
    +
     				// Ignore ** kwargs type of call.
    -				desc["**"] = Required(false)
    +				desc.ArgsRequired["**"] = Required(false)
     				for _, arg := range api.Args {
    -					desc[arg.Name] = Required(arg.Required)
    +					desc.ArgsRequired[arg.Name] = Required(arg.Required)
     				}
     				if !api.FreeFormArgs {
     					self.functions[api.Name] = desc
     				}
     			}
     			if api.Type == "Plugin" {
    -				desc := make(map[string]Required)
    -				desc["**"] = Required(false)
    +				desc := NewCallDesciptor(api)
    +
    +				// Ignore ** kwargs type of call.
    +				desc.ArgsRequired["**"] = Required(false)
     				for _, arg := range api.Args {
    -					desc[arg.Name] = Required(arg.Required)
    +					desc.ArgsRequired[arg.Name] = Required(arg.Required)
     				}
     				if !api.FreeFormArgs {
     					self.plugins[api.Name] = desc
    @@ -96,7 +184,8 @@ func (self *ApiDescription) verifyArtifact(
     func (self *ApiDescription) VerifyCallSite(
     	ctx context.Context, config_obj *config_proto.Config,
     	repository services.Repository,
    -	callsite vfilter.CallSite) (res []error) {
    +	callsite vfilter.CallSite,
    +	state *AnalysisState) (res []error) {
     
     	err := self.init()
     	if err != nil {
    @@ -112,8 +201,10 @@ func (self *ApiDescription) VerifyCallSite(
     	if callsite.Type == "plugin" {
     		desc, pres := self.plugins[callsite.Name]
     		if pres {
    +			state.AnalyseCall(callsite, desc)
    +
     			for _, arg := range callsite.Args {
    -				_, pres := desc[arg]
    +				_, pres := desc.ArgsRequired[arg]
     				if !pres {
     					res = append(res, fmt.Errorf(
     						"Invalid arg %v for plugin %v()",
    @@ -122,7 +213,7 @@ func (self *ApiDescription) VerifyCallSite(
     			}
     
     			// Now check if any of the required args are missing
    -			for arg, required := range desc {
    +			for arg, required := range desc.ArgsRequired {
     				if bool(required) && !utils.InString(callsite.Args, arg) {
     					res = append(res, fmt.Errorf(
     						"While calling plugin %v(), required arg %v is not provided",
    @@ -135,8 +226,10 @@ func (self *ApiDescription) VerifyCallSite(
     	if callsite.Type == "function" {
     		desc, pres := self.functions[callsite.Name]
     		if pres {
    +			state.AnalyseCall(callsite, desc)
    +
     			for _, arg := range callsite.Args {
    -				_, pres := desc[arg]
    +				_, pres := desc.ArgsRequired[arg]
     				if !pres {
     					res = append(res, fmt.Errorf(
     						"Invalid arg %v for function %v()",
    @@ -145,7 +238,7 @@ func (self *ApiDescription) VerifyCallSite(
     			}
     
     			// Now check if any of the required args are missing
    -			for arg, required := range desc {
    +			for arg, required := range desc.ArgsRequired {
     				if bool(required) && !utils.InString(callsite.Args, arg) {
     					res = append(res, fmt.Errorf(
     						"While calling vql function %v(), required arg %v is not called",
    @@ -161,7 +254,8 @@ func (self *ApiDescription) VerifyCallSite(
     
     // Run additional validation on the VQL to ensure it is valid.
     func VerifyVQL(ctx context.Context, config_obj *config_proto.Config,
    -	query string, repository services.Repository) (res []error) {
    +	query string, repository services.Repository,
    +	state *AnalysisState) (res []error) {
     
     	scope := vql_subsystem.MakeScope()
     
    @@ -177,7 +271,7 @@ func VerifyVQL(ctx context.Context, config_obj *config_proto.Config,
     
     		for _, cs := range visitor.CallSites {
     			res = append(res, api_description.VerifyCallSite(
    -				ctx, config_obj, repository, cs)...)
    +				ctx, config_obj, repository, cs, state)...)
     		}
     	}
     
    @@ -186,24 +280,14 @@ func VerifyVQL(ctx context.Context, config_obj *config_proto.Config,
     
     func VerifyArtifact(
     	ctx context.Context, config_obj *config_proto.Config,
    -	artifact_path string,
    +	repository services.Repository,
     	artifact *artifacts_proto.Artifact,
    -	returned_errs map[string]error) {
    -
    -	manager, err := services.GetRepositoryManager(config_obj)
    -	if err != nil {
    -		return
    -	}
    -
    -	repository, err := manager.GetGlobalRepository(config_obj)
    -	if err != nil {
    -		return
    -	}
    +	state *AnalysisState) {
     
     	if artifact.Precondition != "" {
     		for _, err := range VerifyVQL(ctx, config_obj,
    -			artifact.Precondition, repository) {
    -			returned_errs[artifact_path] = err
    +			artifact.Precondition, repository, state) {
    +			state.SetError(err)
     		}
     	}
     
    @@ -214,21 +298,23 @@ func VerifyArtifact(
     			err := GetQueryDependencies(ctx, config_obj,
     				repository, s.Query, 0, dependency)
     			if err != nil {
    -				returned_errs[artifact_path] = err
    +				state.SetError(err)
     				continue
     			}
     
     			// Now check for broken callsites
     			for _, err := range VerifyVQL(ctx, config_obj,
    -				s.Query, repository) {
    -				returned_errs[artifact_path] = err
    +				s.Query, repository, state) {
    +				state.SetError(err)
     			}
     		}
     		if s.Precondition != "" {
     			for _, err := range VerifyVQL(ctx, config_obj,
    -				s.Precondition, repository) {
    -				returned_errs[artifact_path] = err
    +				s.Precondition, repository, state) {
    +				state.SetError(err)
     			}
     		}
     	}
    +
    +	state.AnalyseArtifactRequiredPermissions(artifact)
     }
    
  • services/launcher/verifier_test.go+2 1 modified
    @@ -43,8 +43,9 @@ func (self *LauncherTestSuite) TestVerifyVQL() {
     	assert.NoError(self.T(), err)
     
     	for _, tc := range verifier_test_cases {
    +		state := launcher.NewAnalysisState("")
     		errs := launcher.VerifyVQL(self.Ctx,
    -			self.ConfigObj, tc.query, repository)
    +			self.ConfigObj, tc.query, repository, state)
     		if len(errs) > 0 {
     			if tc.error_regex == "" {
     				self.T().Fatalf("%v: Expected no error but got %v",
    
  • services/repository/plugin_test.go+8 59 modified
    @@ -70,14 +70,13 @@ func (self *PluginTestSuite) TestArtifactsSyntax() {
     	assert.NoError(self.T(), err)
     
     	new_repository := manager.NewRepository()
    +	new_repository.SetParent(repository, ConfigObj)
     
     	names, err := repository.List(self.Ctx, ConfigObj)
     	assert.NoError(self.T(), err)
     
    -	// Additinal verifications
    -	returned_errs := make(map[string]error)
    -
     	for _, artifact_name := range names {
    +		state := launcher.NewAnalysisState(artifact_name)
     		artifact, pres := repository.Get(self.Ctx, ConfigObj, artifact_name)
     		assert.True(self.T(), pres)
     
    @@ -87,15 +86,14 @@ func (self *PluginTestSuite) TestArtifactsSyntax() {
     			assert.NoError(self.T(), err, "Error compiling "+artifact_name)
     
     			launcher.VerifyArtifact(
    -				self.Ctx, self.ConfigObj, artifact_name, artifact, returned_errs)
    -		}
    -	}
    +				self.Ctx, self.ConfigObj, new_repository, artifact, state)
     
    -	for artifact_name, err := range returned_errs {
    -		fmt.Printf("Error with %v: %v\n", artifact_name, err)
    +			for _, err := range state.Errors {
    +				fmt.Printf("Error with %v: %v\n", artifact_name, err)
    +			}
    +			assert.True(self.T(), len(state.Errors) == 0)
    +		}
     	}
    -
    -	assert.True(self.T(), len(returned_errs) == 0)
     }
     
     var (
    @@ -347,55 +345,6 @@ func (self *PluginTestSuite) TestClientPluginMultipleSourcesAndPrecondtionsEvent
     
     }
     
    -var (
    -	memory_leak_test = `
    -name: ArtifactWithMemoryLeak
    -sources:
    -- query: |
    -    LET X <= "Hello World" * 1000000
    -
    -    SELECT X FROM scope()
    -`
    -)
    -
    -func (self *PluginTestSuite) TestPluginMemoryLeak() {
    -	repository := self.LoadArtifacts(memory_leak_test)
    -	builder := services.ScopeBuilder{
    -		Config:     self.ConfigObj,
    -		ACLManager: acl_managers.NullACLManager{},
    -		Repository: repository,
    -		Logger: logging.NewPlainLogger(
    -			self.ConfigObj, &logging.FrontendComponent),
    -		Env: ordereddict.NewDict(),
    -	}
    -
    -	manager, _ := services.GetRepositoryManager(self.ConfigObj)
    -	scope := manager.BuildScope(builder)
    -	defer scope.Close()
    -
    -	queries := []string{
    -		`SELECT * FROM foreach(
    -   row={
    -      SELECT * FROM range(end=10000)
    -   }, query={
    -      SELECT * FROM Artifact.ArtifactWithMemoryLeak()
    -      WHERE FALSE
    -   })`,
    -	}
    -
    -	results := ordereddict.NewDict()
    -	for _, query := range queries {
    -		rows := []vfilter.Row{}
    -		vql, err := vfilter.Parse(query)
    -		assert.NoError(self.T(), err)
    -
    -		for row := range vql.Eval(self.Ctx, scope) {
    -			rows = append(rows, row)
    -		}
    -		results.Set(query, rows)
    -	}
    -}
    -
     func TestArtifactPlugin(t *testing.T) {
     	suite.Run(t, &PluginTestSuite{})
     }
    
  • services/sanity/lockdown.go+9 1 modified
    @@ -17,7 +17,12 @@ func (self SanityChecks) CheckForLockdown(
     	}
     
     	lockdown_token := &acl_proto.ApiClientACL{
    -		ArtifactWriter:       true,
    +		ArtifactWriter: true,
    +
    +		// Labeling clients can move them between label groups which
    +		// may cause new artifacts to be collected automatically
    +		// (e.g. Quarantine).
    +		LabelClients:         true,
     		ServerArtifactWriter: true,
     		CollectClient:        true,
     		CollectServer:        true,
    @@ -28,6 +33,9 @@ func (self SanityChecks) CheckForLockdown(
     		FilesystemRead:       true,
     		MachineState:         true,
     		CollectBasic:         true,
    +
    +		Impersonation: true,
    +		OrgAdmin:      true,
     	}
     
     	if config_obj.Defaults != nil &&
    
  • vql/golang/verify.go+84 0 added
    @@ -0,0 +1,84 @@
    +package golang
    +
    +import (
    +	"context"
    +
    +	"github.com/Velocidex/ordereddict"
    +	"www.velocidex.com/golang/velociraptor/services"
    +	"www.velocidex.com/golang/velociraptor/services/launcher"
    +	vql_subsystem "www.velocidex.com/golang/velociraptor/vql"
    +	"www.velocidex.com/golang/vfilter"
    +	"www.velocidex.com/golang/vfilter/arg_parser"
    +)
    +
    +type VerifyFunctionArgs struct {
    +	Artifact string `vfilter:"required,field=artifact,doc=The artifact to verify. This can be an artifact source in yaml or json or the name of an artifact"`
    +}
    +
    +func init() {
    +	vql_subsystem.RegisterFunction(
    +		vfilter.GenericFunction{
    +			FunctionName: "verify",
    +			Doc: `verify an artifact
    +
    +This function will verify the artifact and flag any potential errors or warnings.
    +`,
    +			Metadata: vql_subsystem.VQLMetadata().Build(),
    +			ArgType:  &VerifyFunctionArgs{},
    +			Function: func(
    +				ctx context.Context,
    +				scope vfilter.Scope,
    +				args *ordereddict.Dict) vfilter.Any {
    +
    +				arg := &VerifyFunctionArgs{}
    +				err := arg_parser.ExtractArgsWithContext(ctx, scope, args, arg)
    +				if err != nil {
    +					scope.Log("verify: %v", err)
    +					return vfilter.Null{}
    +				}
    +
    +				config_obj, ok := vql_subsystem.GetServerConfig(scope)
    +				if !ok {
    +					scope.Log("verify: Must run on the server")
    +					return vfilter.Null{}
    +				}
    +
    +				manager, err := services.GetRepositoryManager(config_obj)
    +				if err != nil {
    +					return err
    +				}
    +
    +				repository, err := manager.GetGlobalRepository(config_obj)
    +				if err != nil {
    +					return err
    +				}
    +
    +				state := launcher.NewAnalysisState(arg.Artifact)
    +
    +				artifact, pres := repository.Get(ctx, config_obj, arg.Artifact)
    +				if !pres {
    +					local_repository := manager.NewRepository()
    +					local_repository.SetParent(repository, config_obj)
    +
    +					artifact, err = local_repository.LoadYaml(arg.Artifact,
    +						services.ArtifactOptions{
    +							ValidateArtifact:     true,
    +							ArtifactIsBuiltIn:    true,
    +							AllowOverridingAlias: true,
    +						})
    +					if err != nil {
    +						state.SetError(err)
    +						return state
    +					}
    +
    +					repository = local_repository
    +				}
    +
    +				// Verify the artifact
    +				launcher.VerifyArtifact(
    +					ctx, config_obj, repository, artifact, state)
    +
    +				return state
    +			},
    +		})
    +}
    
  • vql/parsers/pst_parser.go+2 2 modified
    @@ -1,5 +1,5 @@
    -//go:build !linux && !386
    -// +build !linux,!386
    +//go:build !386
    +// +build !386
     
     package parsers
     
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

7

News mentions

0

No linked articles in our index yet.