Skip to content

Commit

Permalink
Add kolide_softwareupdate table
Browse files Browse the repository at this point in the history
  • Loading branch information
RebeccaMahany committed Apr 10, 2023
1 parent 6380a0c commit 31eb41f
Show file tree
Hide file tree
Showing 12 changed files with 276 additions and 0 deletions.
2 changes: 2 additions & 0 deletions pkg/osquery/table/platform_tables_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/kolide/launcher/pkg/osquery/tables/apple_silicon_security_policy"
"github.com/kolide/launcher/pkg/osquery/tables/dataflattentable"
"github.com/kolide/launcher/pkg/osquery/tables/execparsers/remotectl"
"github.com/kolide/launcher/pkg/osquery/tables/execparsers/softwareupdate"
"github.com/kolide/launcher/pkg/osquery/tables/filevault"
"github.com/kolide/launcher/pkg/osquery/tables/firmwarepasswd"
"github.com/kolide/launcher/pkg/osquery/tables/ioreg"
Expand Down Expand Up @@ -116,5 +117,6 @@ func platformTables(client *osquery.ExtensionManagerClient, logger log.Logger, c
munki.ManagedInstalls(client, logger),
munki.MunkiReport(client, logger),
dataflattentable.NewExecAndParseTable(logger, "kolide_remotectl", remotectl.Parser, []string{`/usr/libexec/remotectl`, `dumpstate`}),
dataflattentable.NewExecAndParseTable(logger, "kolide_softwareupdate", softwareupdate.Parser, []string{`/usr/sbin/softwareupdate`, `--list`, `--no-scan`}),
}
}
62 changes: 62 additions & 0 deletions pkg/osquery/tables/execparsers/softwareupdate/parse.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
//go:build darwin
// +build darwin

package softwareupdate

import (
"bufio"
"fmt"
"io"
"strings"
)

func (p *parser) parseSoftwareupdate(reader io.Reader) (any, error) {
results := make([]map[string]string, 0)

p.scanner = bufio.NewScanner(reader)
for p.scanner.Scan() {
currentLine := strings.TrimSpace(p.scanner.Text())

// There are some header lines (e.g. `Software Update Tool`) that we can safely discard.
// We only care about pairs of lines, where the first line begins in the following way.
if !strings.HasPrefix(currentLine, "* Label:") {
continue
}

// Software updates are listed in the following format:
// * Label: <title>
// Title: <title>, Version: <version>, Size: <size>, Recommended: YES|?, Action: <action>,
label := strings.TrimSpace(strings.TrimPrefix(currentLine, "* Label:"))
labelAttributes, err := p.parseUpdate(label)
if err != nil {
return results, fmt.Errorf("could not parse software update data for label %s: %w", label, err)
}

results = append(results, labelAttributes)
}

return results, nil
}

func (p *parser) parseUpdate(label string) (map[string]string, error) {
result := make(map[string]string)
result["Label"] = label

// Get the next line
if !p.scanner.Scan() {
return result, fmt.Errorf("software update data missing for label %s", label)
}
updateDataStr := strings.TrimSuffix(strings.TrimSpace(p.scanner.Text()), ",")

// Add each update attribute to the result
updateData := strings.Split(updateDataStr, ",")
for _, attr := range updateData {
keyValPair := strings.SplitN(attr, ":", 2)
if len(keyValPair) < 2 {
return result, fmt.Errorf("software update data has malformed attribute %s", attr)
}
result[strings.TrimSpace(keyValPair[0])] = strings.TrimSpace(keyValPair[1])
}

return result, nil
}
149 changes: 149 additions & 0 deletions pkg/osquery/tables/execparsers/softwareupdate/parse_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
package softwareupdate

import (
"bytes"
_ "embed"
"testing"

"github.com/stretchr/testify/require"
)

//go:embed test-data/beta-update-available-noscan.txt
var beta_update_available_noscan []byte

//go:embed test-data/beta-update-available-scan.txt
var beta_update_available_scan []byte

//go:embed test-data/error-scan.txt
var error_scan []byte

//go:embed test-data/multiple-updates-available-noscan.txt
var multiple_updates_available_noscan []byte

//go:embed test-data/no-update-available-noscan.txt
var no_update_available_noscan []byte

//go:embed test-data/no-update-available-scan.txt
var no_update_available_scan []byte

//go:embed test-data/update-available-noscan.txt
var update_available_noscan []byte

//go:embed test-data/update-available-scan.txt
var update_available_scan []byte

func TestParse(t *testing.T) {
t.Parallel()

var tests = []struct {
name string
input []byte
expected []map[string]string
}{
{
name: "beta update available, --no-scan",
input: beta_update_available_noscan,
expected: []map[string]string{
{
"Label": "macOS Ventura 13.3 Beta 3-22E5236f",
"Title": "macOS Ventura 13.3 Beta 3",
"Version": "13.3",
"Size": "3310848K",
"Recommended": "YES",
"Action": "restart",
},
},
},
{
name: "beta update available",
input: beta_update_available_scan,
expected: []map[string]string{
{
"Label": "macOS Ventura 13.3 Beta 3-22E5236f",
"Title": "macOS Ventura 13.3 Beta 3",
"Version": "13.3",
"Size": "3310848K",
"Recommended": "YES",
"Action": "restart",
},
},
},
{
name: "error when scanning",
input: error_scan,
expected: make([]map[string]string, 0),
},
{
name: "multiple updates available, --no-scan",
input: multiple_updates_available_noscan,
expected: []map[string]string{
{
"Label": "Command Line Tools for Xcode-14.3",
"Title": "Command Line Tools for Xcode",
"Version": "14.3",
"Size": "711888KiB",
"Recommended": "YES",
},
{
"Label": "macOS Ventura 13.4 Beta-22F5027f",
"Title": "macOS Ventura 13.4 Beta",
"Version": "13.4",
"Size": "11487824K",
"Recommended": "YES",
"Action": "restart",
},
},
},
{
name: "no update available, --no-scan",
input: no_update_available_noscan,
expected: make([]map[string]string, 0),
},
{
name: "no update available",
input: no_update_available_scan,
expected: make([]map[string]string, 0),
},
{
name: "update available, --no-scan",
input: update_available_noscan,
expected: []map[string]string{
{
"Label": "macOS Ventura 13.3.1-22E261",
"Title": "macOS Ventura 13.3.1",
"Version": "13.3.1",
"Size": "868648KiB",
"Recommended": "YES",
"Action": "restart",
},
},
},
{
name: "update available",
input: update_available_scan,
expected: []map[string]string{
{
"Label": "macOS Ventura 13.3.1-22E261",
"Title": "macOS Ventura 13.3.1",
"Version": "13.3.1",
"Size": "868648KiB",
"Recommended": "YES",
"Action": "restart",
},
},
},
}

for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
})

p := New()
result, err := p.Parse(bytes.NewReader(tt.input))
require.NoError(t, err, "unexpected error parsing input")

require.ElementsMatch(t, tt.expected, result)
}
}
23 changes: 23 additions & 0 deletions pkg/osquery/tables/execparsers/softwareupdate/softwareupdate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//go:build darwin
// +build darwin

package softwareupdate

import (
"bufio"
"io"
)

type parser struct {
scanner *bufio.Scanner
}

var Parser = New()

func New() *parser {
return &parser{}
}

func (p *parser) Parse(reader io.Reader) (any, error) {
return p.parseSoftwareupdate(reader)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Software Update Tool

Software Update found the following new or updated software:
* Label: macOS Ventura 13.3 Beta 3-22E5236f
Title: macOS Ventura 13.3 Beta 3, Version: 13.3, Size: 3310848K, Recommended: YES, Action: restart,
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

Software Update Tool

Finding available software
Software Update found the following new or updated software:
* Label: macOS Ventura 13.3 Beta 3-22E5236f
Title: macOS Ventura 13.3 Beta 3, Version: 13.3, Size: 3310848K, Recommended: YES, Action: restart,
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Software Update Tool

Scan finished with error: Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." UserInfo={_kCFStreamErrorDomainKey=1, NSLocalizedRecoverySuggestion=Make sure you're connected to the Internet, and then try again., NSLocalizedDescription=The network connection was lost., SUErrorRelatedCode=SUErrorCodeScanCatalogNotFound, NSErrorFailingURLStringKey=https://swscan.apple.com/content/catalogs/others/index-13-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz, NSErrorFailingURLKey=https://swscan.apple.com/content/catalogs/others/index-13-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz, _kCFStreamErrorCodeKey=57}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Software Update Tool

Software Update found the following new or updated software:
* Label: Command Line Tools for Xcode-14.3
Title: Command Line Tools for Xcode, Version: 14.3, Size: 711888KiB, Recommended: YES,
* Label: macOS Ventura 13.4 Beta-22F5027f
Title: macOS Ventura 13.4 Beta, Version: 13.4, Size: 11487824K, Recommended: YES, Action: restart,
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Software Update Tool

No new software available.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Software Update Tool

Finding available software
No new software available.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Software Update Tool

Software Update found the following new or updated software:
* Label: macOS Ventura 13.3.1-22E261
Title: macOS Ventura 13.3.1, Version: 13.3.1, Size: 868648KiB, Recommended: YES, Action: restart,
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Software Update Tool

Finding available software
Software Update found the following new or updated software:
* Label: macOS Ventura 13.3.1-22E261
Title: macOS Ventura 13.3.1, Version: 13.3.1, Size: 868648KiB, Recommended: YES, Action: restart,

0 comments on commit 31eb41f

Please sign in to comment.