Skip to content

Commit

Permalink
refactor power_event_watcher for configurable subscriber behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
zackattack01 committed Jun 27, 2024
1 parent 05ea065 commit 507a30f
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 35 deletions.
3 changes: 2 additions & 1 deletion cmd/launcher/launcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,8 @@ func runLauncher(ctx context.Context, cancel func(), multiSlogger, systemMultiSl
// For now, remediation is not performed -- we only log the hardware change.
agent.DetectAndRemediateHardwareChange(ctx, k)

powerEventWatcher, err := powereventwatcher.New(ctx, k, slogger)
powerEventSubscriber := powereventwatcher.NewKnapsackSubscriber(slogger, k)

Check failure on line 296 in cmd/launcher/launcher.go

View workflow job for this annotation

GitHub Actions / lint (macos-latest)

undefined: powereventwatcher.NewKnapsackSubscriber

Check failure on line 296 in cmd/launcher/launcher.go

View workflow job for this annotation

GitHub Actions / lint (macos-latest)

undefined: powereventwatcher.NewKnapsackSubscriber

Check failure on line 296 in cmd/launcher/launcher.go

View workflow job for this annotation

GitHub Actions / govulncheck (macos-latest)

undefined: powereventwatcher.NewKnapsackSubscriber

Check failure on line 296 in cmd/launcher/launcher.go

View workflow job for this annotation

GitHub Actions / launcher (ubuntu-20.04)

undefined: powereventwatcher.NewKnapsackSubscriber

Check failure on line 296 in cmd/launcher/launcher.go

View workflow job for this annotation

GitHub Actions / launcher (ubuntu-20.04)

undefined: powereventwatcher.NewKnapsackSubscriber

Check failure on line 296 in cmd/launcher/launcher.go

View workflow job for this annotation

GitHub Actions / launcher (macos-12)

undefined: powereventwatcher.NewKnapsackSubscriber

Check failure on line 296 in cmd/launcher/launcher.go

View workflow job for this annotation

GitHub Actions / launcher (macos-12)

undefined: powereventwatcher.NewKnapsackSubscriber

Check failure on line 296 in cmd/launcher/launcher.go

View workflow job for this annotation

GitHub Actions / lint (ubuntu-latest)

undefined: powereventwatcher.NewKnapsackSubscriber

Check failure on line 296 in cmd/launcher/launcher.go

View workflow job for this annotation

GitHub Actions / lint (ubuntu-latest)

undefined: powereventwatcher.NewKnapsackSubscriber

Check failure on line 296 in cmd/launcher/launcher.go

View workflow job for this annotation

GitHub Actions / govulncheck (ubuntu-latest)

undefined: powereventwatcher.NewKnapsackSubscriber
powerEventWatcher, err := powereventwatcher.New(ctx, slogger, powerEventSubscriber)

Check failure on line 297 in cmd/launcher/launcher.go

View workflow job for this annotation

GitHub Actions / lint (macos-latest)

cannot use slogger (variable of type *slog.Logger) as "github.com/kolide/launcher/ee/agent/types".Knapsack value in argument to powereventwatcher.New: *slog.Logger does not implement "github.com/kolide/launcher/ee/agent/types".Knapsack (missing method AddSlogHandler) (typecheck)

Check failure on line 297 in cmd/launcher/launcher.go

View workflow job for this annotation

GitHub Actions / lint (macos-latest)

cannot use slogger (variable of type *slog.Logger) as "github.com/kolide/launcher/ee/agent/types".Knapsack value in argument to powereventwatcher.New: *slog.Logger does not implement "github.com/kolide/launcher/ee/agent/types".Knapsack (missing method AddSlogHandler) (typecheck)

Check failure on line 297 in cmd/launcher/launcher.go

View workflow job for this annotation

GitHub Actions / govulncheck (macos-latest)

cannot use slogger (variable of type *slog.Logger) as "github.com/kolide/launcher/ee/agent/types".Knapsack value in argument to powereventwatcher.New: *slog.Logger does not implement "github.com/kolide/launcher/ee/agent/types".Knapsack (missing method AddSlogHandler)

Check failure on line 297 in cmd/launcher/launcher.go

View workflow job for this annotation

GitHub Actions / launcher (ubuntu-20.04)

cannot use slogger (variable of type *slog.Logger) as "github.com/kolide/launcher/ee/agent/types".Knapsack value in argument to powereventwatcher.New: *slog.Logger does not implement "github.com/kolide/launcher/ee/agent/types".Knapsack (missing method AddSlogHandler)

Check failure on line 297 in cmd/launcher/launcher.go

View workflow job for this annotation

GitHub Actions / launcher (ubuntu-20.04)

cannot use slogger (variable of type *slog.Logger) as "github.com/kolide/launcher/ee/agent/types".Knapsack value in argument to powereventwatcher.New: *slog.Logger does not implement "github.com/kolide/launcher/ee/agent/types".Knapsack (missing method AddSlogHandler)

Check failure on line 297 in cmd/launcher/launcher.go

View workflow job for this annotation

GitHub Actions / launcher (macos-12)

cannot use slogger (variable of type *slog.Logger) as "github.com/kolide/launcher/ee/agent/types".Knapsack value in argument to powereventwatcher.New: *slog.Logger does not implement "github.com/kolide/launcher/ee/agent/types".Knapsack (missing method AddSlogHandler)

Check failure on line 297 in cmd/launcher/launcher.go

View workflow job for this annotation

GitHub Actions / launcher (macos-12)

cannot use slogger (variable of type *slog.Logger) as "github.com/kolide/launcher/ee/agent/types".Knapsack value in argument to powereventwatcher.New: *slog.Logger does not implement "github.com/kolide/launcher/ee/agent/types".Knapsack (missing method AddSlogHandler)

Check failure on line 297 in cmd/launcher/launcher.go

View workflow job for this annotation

GitHub Actions / lint (ubuntu-latest)

cannot use slogger (variable of type *slog.Logger) as "github.com/kolide/launcher/ee/agent/types".Knapsack value in argument to powereventwatcher.New: *slog.Logger does not implement "github.com/kolide/launcher/ee/agent/types".Knapsack (missing method AddSlogHandler) (typecheck)

Check failure on line 297 in cmd/launcher/launcher.go

View workflow job for this annotation

GitHub Actions / lint (ubuntu-latest)

cannot use slogger (variable of type *slog.Logger) as "github.com/kolide/launcher/ee/agent/types".Knapsack value in argument to powereventwatcher.New: *slog.Logger does not implement "github.com/kolide/launcher/ee/agent/types".Knapsack (missing method AddSlogHandler) (typecheck)

Check failure on line 297 in cmd/launcher/launcher.go

View workflow job for this annotation

GitHub Actions / govulncheck (ubuntu-latest)

cannot use slogger (variable of type *slog.Logger) as "github.com/kolide/launcher/ee/agent/types".Knapsack value in argument to powereventwatcher.New: *slog.Logger does not implement "github.com/kolide/launcher/ee/agent/types".Knapsack (missing method AddSlogHandler)
if err != nil {
slogger.Log(ctx, slog.LevelDebug,
"could not init power event watcher",
Expand Down
114 changes: 80 additions & 34 deletions ee/powereventwatcher/power_event_watcher_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,31 @@ type (

powerEventWatcher struct {
slogger *slog.Logger
knapsack types.Knapsack
powerEventSubscriber powerEventSubscriber
subscriptionHandle uintptr
subscribeProcedure *syscall.LazyProc
unsubscribeProcedure *syscall.LazyProc
renderEventLogProcedure *syscall.LazyProc
interrupt chan struct{}
interrupted bool
}

// powerEventSubscriber is an interface to be implemented by anything utilizing the power event updates.
// implementers are provided to New, and the interface methods below are called as described during relevant updates
powerEventSubscriber interface {
// OnPowerEvent will be called for the provided subscriber whenever any watched event is observed
OnPowerEvent(eventID int) error
// OnStartup will be called when the powerEventWatcher is initially set up, allowing subscribers
// to perform any setup behavior (e.g. cache clearing, state resetting)
OnStartup() error
}

// knapsackSubscriber implements the powerEventSubscriber interface and
// updates the knapsack.InModernStandby state based on the power events observed
knapsackSubscriber struct {
knapsack types.Knapsack
slogger *slog.Logger
}
)

const (
Expand All @@ -46,16 +63,66 @@ const (
operationSuccessfulMsg = "The operation completed successfully."
)

func NewKnapsackSubscriber(slogger *slog.Logger, k types.Knapsack) *knapsackSubscriber {
return &knapsackSubscriber{
knapsack: k,
slogger: slogger,
}
}

func (ks *knapsackSubscriber) OnPowerEvent(eventID int) error {
switch eventID {
case eventIdEnteringModernStandby, eventIdEnteringSleep:
ks.slogger.Log(context.TODO(), slog.LevelDebug,
"system is sleeping",
"event_id", eventID,
)
if err := ks.knapsack.SetInModernStandby(true); err != nil {
ks.slogger.Log(context.TODO(), slog.LevelWarn,
"encountered error setting modern standby value",
"in_modern_standby", true,
"err", err,
)
}
case eventIdExitingModernStandby:
ks.slogger.Log(context.TODO(), slog.LevelDebug,
"system is waking",
"event_id", eventID,
)
if err := ks.knapsack.SetInModernStandby(false); err != nil {
ks.slogger.Log(context.TODO(), slog.LevelWarn,
"encountered error setting modern standby value",
"in_modern_standby", false,
"err", err,
)
}
default:
ks.slogger.Log(context.TODO(), slog.LevelWarn,
"received unexpected event ID in log",
"event_id", eventID,
)
}

return nil
}

func (ks *knapsackSubscriber) OnStartup() error {
// Clear InModernStandby flag, in case it's cached. We may have missed wake/sleep events
// while launcher was not running, and we want to err on the side of assuming the device
// is awake.
return ks.knapsack.SetInModernStandby(false)
}

// New sets up a subscription to relevant power events with a callback to `onPowerEvent`.
func New(ctx context.Context, k types.Knapsack, slogger *slog.Logger) (*powerEventWatcher, error) {
func New(ctx context.Context, slogger *slog.Logger, pes powerEventSubscriber) (*powerEventWatcher, error) {
_, span := traces.StartSpan(ctx)
defer span.End()

evtApi := syscall.NewLazyDLL("wevtapi.dll")

p := &powerEventWatcher{
slogger: slogger.With("component", "power_event_watcher"),
knapsack: k,
powerEventSubscriber: pes,
subscribeProcedure: evtApi.NewProc("EvtSubscribe"),
unsubscribeProcedure: evtApi.NewProc("EvtClose"),
renderEventLogProcedure: evtApi.NewProc("EvtRender"),
Expand Down Expand Up @@ -97,10 +164,13 @@ func New(ctx context.Context, k types.Knapsack, slogger *slog.Logger) (*powerEve
// Save the handle so that we can close it later
p.subscriptionHandle = subscriptionHandle

// Clear InModernStandby flag, in case it's cached. We may have missed wake/sleep events
// while launcher was not running, and we want to err on the side of assuming the device
// is awake.
k.SetInModernStandby(false)
if err := p.powerEventSubscriber.OnStartup(); err != nil {
// log any issues here but don't prevent creation of the watcher
slogger.Log(ctx, slog.LevelError,
"encountered error issuing subscriber OnStartup",
"err", err,
)
}

return p, nil
}
Expand Down Expand Up @@ -195,34 +265,10 @@ func (p *powerEventWatcher) onPowerEvent(action uint32, _ uintptr, eventHandle u
return ret
}

switch e.System.EventID {
case eventIdEnteringModernStandby, eventIdEnteringSleep:
p.slogger.Log(context.TODO(), slog.LevelDebug,
"system is sleeping",
"event_id", e.System.EventID,
)
if err := p.knapsack.SetInModernStandby(true); err != nil {
p.slogger.Log(context.TODO(), slog.LevelWarn,
"could not enable osquery healthchecks on system sleep",
"err", err,
)
}
case eventIdExitingModernStandby:
p.slogger.Log(context.TODO(), slog.LevelDebug,
"system is waking",
"event_id", e.System.EventID,
)
if err := p.knapsack.SetInModernStandby(false); err != nil {
p.slogger.Log(context.TODO(), slog.LevelWarn,
"could not enable osquery healthchecks on system wake",
"err", err,
)
}
default:
if err := p.powerEventSubscriber.OnPowerEvent(e.System.EventID); err != nil {
p.slogger.Log(context.TODO(), slog.LevelWarn,
"received unexpected event ID in log",
"event_id", e.System.EventID,
"raw_event", string(utf8bytes),
"subscriber encountered error OnPowerEvent update",
"err", err,
)
}

Expand Down

0 comments on commit 507a30f

Please sign in to comment.