Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hidding API queries #31

Merged
merged 1 commit into from
Nov 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/admin/templates/queries-logs.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
<i class="fas fa-hourglass-half"></i> [ <b>ACTIVE</b> ] - Results for {{ .Name }}
{{ end }}
{{ if $template.ResultsLink }}
- <a href="{{ $template.ResultsLink }}" _target="_blank"><i class="fas fa-external-link-alt"></i></a>
- <a href="{{ $template.ResultsLink }}" target="_blank"><i class="fas fa-external-link-alt"></i></a>
{{ end }}
<div class="card-header-actions">
<button class="btn btn-sm btn-outline-primary" data-tooltip="true"
Expand Down
29 changes: 26 additions & 3 deletions cmd/api/handlers-queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ func apiQueriesRunHandler(w http.ResponseWriter, r *http.Request) {
Active: true,
Completed: false,
Deleted: false,
Hidden: true,
Type: queries.StandardQueryType,
}
if err := queriesmgr.Create(newQuery); err != nil {
Expand Down Expand Up @@ -164,12 +165,34 @@ func apiQueriesRunHandler(w http.ResponseWriter, r *http.Request) {
incMetric(metricAPIOK)
}

// GET Handler to return multiple queries in JSON
func apiQueriesShowHandler(w http.ResponseWriter, r *http.Request) {
// GET Handler to return all queries in JSON
func apiAllQueriesShowHandler(w http.ResponseWriter, r *http.Request) {
incMetric(metricAPIReq)
utils.DebugHTTPDump(r, settingsmgr.DebugHTTP(settings.ServiceAPI), false)
// Get queries
queries, err := queriesmgr.GetQueries(queries.TargetAll)
queries, err := queriesmgr.GetQueries(queries.TargetCompleted)
if err != nil {
incMetric(metricAPIErr)
apiErrorResponse(w, "error getting queries", http.StatusInternalServerError, err)
return
}
if len(queries) == 0 {
incMetric(metricAPIErr)
log.Printf("no queries")
apiErrorResponse(w, "no queries", http.StatusNotFound, nil)
return
}
// Serialize and serve JSON
apiHTTPResponse(w, JSONApplicationUTF8, http.StatusOK, queries)
incMetric(metricAPIOK)
}

// GET Handler to return hidden queries in JSON
func apiHiddenQueriesShowHandler(w http.ResponseWriter, r *http.Request) {
incMetric(metricAPIReq)
utils.DebugHTTPDump(r, settingsmgr.DebugHTTP(settings.ServiceAPI), false)
// Get queries
queries, err := queriesmgr.GetQueries(queries.TargetHiddenCompleted)
if err != nil {
incMetric(metricAPIErr)
apiErrorResponse(w, "error getting queries", http.StatusInternalServerError, err)
Expand Down
8 changes: 6 additions & 2 deletions cmd/api/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ const (
apiNodesPath string = "/nodes"
// API queries path
apiQueriesPath string = "/queries"
// API all queries path
apiAllQueriesPath string = "/all-queries"
// API carves path
apiCarvesPath string = "/carves"
// API platforms path
Expand Down Expand Up @@ -219,10 +221,12 @@ func main() {
routerAPI.Handle(_apiPath(apiQueriesPath)+"/{name}/", handlerAuthCheck(http.HandlerFunc(apiQueryShowHandler))).Methods("GET")
routerAPI.Handle(_apiPath(apiQueriesPath), handlerAuthCheck(http.HandlerFunc(apiQueriesRunHandler))).Methods("POST")
routerAPI.Handle(_apiPath(apiQueriesPath)+"/", handlerAuthCheck(http.HandlerFunc(apiQueriesRunHandler))).Methods("POST")
routerAPI.Handle(_apiPath(apiQueriesPath), handlerAuthCheck(http.HandlerFunc(apiQueriesShowHandler))).Methods("GET")
routerAPI.Handle(_apiPath(apiQueriesPath)+"/", handlerAuthCheck(http.HandlerFunc(apiQueriesShowHandler))).Methods("GET")
routerAPI.Handle(_apiPath(apiQueriesPath), handlerAuthCheck(http.HandlerFunc(apiHiddenQueriesShowHandler))).Methods("GET")
routerAPI.Handle(_apiPath(apiQueriesPath)+"/", handlerAuthCheck(http.HandlerFunc(apiHiddenQueriesShowHandler))).Methods("GET")
routerAPI.Handle(_apiPath(apiQueriesPath)+"/results/{name}", handlerAuthCheck(http.HandlerFunc(apiQueryResultsHandler))).Methods("GET")
routerAPI.Handle(_apiPath(apiQueriesPath)+"/results/{name}/", handlerAuthCheck(http.HandlerFunc(apiQueryResultsHandler))).Methods("GET")
routerAPI.Handle(_apiPath(apiAllQueriesPath), handlerAuthCheck(http.HandlerFunc(apiAllQueriesShowHandler))).Methods("GET")
routerAPI.Handle(_apiPath(apiAllQueriesPath)+"/", handlerAuthCheck(http.HandlerFunc(apiAllQueriesShowHandler))).Methods("GET")
// API: platforms
routerAPI.Handle(_apiPath(apiPlatformsPath), handlerAuthCheck(http.HandlerFunc(apiPlatformsHandler))).Methods("GET")
routerAPI.Handle(_apiPath(apiPlatformsPath)+"/", handlerAuthCheck(http.HandlerFunc(apiPlatformsHandler))).Methods("GET")
Expand Down
2 changes: 1 addition & 1 deletion cmd/tls/handlers-tls.go
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ func queryReadHandler(w http.ResponseWriter, r *http.Request) {
// Prepare response and serialize queries
if accelerate {
sAccelerate := int(settingsmap[settings.AcceleratedSeconds].Integer)
response, err = json.Marshal(types.AcceleratedQueryReadResponse{Queries: qs, Accelerated: sAccelerate, NodeInvalid: nodeInvalid})
response, err = json.Marshal(types.AcceleratedQueryReadResponse{Queries: qs, Accelerate: sAccelerate, NodeInvalid: nodeInvalid})
} else {
response, err = json.Marshal(types.QueryReadResponse{Queries: qs, NodeInvalid: nodeInvalid})
}
Expand Down
47 changes: 42 additions & 5 deletions pkg/queries/queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,22 @@ const (
)

const (
// TargetAll for all queries
// TargetAll for all queries but hidden
TargetAll string = "all"
// TargetAllFull for all queries including hidden ones
TargetAllFull string = "all-full"
// TargetActive for active queries
TargetActive string = "active"
// TargetHiddenActive for hidden active queries
TargetHiddenActive string = "hidden-active"
// TargetCompleted for completed queries
TargetCompleted string = "completed"
// TargetHiddenCompleted for hidden completed queries
TargetHiddenCompleted string = "hidden-completed"
// TargetDeleted for deleted queries
TargetDeleted string = "deleted"
// TargetHidden for hidden queries
TargetHidden string = "hidden"
)

// DistributedQuery as abstraction of a distributed query
Expand Down Expand Up @@ -133,7 +139,7 @@ func (q *Queries) NodeQueries(node nodes.OsqueryNode) (QueryReadQueries, bool, e
return qs, acelerate, nil
}

// Gets all queries by target (active/completed/all/all-full/deleted)
// Gets all queries by target (active/completed/all/all-full/deleted/hidden)
func (q *Queries) Gets(target, qtype string) ([]DistributedQuery, error) {
var queries []DistributedQuery
switch target {
Expand All @@ -145,8 +151,12 @@ func (q *Queries) Gets(target, qtype string) ([]DistributedQuery, error) {
if err := q.DB.Where("active = ? AND completed = ? AND deleted = ? AND type = ?", false, true, false, qtype).Find(&queries).Error; err != nil {
return queries, err
}
case TargetHiddenCompleted:
if err := q.DB.Where("active = ? AND completed = ? AND deleted = ? AND hidden = ? AND type = ?", false, true, false, true, qtype).Find(&queries).Error; err != nil {
return queries, err
}
case TargetAllFull:
if err := q.DB.Where("deleted = ? AND hidden = ? AND type = ?", false, true, qtype).Find(&queries).Error; err != nil {
if err := q.DB.Where("deleted = ? AND type = ?", false, qtype).Find(&queries).Error; err != nil {
return queries, err
}
case TargetAll:
Expand All @@ -157,6 +167,10 @@ func (q *Queries) Gets(target, qtype string) ([]DistributedQuery, error) {
if err := q.DB.Where("deleted = ? AND type = ?", true, qtype).Find(&queries).Error; err != nil {
return queries, err
}
case TargetHidden:
if err := q.DB.Where("deleted = ? AND hidden = ? AND type = ?", false, true, qtype).Find(&queries).Error; err != nil {
return queries, err
}
}
return queries, nil
}
Expand All @@ -170,12 +184,12 @@ func (q *Queries) GetActive() ([]DistributedQuery, error) {
return queries, nil
}

// GetQueries all queries by target (active/completed/all/all-full/deleted)
// GetQueries all queries by target (active/completed/all/all-full/deleted/hidden)
func (q *Queries) GetQueries(target string) ([]DistributedQuery, error) {
return q.Gets(target, StandardQueryType)
}

// GetCarves all carve queries by target (active/completed/all/all-full/deleted)
// GetCarves all carve queries by target (active/completed/all/all-full/deleted/hidden)
func (q *Queries) GetCarves(target string) ([]DistributedQuery, error) {
return q.Gets(target, CarveQueryType)
}
Expand Down Expand Up @@ -336,3 +350,26 @@ func (q *Queries) TrackExecution(name, uuid string, result int) error {
}
return nil
}

// Helper to decide whether if the query targets apply to a give node
func isQueryTarget(node nodes.OsqueryNode, targets []DistributedQueryTarget) bool {
for _, t := range targets {
// Check for environment match
if t.Type == QueryTargetEnvironment && t.Value == node.Environment {
return true
}
// Check for platform match
if t.Type == QueryTargetPlatform && node.Platform == t.Value {
return true
}
// Check for UUID match
if t.Type == QueryTargetUUID && node.UUID == t.Value {
return true
}
// Check for localname match
if t.Type == QueryTargetLocalname && node.Localname == t.Value {
return true
}
}
return false
}
28 changes: 0 additions & 28 deletions pkg/queries/utils.go

This file was deleted.

2 changes: 1 addition & 1 deletion pkg/types/osquery.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ type QueryReadResponse struct {
type AcceleratedQueryReadResponse struct {
Queries queries.QueryReadQueries `json:"queries"`
NodeInvalid bool `json:"node_invalid"`
Accelerated int `json:"accelerated"`
Accelerate int `json:"accelerate"`
}

// QueryWriteQueries to hold the on-demand queries results
Expand Down