Skip to content

Commit

Permalink
Verify client's key with or without the org id. (Velocidex#2192)
Browse files Browse the repository at this point in the history
Fixed a bug in the `velociraptor gui` command that made the second org
client unresponsive.

Also hide the table filtering in the Hunt Clients tab because it can
not work (Users are supposed to use the hunt cell suggestion instead).
  • Loading branch information
scudette authored Oct 27, 2022
1 parent 6f2896e commit c28c827
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 29 deletions.
35 changes: 22 additions & 13 deletions api/csv.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,19 +60,9 @@ func getTable(

file_store_factory := file_store.GetFileStore(config_obj)

options := result_sets.ResultSetOptions{}
if in.SortColumn != "" {
options.SortColumn = in.SortColumn
options.SortAsc = in.SortDirection
}

if in.FilterColumn != "" &&
in.FilterRegex != "" {
options.FilterColumn = in.FilterColumn
options.FilterRegex, err = regexp.Compile("(?i)" + in.FilterRegex)
if err != nil {
return nil, err
}
options, err := getTableOptions(in)
if err != nil {
return result, err
}

rs_reader, err := result_sets.NewResultSetReaderWithOptions(
Expand Down Expand Up @@ -345,3 +335,22 @@ func getTimeline(

return result, nil
}

func getTableOptions(in *api_proto.GetTableRequest) (
options result_sets.ResultSetOptions, err error) {
if in.SortColumn != "" {
options.SortColumn = in.SortColumn
options.SortAsc = in.SortDirection
}

if in.FilterColumn != "" &&
in.FilterRegex != "" {
options.FilterColumn = in.FilterColumn
options.FilterRegex, err = regexp.Compile("(?i)" + in.FilterRegex)
if err != nil {
return options, err
}
}

return options, nil
}
2 changes: 1 addition & 1 deletion constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (
)

const (
VERSION = "0.6.7-dev"
VERSION = "0.6.7-rc1"
ENROLLMENT_WELL_KNOWN_FLOW = "E:Enrol"
MONITORING_WELL_KNOWN_FLOW = FLOW_PREFIX + "Monitoring"

Expand Down
18 changes: 13 additions & 5 deletions crypto/client/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ func NewCryptoManager(config_obj *config_proto.Config,
public_key_resolver PublicKeyResolver,
logger *logging.LogContext) (
*CryptoManager, error) {

private_key, err := crypto_utils.ParseRsaPrivateKeyFromPemStr(private_key_pem)
if err != nil {
return nil, err
Expand Down Expand Up @@ -182,12 +183,19 @@ func (self *CryptoManager) getAuthState(

// Verify the cipher signature using the certificate known for
// the sender.
public_key, pres := self.Resolver.GetPublicKey(config_obj, cipher_metadata.Source)
client_id := utils.ClientIdFromSource(cipher_metadata.Source)
public_key, pres := self.Resolver.GetPublicKey(
config_obj, cipher_metadata.Source)
if !pres {
// We dont know who we are talking to so we can not
// trust them.
return false,
fmt.Errorf("No cert found for %s", cipher_metadata.Source)
// Try to extract an org id from the source in case the public
// key was added without one.
public_key, pres = self.Resolver.GetPublicKey(config_obj, client_id)
if !pres {
// We dont know who we are talking to so we can not trust
// them.
return false,
fmt.Errorf("No cert found for %s", cipher_metadata.Source)
}
}

hashed := sha256.Sum256(serialized_cipher)
Expand Down
11 changes: 11 additions & 0 deletions datastore/filebased.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ import (

var (
file_based_imp = &FileBaseDataStore{}

datastoreNotConfiguredError = errors.New("Datastore not configured")
)

const (
Expand Down Expand Up @@ -294,6 +296,10 @@ func (self *FileBaseDataStore) Close() {}
func writeContentToFile(config_obj *config_proto.Config,
urn api.DSPathSpec, data []byte) error {

if config_obj.Datastore == nil {
return datastoreNotConfiguredError
}

filename := urn.AsDatastoreFilename(config_obj)
file, err := os.OpenFile(
filename, os.O_RDWR|os.O_CREATE, 0660)
Expand Down Expand Up @@ -331,6 +337,11 @@ func writeContentToFile(config_obj *config_proto.Config,
func readContentFromFile(
config_obj *config_proto.Config, urn api.DSPathSpec,
must_exist bool) ([]byte, error) {

if config_obj.Datastore == nil {
return nil, datastoreNotConfiguredError
}

file, err := os.Open(urn.AsDatastoreFilename(config_obj))
if err == nil {
defer file.Close()
Expand Down
18 changes: 11 additions & 7 deletions gui/velociraptor/src/components/core/paged-table.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ class VeloPagedTable extends Component {

translate_column_headers: PropTypes.bool,

// If set we remove the option to filter/sort the table.
no_transformations: PropTypes.bool,

// An optional toolbar that can be passed to the table.
toolbar: PropTypes.object,

Expand Down Expand Up @@ -472,13 +475,14 @@ class VeloPagedTable extends Component {
}))}>
<FontAwesomeIcon icon="file-csv"/>
</Button>
<Button variant="default"
onClick={()=>this.setState({
show_transform_dialog: true,
})}
title={T("Transform Table")}>
<FontAwesomeIcon icon="filter"/>
</Button>
{!this.props.no_transformations &&
<Button variant="default"
onClick={()=>this.setState({
show_transform_dialog: true,
})}
title={T("Transform Table")}>
<FontAwesomeIcon icon="filter"/>
</Button>}
</ButtonGroup>
{ transformed.length > 0 &&
<ButtonGroup className="float-right">
Expand Down
1 change: 1 addition & 0 deletions gui/velociraptor/src/components/hunts/hunt-clients.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export default class HuntClients extends React.Component {
renderers={renderers}
params={params}
translate_column_headers={true}
no_transformations={true}
/>
);
}
Expand Down
13 changes: 10 additions & 3 deletions services/notebook/initial.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,9 @@ LET ColumnTypes <= dict(
/*
# Flows with ERROR status
*/
SELECT ClientId, FlowId, Flow.start_time As StartedTime,
SELECT ClientId,
client_info(client_id=ClientId).os_info.hostname AS Hostname,
FlowId, Flow.start_time As StartedTime,
Flow.state AS FlowState, Flow.status as FlowStatus,
Flow.execution_duration as Duration,
Flow.total_collected_bytes as TotalBytes,
Expand All @@ -297,7 +299,9 @@ WHERE FlowState =~ 'ERROR'
/*
## Flows with RUNNING status
*/
SELECT ClientId, FlowId, Flow.start_time As StartedTime,
SELECT ClientId,
client_info(client_id=ClientId).os_info.hostname AS Hostname,
FlowId, Flow.start_time As StartedTime,
Flow.state AS FlowState, Flow.status as FlowStatus,
Flow.execution_duration as Duration,
Flow.total_collected_bytes as TotalBytes,
Expand All @@ -308,13 +312,16 @@ WHERE FlowState =~ 'RUNNING'
/*
## Flows with FINISHED status
*/
SELECT ClientId, FlowId, Flow.start_time As StartedTime,
SELECT ClientId,
client_info(client_id=ClientId).os_info.hostname AS Hostname,
FlowId, Flow.start_time As StartedTime,
Flow.state AS FlowState, Flow.status as FlowStatus,
Flow.execution_duration as Duration,
Flow.total_collected_bytes as TotalBytes,
Flow.total_collected_rows as TotalRows
FROM hunt_flows(hunt_id=HuntId)
WHERE FlowState =~ 'Finished'
LIMIT 1000
`})

return getDefaultCellsForSources(config_obj, sources, notebook_metadata)
Expand Down
5 changes: 5 additions & 0 deletions utils/orgs.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ func OrgIdFromClientId(client_id string) string {
return ""
}

func ClientIdFromSource(client_id string) string {
parts := strings.Split(client_id, "-")
return parts[0]
}

func IsRootOrg(org_id string) bool {
return org_id == "" || org_id == "root"
}
Expand Down

0 comments on commit c28c827

Please sign in to comment.