2016-09-26 18:48:55 +00:00
|
|
|
package service
|
2016-09-04 05:13:42 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
2016-09-06 21:28:07 +00:00
|
|
|
"net/http"
|
2016-09-04 05:13:42 +00:00
|
|
|
|
2016-09-29 04:21:39 +00:00
|
|
|
hostctx "github.com/kolide/kolide-ose/server/contexts/host"
|
2016-09-26 18:48:55 +00:00
|
|
|
"github.com/kolide/kolide-ose/server/errors"
|
|
|
|
"github.com/kolide/kolide-ose/server/kolide"
|
2016-09-04 05:13:42 +00:00
|
|
|
"golang.org/x/net/context"
|
|
|
|
)
|
|
|
|
|
2016-09-21 03:08:11 +00:00
|
|
|
type osqueryError struct {
|
2016-09-29 04:21:39 +00:00
|
|
|
message string
|
|
|
|
nodeInvalid bool
|
2016-09-21 03:08:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (e osqueryError) Error() string {
|
|
|
|
return e.message
|
|
|
|
}
|
|
|
|
|
2016-09-29 04:21:39 +00:00
|
|
|
func (e osqueryError) NodeInvalid() bool {
|
|
|
|
return e.nodeInvalid
|
|
|
|
}
|
|
|
|
|
|
|
|
func (svc service) AuthenticateHost(ctx context.Context, nodeKey string) (*kolide.Host, error) {
|
|
|
|
if nodeKey == "" {
|
|
|
|
return nil, osqueryError{
|
|
|
|
message: "authentication error: missing node key",
|
|
|
|
nodeInvalid: true,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
host, err := svc.ds.AuthenticateHost(nodeKey)
|
|
|
|
if err != nil {
|
|
|
|
return nil, osqueryError{
|
|
|
|
message: "authentication error: " + err.Error(),
|
|
|
|
nodeInvalid: true,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return host, nil
|
|
|
|
}
|
|
|
|
|
2016-09-04 05:13:42 +00:00
|
|
|
func (svc service) EnrollAgent(ctx context.Context, enrollSecret, hostIdentifier string) (string, error) {
|
2016-09-14 16:11:06 +00:00
|
|
|
if enrollSecret != svc.config.Osquery.EnrollSecret {
|
2016-09-29 04:21:39 +00:00
|
|
|
return "", osqueryError{message: "invalid enroll secret", nodeInvalid: true}
|
2016-09-04 05:13:42 +00:00
|
|
|
}
|
|
|
|
|
2016-09-14 16:11:06 +00:00
|
|
|
host, err := svc.ds.EnrollHost(hostIdentifier, "", "", "", svc.config.Osquery.NodeKeySize)
|
2016-09-04 05:13:42 +00:00
|
|
|
if err != nil {
|
2016-09-29 04:21:39 +00:00
|
|
|
return "", osqueryError{message: "enrollment failed: " + err.Error(), nodeInvalid: true}
|
2016-09-04 05:13:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return host.NodeKey, nil
|
|
|
|
}
|
|
|
|
|
2016-09-29 04:21:39 +00:00
|
|
|
func (svc service) GetClientConfig(ctx context.Context) (*kolide.OsqueryConfig, error) {
|
2016-09-06 21:28:07 +00:00
|
|
|
var config kolide.OsqueryConfig
|
2016-09-19 23:11:39 +00:00
|
|
|
return &config, nil
|
2016-09-04 05:13:42 +00:00
|
|
|
}
|
|
|
|
|
2016-09-29 04:21:39 +00:00
|
|
|
func (svc service) SubmitStatusLogs(ctx context.Context, logs []kolide.OsqueryStatusLog) error {
|
2016-10-01 02:18:27 +00:00
|
|
|
host, ok := hostctx.FromContext(ctx)
|
|
|
|
if !ok {
|
|
|
|
return osqueryError{message: "internal error: missing host from request context"}
|
|
|
|
}
|
|
|
|
|
2016-09-06 21:28:07 +00:00
|
|
|
for _, log := range logs {
|
|
|
|
err := json.NewEncoder(svc.osqueryStatusLogWriter).Encode(log)
|
|
|
|
if err != nil {
|
|
|
|
return errors.NewFromError(err, http.StatusInternalServerError, "error writing status log")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-01 02:18:27 +00:00
|
|
|
err := svc.ds.MarkHostSeen(&host, svc.clock.Now())
|
|
|
|
if err != nil {
|
|
|
|
return osqueryError{message: "failed to update host seen: " + err.Error()}
|
2016-09-06 21:28:07 +00:00
|
|
|
}
|
2016-10-01 02:18:27 +00:00
|
|
|
|
2016-09-04 05:13:42 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2016-10-01 02:18:27 +00:00
|
|
|
func (svc service) SubmitResultLogs(ctx context.Context, logs []kolide.OsqueryResultLog) error {
|
2016-09-29 04:21:39 +00:00
|
|
|
host, ok := hostctx.FromContext(ctx)
|
|
|
|
if !ok {
|
|
|
|
return osqueryError{message: "internal error: missing host from request context"}
|
|
|
|
}
|
|
|
|
|
2016-10-01 02:18:27 +00:00
|
|
|
for _, log := range logs {
|
|
|
|
err := json.NewEncoder(svc.osqueryResultLogWriter).Encode(log)
|
|
|
|
if err != nil {
|
|
|
|
return errors.NewFromError(err, http.StatusInternalServerError, "error writing result log")
|
|
|
|
}
|
2016-09-29 04:21:39 +00:00
|
|
|
}
|
|
|
|
|
2016-10-01 02:18:27 +00:00
|
|
|
err := svc.ds.MarkHostSeen(&host, svc.clock.Now())
|
2016-09-29 04:21:39 +00:00
|
|
|
if err != nil {
|
2016-10-01 02:18:27 +00:00
|
|
|
return osqueryError{message: "failed to update host seen: " + err.Error()}
|
2016-09-29 04:21:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2016-09-21 03:08:11 +00:00
|
|
|
// hostLabelQueryPrefix is appended before the query name when a query is
|
|
|
|
// provided as a label query. This allows the results to be retrieved when
|
|
|
|
// osqueryd writes the distributed query results.
|
|
|
|
const hostLabelQueryPrefix = "kolide_label_query_"
|
|
|
|
|
|
|
|
// hostDetailQueryPrefix is appended before the query name when a query is
|
|
|
|
// provided as a detail query.
|
|
|
|
const hostDetailQueryPrefix = "kolide_detail_query_"
|
|
|
|
|
|
|
|
// hostDetailQueries returns the map of queries that should be executed by
|
|
|
|
// osqueryd to fill in the host details
|
|
|
|
func hostDetailQueries(host kolide.Host) map[string]string {
|
|
|
|
queries := make(map[string]string)
|
|
|
|
if host.Platform == "" {
|
|
|
|
queries[hostDetailQueryPrefix+"platform"] = "select build_platform from osquery_info;"
|
|
|
|
}
|
|
|
|
return queries
|
|
|
|
}
|
|
|
|
|
2016-09-04 05:13:42 +00:00
|
|
|
func (svc service) GetDistributedQueries(ctx context.Context) (map[string]string, error) {
|
2016-09-21 03:08:11 +00:00
|
|
|
queries := make(map[string]string)
|
|
|
|
|
2016-09-29 04:21:39 +00:00
|
|
|
host, ok := hostctx.FromContext(ctx)
|
2016-09-26 17:14:39 +00:00
|
|
|
if !ok {
|
2016-09-29 04:21:39 +00:00
|
|
|
return nil, osqueryError{message: "internal error: missing host from request context"}
|
2016-09-21 03:08:11 +00:00
|
|
|
}
|
|
|
|
|
2016-09-26 17:14:39 +00:00
|
|
|
queries = hostDetailQueries(host)
|
2016-09-21 03:08:11 +00:00
|
|
|
if len(queries) > 0 {
|
|
|
|
// If the host details need to be updated, we should do so
|
|
|
|
// before checking for any other queries
|
|
|
|
return queries, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Retrieve the label queries that should be updated
|
|
|
|
cutoff := svc.clock.Now().Add(-svc.config.Osquery.LabelUpdateInterval)
|
2016-09-26 17:14:39 +00:00
|
|
|
labelQueries, err := svc.ds.LabelQueriesForHost(&host, cutoff)
|
2016-09-21 03:08:11 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
for name, query := range labelQueries {
|
|
|
|
queries[hostLabelQueryPrefix+name] = query
|
|
|
|
}
|
2016-09-04 05:13:42 +00:00
|
|
|
|
2016-09-21 03:08:11 +00:00
|
|
|
// TODO: retrieve the active distributed queries for this host
|
2016-09-04 05:13:42 +00:00
|
|
|
|
|
|
|
return queries, nil
|
|
|
|
}
|
|
|
|
|
2016-09-06 21:28:07 +00:00
|
|
|
func (svc service) SubmitDistributedQueryResults(ctx context.Context, results kolide.OsqueryDistributedQueryResults) error {
|
2016-09-04 05:13:42 +00:00
|
|
|
return nil
|
|
|
|
}
|