go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/providers/os/resources/packages/macos_packages.go (about)

     1  // Copyright (c) Mondoo, Inc.
     2  // SPDX-License-Identifier: BUSL-1.1
     3  
     4  package packages
     5  
     6  import (
     7  	"fmt"
     8  	"io"
     9  	"strings"
    10  
    11  	"github.com/cockroachdb/errors"
    12  	"go.mondoo.com/cnquery/providers/os/connection/shared"
    13  	plist "howett.net/plist"
    14  )
    15  
    16  const (
    17  	MacosPkgFormat = "macos"
    18  )
    19  
    20  // parse macos system version property list
    21  func ParseMacOSPackages(input io.Reader) ([]Package, error) {
    22  	var r io.ReadSeeker
    23  	r, ok := input.(io.ReadSeeker)
    24  
    25  	// if the read seaker is not implemented lets cache stdout in-memory
    26  	if !ok {
    27  		packageList, err := io.ReadAll(input)
    28  		if err != nil {
    29  			return nil, err
    30  		}
    31  		r = strings.NewReader(string(packageList))
    32  	}
    33  
    34  	type sysProfilerItems struct {
    35  		Name    string `plist:"_name"`
    36  		Version string `plist:"version"`
    37  	}
    38  
    39  	type sysProfiler struct {
    40  		Items []sysProfilerItems `plist:"_items"`
    41  	}
    42  
    43  	var data []sysProfiler
    44  	decoder := plist.NewDecoder(r)
    45  	err := decoder.Decode(&data)
    46  	if err != nil {
    47  		return nil, err
    48  	}
    49  
    50  	if len(data) != 1 {
    51  		return nil, errors.New("format not supported")
    52  	}
    53  
    54  	pkgs := make([]Package, len(data[0].Items))
    55  	for i, entry := range data[0].Items {
    56  		pkgs[i].Name = entry.Name
    57  		pkgs[i].Version = entry.Version
    58  		pkgs[i].Format = MacosPkgFormat
    59  	}
    60  
    61  	return pkgs, nil
    62  }
    63  
    64  // MacOS
    65  type MacOSPkgManager struct {
    66  	conn shared.Connection
    67  }
    68  
    69  func (mpm *MacOSPkgManager) Name() string {
    70  	return "macOS Package Manager"
    71  }
    72  
    73  func (mpm *MacOSPkgManager) Format() string {
    74  	return MacosPkgFormat
    75  }
    76  
    77  func (mpm *MacOSPkgManager) List() ([]Package, error) {
    78  	cmd, err := mpm.conn.RunCommand("system_profiler SPApplicationsDataType -xml")
    79  	if err != nil {
    80  		return nil, fmt.Errorf("could not read package list")
    81  	}
    82  
    83  	return ParseMacOSPackages(cmd.Stdout)
    84  }
    85  
    86  func (mpm *MacOSPkgManager) Available() (map[string]PackageUpdate, error) {
    87  	return nil, errors.New("cannot determine available packages for macOS")
    88  }