-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ Add basic support for scanning windows disk drives via device conn. (…
…#4208) * ✨ Add basic support for scanning windows disk drives via device conn. Signed-off-by: Preslav <preslav@mondoo.com> * Set disk to online if offline. Signed-off-by: Preslav <preslav@mondoo.com> * add comments. * Add new --serial-number arg. Add support for filtering disks by serial number. * clarify which params are only for windows/linux. Signed-off-by: Preslav <preslav@mondoo.com> * 🔥🪟 use reg.exe to (un)load sub keys (#4226) Proof-of-concept that we can use the `reg` command instead of the syscall that doesn't seem to work when running with `SYSTEM` user. https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/reg Signed-off-by: Salim Afiune Maya <afiune@mondoo.com> * Add tests. Signed-off-by: Preslav <preslav@mondoo.com> --------- Signed-off-by: Preslav <preslav@mondoo.com> Signed-off-by: Salim Afiune Maya <afiune@mondoo.com> Co-authored-by: Salim Afiune Maya <afiune@mondoo.com>
- Loading branch information
1 parent
f269cc1
commit 77c0081
Showing
9 changed files
with
529 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
114 changes: 114 additions & 0 deletions
114
providers/os/connection/device/windows/device_manager.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
// Copyright (c) Mondoo, Inc. | ||
// SPDX-License-Identifier: BUSL-1.1 | ||
|
||
package windows | ||
|
||
import ( | ||
"errors" | ||
"strings" | ||
|
||
"github.com/rs/zerolog/log" | ||
"go.mondoo.com/cnquery/v11/providers/os/connection/snapshot" | ||
) | ||
|
||
const ( | ||
LunOption = "lun" | ||
SerialNumberOption = "serial-number" | ||
) | ||
|
||
type WindowsDeviceManager struct { | ||
cmdRunner *snapshot.LocalCommandRunner | ||
opts map[string]string | ||
// indicates if the disk we've targeted has been set to online. we use this to know if we need to put it back offline once we're done | ||
diskSetToOnline bool | ||
// if we've set the disk online, we need to know the index to set it back offline | ||
diskIndex int | ||
} | ||
|
||
func NewWindowsDeviceManager(shell []string, opts map[string]string) (*WindowsDeviceManager, error) { | ||
if err := validateOpts(opts); err != nil { | ||
return nil, err | ||
} | ||
return &WindowsDeviceManager{ | ||
cmdRunner: &snapshot.LocalCommandRunner{Shell: shell}, | ||
opts: opts, | ||
}, nil | ||
} | ||
|
||
func (d *WindowsDeviceManager) Name() string { | ||
return "windows" | ||
} | ||
|
||
func (d *WindowsDeviceManager) IdentifyMountTargets(opts map[string]string) ([]*snapshot.PartitionInfo, error) { | ||
log.Debug().Msg("device connection> identifying mount targets") | ||
diskDrives, err := d.IdentifyDiskDrives() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
targetDrive, err := filterDiskDrives(diskDrives, opts) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
diskOnline, err := d.identifyDiskOnline(targetDrive.Index) | ||
if err != nil { | ||
return nil, err | ||
} | ||
if diskOnline.IsOffline { | ||
err = d.setDiskOnlineState(targetDrive.Index, true) | ||
if err != nil { | ||
return nil, err | ||
} | ||
d.diskSetToOnline = true | ||
d.diskIndex = targetDrive.Index | ||
} | ||
partitions, err := d.identifyPartitions(targetDrive.Index) | ||
if err != nil { | ||
return nil, err | ||
} | ||
partition, err := filterPartitions(partitions) | ||
if err != nil { | ||
return nil, err | ||
} | ||
partitionInfo := &snapshot.PartitionInfo{ | ||
Name: partition.DriveLetter, | ||
FsType: "Windows", | ||
} | ||
return []*snapshot.PartitionInfo{partitionInfo}, nil | ||
} | ||
|
||
// validates the options provided to the device manager | ||
func validateOpts(opts map[string]string) error { | ||
lun := opts[LunOption] | ||
serialNumber := opts[SerialNumberOption] | ||
|
||
if lun != "" && serialNumber != "" { | ||
return errors.New("lun and serial-number are mutually exclusive options") | ||
} | ||
|
||
if lun == "" && serialNumber == "" { | ||
return errors.New("either lun or serial-number must be provided") | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (d *WindowsDeviceManager) Mount(pi *snapshot.PartitionInfo) (string, error) { | ||
// note: we do not (yet) do the mounting in windows. for now, we simply return the drive letter | ||
// as that means the drive is already mounted | ||
if strings.HasSuffix(pi.Name, ":") { | ||
return pi.Name, nil | ||
} | ||
return pi.Name + ":", nil | ||
} | ||
|
||
func (d *WindowsDeviceManager) UnmountAndClose() { | ||
log.Debug().Msg("closing windows device manager") | ||
if d.diskSetToOnline { | ||
err := d.setDiskOnlineState(d.diskIndex, false) | ||
if err != nil { | ||
log.Debug().Err(err).Msg("could not set disk offline") | ||
} | ||
} | ||
} |
43 changes: 43 additions & 0 deletions
43
providers/os/connection/device/windows/device_manager_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
// Copyright (c) Mondoo, Inc. | ||
// SPDX-License-Identifier: BUSL-1.1 | ||
|
||
package windows | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestValidateOpts(t *testing.T) { | ||
t.Run("valid (only LUN)", func(t *testing.T) { | ||
opts := map[string]string{ | ||
LunOption: "0", | ||
} | ||
err := validateOpts(opts) | ||
require.NoError(t, err) | ||
}) | ||
|
||
t.Run("valid (only serial number)", func(t *testing.T) { | ||
opts := map[string]string{ | ||
SerialNumberOption: "0", | ||
} | ||
err := validateOpts(opts) | ||
require.NoError(t, err) | ||
}) | ||
|
||
t.Run("invalid (both LUN and serial number are provided", func(t *testing.T) { | ||
opts := map[string]string{ | ||
SerialNumberOption: "1234", | ||
LunOption: "1", | ||
} | ||
err := validateOpts(opts) | ||
require.Error(t, err) | ||
}) | ||
|
||
t.Run("invalid (neither LUN nor serial number are provided", func(t *testing.T) { | ||
opts := map[string]string{} | ||
err := validateOpts(opts) | ||
require.Error(t, err) | ||
}) | ||
} |
Oops, something went wrong.