diff --git a/cmd/launcher/interactive.go b/cmd/launcher/interactive.go index ec98b13cd..2b69cea44 100644 --- a/cmd/launcher/interactive.go +++ b/cmd/launcher/interactive.go @@ -8,7 +8,7 @@ import ( "os" "strings" - "github.com/go-kit/kit/log" + "github.com/kolide/kit/logutil" "github.com/kolide/launcher/cmd/launcher/internal" "github.com/kolide/launcher/ee/agent" "github.com/kolide/launcher/ee/tuf" @@ -20,11 +20,8 @@ import ( func runInteractive(args []string) error { flagset := flag.NewFlagSet("interactive", flag.ExitOnError) var ( - flOsquerydPath = flagset.String( - "osqueryd_path", - "", - "The path to the oqueryd binary", - ) + flDebug = flagset.Bool("debug", false, "enable debug logging") + flOsquerydPath = flagset.String("osqueryd_path", "", "The path to the oqueryd binary") flOsqueryFlags launcher.ArrayFlags ) @@ -35,9 +32,11 @@ func runInteractive(args []string) error { return err } + logger := logutil.NewServerLogger(*flDebug) + osquerydPath := *flOsquerydPath if osquerydPath == "" { - latestOsquerydBinary, err := tuf.CheckOutLatestWithoutConfig("osqueryd", log.NewNopLogger()) + latestOsquerydBinary, err := tuf.CheckOutLatestWithoutConfig("osqueryd", logger) if err != nil { osquerydPath = launcher.FindOsquery() if osquerydPath == "" { @@ -81,7 +80,7 @@ func runInteractive(args []string) error { flOsqueryFlags = append(flOsqueryFlags, fmt.Sprintf("tls_server_certs=%s", certs)) } - osqueryProc, extensionsServer, err := interactive.StartProcess(rootDir, osquerydPath, flOsqueryFlags) + osqueryProc, extensionsServer, err := interactive.StartProcess(logger, rootDir, osquerydPath, flOsqueryFlags) if err != nil { return fmt.Errorf("error starting osqueryd: %s", err) } diff --git a/pkg/osquery/table/spotlight.go b/ee/tables/spotlight/spotlight.go similarity index 53% rename from pkg/osquery/table/spotlight.go rename to ee/tables/spotlight/spotlight.go index d834d8f06..7197a7561 100644 --- a/pkg/osquery/table/spotlight.go +++ b/ee/tables/spotlight/spotlight.go @@ -1,38 +1,54 @@ //go:build darwin // +build darwin -package table +package spotlight import ( + "bufio" + "bytes" "context" "errors" "fmt" + "io" "strings" + "github.com/go-kit/kit/log" + "github.com/kolide/launcher/ee/allowedcmd" + "github.com/kolide/launcher/ee/tables/tablehelpers" "github.com/osquery/osquery-go/plugin/table" ) +type spotlightTable struct { + logger log.Logger +} + /* Spotlight returns a macOS spotlight table Example Query: SELECT uid, f.path FROM file - AS f JOIN spotlight ON spotlight.path = f.path + AS f JOIN kolide_spotlight ON spotlight.path = f.path AND spotlight.query = "kMDItemKint = 'Agile Keychain'"; */ -func Spotlight() *table.Plugin { +func TablePlugin(logger log.Logger) *table.Plugin { columns := []table.ColumnDefinition{ table.TextColumn("query"), table.TextColumn("path"), } - return table.NewPlugin("kolide_spotlight", columns, generateSpotlight) + + t := &spotlightTable{ + logger: logger, + } + + return table.NewPlugin("kolide_spotlight", columns, t.generate) } -func generateSpotlight(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) { +func (t *spotlightTable) generate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) { q, ok := queryContext.Constraints["query"] if !ok || len(q.Constraints) == 0 { return nil, errors.New("The spotlight table requires that you specify a constraint WHERE query =") } + where := q.Constraints[0].Expression var query []string if strings.Contains(where, "-") { @@ -40,16 +56,28 @@ func generateSpotlight(ctx context.Context, queryContext table.QueryContext) ([] } else { query = []string{where} } - lines, err := mdfind(query...) + + out, err := tablehelpers.Exec(ctx, t.logger, 120, allowedcmd.Mdfind, query, false) if err != nil { return nil, fmt.Errorf("call mdfind: %w", err) } + var resp []map[string]string - for _, line := range lines { + + lr := bufio.NewReader(bytes.NewReader(out)) + for { + line, _, err := lr.ReadLine() + if err == io.EOF { + break + } + if err != nil { + return nil, err + } m := make(map[string]string, 2) m["query"] = where - m["path"] = line + m["path"] = string(line) resp = append(resp, m) } + return resp, nil } diff --git a/pkg/osquery/interactive/interactive.go b/pkg/osquery/interactive/interactive.go index e93089f8d..ec198b497 100644 --- a/pkg/osquery/interactive/interactive.go +++ b/pkg/osquery/interactive/interactive.go @@ -17,7 +17,7 @@ import ( const extensionName = "com.kolide.launcher_interactive" -func StartProcess(rootDir, osquerydPath string, osqueryFlags []string) (*os.Process, *osquery.ExtensionManagerServer, error) { +func StartProcess(logger log.Logger, rootDir, osquerydPath string, osqueryFlags []string) (*os.Process, *osquery.ExtensionManagerServer, error) { if err := os.MkdirAll(rootDir, fsutil.DirMode); err != nil { return nil, nil, fmt.Errorf("creating root dir for interactive mode: %w", err) @@ -58,7 +58,7 @@ func StartProcess(rootDir, osquerydPath string, osqueryFlags []string) (*os.Proc return nil, nil, fmt.Errorf("error waiting for osquery to create socket: %w", err) } - extensionServer, err := loadExtensions(socketPath, osquerydPath) + extensionServer, err := loadExtensions(logger, socketPath, osquerydPath) if err != nil { err = fmt.Errorf("error loading extensions: %w", err) @@ -100,7 +100,7 @@ func buildOsqueryFlags(socketPath, augeasLensesPath string, osqueryFlags []strin return flags } -func loadExtensions(socketPath string, osquerydPath string) (*osquery.ExtensionManagerServer, error) { +func loadExtensions(logger log.Logger, socketPath string, osquerydPath string) (*osquery.ExtensionManagerServer, error) { client, err := osquery.NewClient(socketPath, 10*time.Second, osquery.MaxWaitTime(10*time.Second)) if err != nil { return nil, fmt.Errorf("error creating osquery client: %w", err) @@ -117,7 +117,7 @@ func loadExtensions(socketPath string, osquerydPath string) (*osquery.ExtensionM return extensionManagerServer, fmt.Errorf("error creating extension manager server: %w", err) } - extensionManagerServer.RegisterPlugin(table.PlatformTables(log.NewNopLogger(), osquerydPath)...) + extensionManagerServer.RegisterPlugin(table.PlatformTables(logger, osquerydPath)...) if err := extensionManagerServer.Start(); err != nil { return nil, fmt.Errorf("error starting extension manager server: %w", err) diff --git a/pkg/osquery/interactive/interactive_test.go b/pkg/osquery/interactive/interactive_test.go index f7d1ec610..40d677653 100644 --- a/pkg/osquery/interactive/interactive_test.go +++ b/pkg/osquery/interactive/interactive_test.go @@ -14,6 +14,7 @@ import ( "runtime" "testing" + "github.com/go-kit/kit/log" "github.com/kolide/kit/fsutil" "github.com/kolide/launcher/pkg/packaging" "github.com/stretchr/testify/require" @@ -83,7 +84,7 @@ func TestProc(t *testing.T) { require.NoError(t, downloadOsquery(rootDir)) osquerydPath := filepath.Join(rootDir, "osqueryd") - proc, _, err := StartProcess(rootDir, osquerydPath, tt.osqueryFlags) + proc, _, err := StartProcess(log.NewNopLogger(), rootDir, osquerydPath, tt.osqueryFlags) if tt.errContainsStr != "" { require.Error(t, err) diff --git a/pkg/osquery/table/mdfind_darwin.go b/pkg/osquery/table/mdfind_darwin.go deleted file mode 100644 index 35a6a2409..000000000 --- a/pkg/osquery/table/mdfind_darwin.go +++ /dev/null @@ -1,42 +0,0 @@ -//go:build darwin || !cgo -// +build darwin !cgo - -package table - -import ( - "bufio" - "bytes" - "context" - "fmt" - "io" - "time" - - "github.com/kolide/launcher/ee/allowedcmd" -) - -func mdfind(args ...string) ([]string, error) { - ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) - defer cancel() - - cmd, err := allowedcmd.Mdfind(ctx, args...) - if err != nil { - return nil, fmt.Errorf("creating mdfind command: %w", err) - } - out, err := cmd.Output() - if err != nil { - return nil, err - } - var lines []string - lr := bufio.NewReader(bytes.NewReader(out)) - for { - line, _, err := lr.ReadLine() - if err == io.EOF { - break - } - if err != nil { - return nil, err - } - lines = append(lines, string(line)) - } - return lines, nil -} diff --git a/pkg/osquery/table/platform_tables_darwin.go b/pkg/osquery/table/platform_tables_darwin.go index 62ce78f6b..18dd444b6 100644 --- a/pkg/osquery/table/platform_tables_darwin.go +++ b/pkg/osquery/table/platform_tables_darwin.go @@ -24,6 +24,7 @@ import ( "github.com/kolide/launcher/ee/tables/osquery_user_exec_table" "github.com/kolide/launcher/ee/tables/profiles" "github.com/kolide/launcher/ee/tables/pwpolicy" + "github.com/kolide/launcher/ee/tables/spotlight" "github.com/kolide/launcher/ee/tables/systemprofiler" "github.com/kolide/launcher/ee/tables/zfs" _ "github.com/mattn/go-sqlite3" @@ -88,7 +89,7 @@ func platformSpecificTables(logger log.Logger, currentOsquerydBinaryPath string) macos_software_update.RecommendedUpdates(logger), macos_software_update.AvailableProducts(logger), MachoInfo(), - Spotlight(), + spotlight.TablePlugin(logger), TouchIDUserConfig(logger), TouchIDSystemConfig(logger), UserAvatar(logger),