go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/providers/os/connection/shared/shared.go (about)

     1  // Copyright (c) Mondoo, Inc.
     2  // SPDX-License-Identifier: BUSL-1.1
     3  
     4  package shared
     5  
     6  import (
     7  	"io"
     8  	"io/fs"
     9  	"os"
    10  	"regexp"
    11  	"strings"
    12  	"time"
    13  
    14  	"github.com/spf13/afero"
    15  	"go.mondoo.com/cnquery/llx"
    16  	"go.mondoo.com/cnquery/providers-sdk/v1/inventory"
    17  )
    18  
    19  type ConnectionType string
    20  
    21  type Connection interface {
    22  	RunCommand(command string) (*Command, error)
    23  	FileInfo(path string) (FileInfoDetails, error)
    24  	FileSystem() afero.Fs
    25  	ID() uint32
    26  	Name() string
    27  	Type() ConnectionType
    28  	Asset() *inventory.Asset
    29  	Capabilities() Capabilities
    30  }
    31  
    32  type SimpleConnection interface {
    33  	ID() uint32
    34  	Name() string
    35  	Type() ConnectionType
    36  	Asset() *inventory.Asset
    37  }
    38  
    39  type Command struct {
    40  	Command    string
    41  	Stats      PerfStats
    42  	Stdout     io.ReadWriter
    43  	Stderr     io.ReadWriter
    44  	ExitStatus int
    45  }
    46  
    47  type Capabilities byte
    48  
    49  const (
    50  	Capability_RunCommand Capabilities = 1 << iota
    51  	Capability_File
    52  	Capability_FindFile
    53  	Capability_FileSearch
    54  )
    55  
    56  func (c Capabilities) Has(other Capabilities) bool {
    57  	return c&other == other
    58  }
    59  
    60  func (c Capabilities) String() []string {
    61  	res := []string{}
    62  	if c.Has(Capability_RunCommand) {
    63  		res = append(res, "run-command")
    64  	}
    65  	if c.Has(Capability_File) {
    66  		res = append(res, "file")
    67  	}
    68  	if c.Has(Capability_FindFile) {
    69  		res = append(res, "find-file")
    70  	}
    71  	return res
    72  }
    73  
    74  type FileSearch interface {
    75  	Find(from string, r *regexp.Regexp, typ string) ([]string, error)
    76  }
    77  
    78  type PerfStats struct {
    79  	Start    time.Time     `json:"start"`
    80  	Duration time.Duration `json:"duration"`
    81  }
    82  
    83  type FileInfo struct {
    84  	FName    string
    85  	FSize    int64
    86  	FIsDir   bool
    87  	FModTime time.Time
    88  	FMode    os.FileMode
    89  	Uid      int64
    90  	Gid      int64
    91  }
    92  
    93  func (f *FileInfo) Name() string {
    94  	return f.FName
    95  }
    96  
    97  func (f *FileInfo) Size() int64 {
    98  	return f.FSize
    99  }
   100  
   101  func (f *FileInfo) Mode() os.FileMode {
   102  	return f.FMode
   103  }
   104  
   105  func (f *FileInfo) ModTime() time.Time {
   106  	return f.FModTime
   107  }
   108  
   109  func (f *FileInfo) IsDir() bool {
   110  	return f.FIsDir
   111  }
   112  
   113  func (f *FileInfo) Sys() interface{} {
   114  	return f
   115  }
   116  
   117  type FileInfoDetails struct {
   118  	Size int64
   119  	Mode FileModeDetails
   120  	Uid  int64
   121  	Gid  int64
   122  }
   123  
   124  type FileModeDetails struct {
   125  	os.FileMode
   126  }
   127  
   128  func (mode FileModeDetails) UserReadable() bool {
   129  	return uint32(mode.FileMode)&0o0400 != 0
   130  }
   131  
   132  func (mode FileModeDetails) UserWriteable() bool {
   133  	return uint32(mode.FileMode)&0o0200 != 0
   134  }
   135  
   136  func (mode FileModeDetails) UserExecutable() bool {
   137  	return uint32(mode.FileMode)&0o0100 != 0
   138  }
   139  
   140  func (mode FileModeDetails) GroupReadable() bool {
   141  	return uint32(mode.FileMode)&0o0040 != 0
   142  }
   143  
   144  func (mode FileModeDetails) GroupWriteable() bool {
   145  	return uint32(mode.FileMode)&0o0020 != 0
   146  }
   147  
   148  func (mode FileModeDetails) GroupExecutable() bool {
   149  	return uint32(mode.FileMode)&0o0010 != 0
   150  }
   151  
   152  func (mode FileModeDetails) OtherReadable() bool {
   153  	return uint32(mode.FileMode)&0o0004 != 0
   154  }
   155  
   156  func (mode FileModeDetails) OtherWriteable() bool {
   157  	return uint32(mode.FileMode)&0o0002 != 0
   158  }
   159  
   160  func (mode FileModeDetails) OtherExecutable() bool {
   161  	return uint32(mode.FileMode)&0o0001 != 0
   162  }
   163  
   164  func (mode FileModeDetails) Suid() bool {
   165  	return mode.FileMode&fs.ModeSetuid != 0
   166  }
   167  
   168  func (mode FileModeDetails) Sgid() bool {
   169  	return mode.FileMode&fs.ModeSetgid != 0
   170  }
   171  
   172  func (mode FileModeDetails) Sticky() bool {
   173  	return mode.FileMode&fs.ModeSticky != 0
   174  }
   175  
   176  func (mode FileModeDetails) UnixMode() uint32 {
   177  	m := mode.FileMode & 0o777
   178  
   179  	if mode.IsDir() {
   180  	}
   181  
   182  	if (mode.FileMode & fs.ModeSetuid) != 0 {
   183  		m |= 0o4000
   184  	}
   185  
   186  	if (mode.FileMode & fs.ModeSetgid) != 0 {
   187  		m |= 0o2000
   188  	}
   189  
   190  	if (mode.FileMode & fs.ModeSticky) != 0 {
   191  		m |= 0o1000
   192  	}
   193  
   194  	return uint32(m)
   195  }
   196  
   197  func ParseSudo(flags map[string]*llx.Primitive) *inventory.Sudo {
   198  	sudo := flags["sudo"]
   199  	if sudo == nil {
   200  		return nil
   201  	}
   202  
   203  	active := sudo.RawData().Value.(bool)
   204  	if !active {
   205  		return nil
   206  	}
   207  
   208  	return &inventory.Sudo{
   209  		Active:     true,
   210  		Executable: "sudo",
   211  	}
   212  }
   213  
   214  func BuildSudoCommand(sudo *inventory.Sudo, cmd string) string {
   215  	var sb strings.Builder
   216  
   217  	if sudo == nil || !sudo.Active {
   218  		return cmd
   219  	}
   220  
   221  	sb.WriteString(sudo.Executable)
   222  
   223  	if len(sudo.User) > 0 {
   224  		sb.WriteString(" -u " + sudo.User)
   225  	}
   226  
   227  	if len(sudo.Shell) > 0 {
   228  		sb.WriteString(" " + sudo.Shell + " -c " + cmd)
   229  	} else {
   230  		sb.WriteString(" ")
   231  		sb.WriteString(cmd)
   232  	}
   233  
   234  	return sb.String()
   235  }
   236  
   237  type Wrapper interface {
   238  	Build(cmd string) string
   239  }